letsencrypt / boulder

An ACME-based certificate authority, written in Go.
Mozilla Public License 2.0
5.2k stars 606 forks source link

IANA gTLD blocking #7013

Open pgporada opened 1 year ago

pgporada commented 1 year ago

For several years SRE has relied upon various scripts to monitor IANA gTLD deprecations. When a gTLD is deprecated they have to do toil work such as:

  1. Making a work tracking ticket
  2. Blocking further issuance of domains with that gTLD
  3. Deleting pending authzs for the to-be-blocked gTLD
  4. Administratively revoking certificates
  5. Updating zlint in boulder

The Baseline Requirements section 4.9.1.1 Reasons for Revoking a Subscriber Certificate state:

The CA […] MUST revoke a Certificate within 5 days if […] The CA is made aware of any circumstance indicating that use of a Fully-Qualified Domain Name or IP address in the Certificate is no longer legally permitted (e.g. a court or arbitrator has revoked a Domain Name Registrant's right to use the Domain Name, a relevant licensing or services agreement between the Domain Name Registrant and the Applicant has terminated, or the Domain Name Registrant has failed to renew the Domain Name)…

The core of the monitoring is currently this slightly edited shell script.

#!/usr/bin/env sh

go install "github.com/zmap/zlint/v3/cmd/zlint-gtld-update@latest"

# Copy the source of truth
curl -sf --retry 5 --retry-delay 30 --retry-max-time 360 "https://raw.githubusercontent.com/zmap/zlint/9396315ef5d8b51947a954acf22b062aafca55c8}/v3/util/gtld_map.go" > "/tmp/extant_map" || { echo "FAILED to download baseline gTLD map"; exit 1; }

zlint-gtld-update > "/tmp/update_map"

# output differences, no differences is good
diff -u3 --suppress-common-lines --ignore-matching-lines="^ \* ZLint Copyright" "/tmp/extant_map" "/tmp/update_map"

Output produced from that diff will look like

--- /tmp/extant_map 2022-12-07 00:03:09.634309424 +0000
+++ /tmp/update_map 2022-12-07 00:03:09.996312588 +0000
@@ -7366,7 +7366,7 @@
"xn--jlq61u9w7b": {
GTLD:           "xn--jlq61u9w7b",
DelegationDate: "2015-12-18",
-       RemovalDate:    "",
+       RemovalDate:    "2022-12-06",
},
"xn--jvr189m": {
GTLD:           "xn--jvr189m",
jsha commented 1 year ago

One proposed fix for this: Some Boulder component that lives in the EFN (probably the WFE) can periodically fetch the "Top-Level Domain List" linked at the bottom of https://www.iana.org/domains/root/files. Then, at issuance time we can check that all names for issuance end in a current TLD. That would solve both of these cases:

Blocking further issuance of domains with that gTLD Deleting pending authzs for the to-be-blocked gTLD

We wouldn't need to delete the pending authzs because they would not be able to be used in issuance due to the new check.

For revoking existing certificates, it's more work. A sketch of it: Add an automated revocation daemon, similar to bad-key-revoker. This daemon would:

jprenken commented 1 year ago

It'll be important to check that IANA's list is in an expected state, before acting on it. We sometimes successfully retrieve the file but find it blank or incomplete. One good check might be to see if any apparently-removed TLDs still have NS records in the root servers.

Depending on how we end up feeling about automating the revocation, it would still be a time-saver to have an interactive command line tool that asks for confirmation but otherwise automates the searches and work.

mcpherrinm commented 1 year ago

Some Boulder component ... (probably the WFE)

Ideally a standalone component that can be run as a cron-like task, not reimplementing cron inside the WFE, I think. That makes egress controls easier, as well as observability.

The HTTP fetch doesn't have to be in boulder; that could just be curl or whatever, and boulder would just need to handle the new file. But it may be simpler to just fetch and process in one custom tool to avoid the need for a driver script.