From 7089cfea48e4e4a028c5349ec0565f309925e20c Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 11 Mar 2024 10:21:54 +0100 Subject: [PATCH 1/5] Ensure we also pin ISRG X2 in TLSA --- core/admin/mailu/models.py | 11 ++++++++--- core/admin/mailu/ui/templates/domain/details.html | 11 +++++++---- core/admin/mailu/ui/views/domains.py | 4 ++-- towncrier/newsfragments/3191.feature | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 towncrier/newsfragments/3191.feature diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 2cad7afb..155e3337 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -281,9 +281,14 @@ class Domain(Base): def dns_tlsa(self): """ return TLSA record for domain when using letsencrypt """ hostname = app.config['HOSTNAME'] - if app.config['TLS_FLAVOR'] in ('letsencrypt', 'mail-letsencrypt'): - # current ISRG Root X1 (RSA 4096, O = Internet Security Research Group, CN = ISRG Root X1) @20210902 - return f'_25._tcp.{hostname}. 86400 IN TLSA 2 1 1 0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3' + if True:# app.config['TLS_FLAVOR'] in ('letsencrypt', 'mail-letsencrypt'): + return [ + # current ISRG Root X1 (RSA 4096, O = Internet Security Research Group, CN = ISRG Root X1) @20210902 + f'_25._tcp.{hostname}. 86400 IN TLSA 2 1 1 0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3', + # current ISRG Root X2 (ECDSA P-384, O = Internet Security Research Group, CN = ISRG Root X2) @20240311 + f'_25._tcp.{hostname}. 86400 IN TLSA 2 1 1 762195c225586ee6c0237456e2107dc54f1efc21f61a792ebd515913cce68332', + ] + return [] @property def dkim_key(self): diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index 74657c28..183f7d1c 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -48,11 +48,14 @@ {%- endif %} -{%- set tlsa_record=domain.dns_tlsa %} -{%- if tlsa_record %} +{%- if domain.dns_tlsa|length > 0 %} - {% trans %}DNS TLSA entry{% endtrans %}
Let's Encrypt
ISRG Root X1
- {{ macros.clip("dns_tlsa") }}
{{ tlsa_record }}
+ {% trans %}DNS TLSA entry{% endtrans %}
Let's Encrypt ISRG Roots + {{ macros.clip("dns_tlsa") }}
+{%- for line in domain.dns_tlsa %}
+{{ line }}
+{%- endfor -%}
+  
{%- endif %} diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index dcd1aedd..5262032b 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -81,8 +81,8 @@ def domain_download_zonefile(domain_name): txt = ' '.join(f'"{txt[p:p+250]}"' for p in range(0, len(txt), 250)) res.append(f'{record} {txt}') res.append(domain.dns_dmarc) - if domain.dns_tlsa: - res.append(domain.dns_tlsa) + for tlsa in domain.dns_tlsa: + res.append(tlsa) res.extend(domain.dns_autoconfig) res.append("") return flask.Response( diff --git a/towncrier/newsfragments/3191.feature b/towncrier/newsfragments/3191.feature new file mode 100644 index 00000000..1fde020c --- /dev/null +++ b/towncrier/newsfragments/3191.feature @@ -0,0 +1 @@ +Ensure that we encourage users to also pin ISRG X2 in their TLSA records From b2d37c4323b06a97e2c653537a120cf6e72bd955 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 11 Mar 2024 10:26:38 +0100 Subject: [PATCH 2/5] Make it clear that there may be more than one --- core/admin/mailu/api/v1/domain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/admin/mailu/api/v1/domain.py b/core/admin/mailu/api/v1/domain.py index c5f98530..80ea75b5 100644 --- a/core/admin/mailu/api/v1/domain.py +++ b/core/admin/mailu/api/v1/domain.py @@ -39,20 +39,20 @@ domain_fields_get = api.model('DomainGet', { 'dns_autoconfig': fields.List(fields.String(description='DNS client auto-configuration entry')), 'dns_mx': fields.String(Description='MX record for domain'), 'dns_spf': fields.String(Description='SPF record for domain'), - 'dns_dkim': fields.String(Description='DKIM record for domain'), + 'dns_dkim': fields.String(Description='DKIM records for domain'), 'dns_dmarc': fields.String(Description='DMARC record for domain'), 'dns_dmarc_report': fields.String(Description='DMARC report record for domain'), - 'dns_tlsa': fields.String(Description='TLSA record for domain'), + 'dns_tlsa': fields.String(Description='TLSA records for domain'), }) domain_fields_dns = api.model('DomainDNS', { 'dns_autoconfig': fields.List(fields.String(description='DNS client auto-configuration entry')), 'dns_mx': fields.String(Description='MX record for domain'), 'dns_spf': fields.String(Description='SPF record for domain'), - 'dns_dkim': fields.String(Description='DKIM record for domain'), + 'dns_dkim': fields.String(Description='DKIM records for domain'), 'dns_dmarc': fields.String(Description='DMARC record for domain'), 'dns_dmarc_report': fields.String(Description='DMARC report record for domain'), - 'dns_tlsa': fields.String(Description='TLSA record for domain'), + 'dns_tlsa': fields.String(Description='TLSA records for domain'), }) manager_fields = api.model('Manager', { From 0171c6d0f8ecc2470601b5fb6000581fd64ea275 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 11 Mar 2024 11:12:53 +0100 Subject: [PATCH 3/5] review --- core/admin/mailu/models.py | 2 +- core/admin/mailu/ui/views/domains.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 155e3337..7cde30b9 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -281,7 +281,7 @@ class Domain(Base): def dns_tlsa(self): """ return TLSA record for domain when using letsencrypt """ hostname = app.config['HOSTNAME'] - if True:# app.config['TLS_FLAVOR'] in ('letsencrypt', 'mail-letsencrypt'): + if app.config['TLS_FLAVOR'] in ('letsencrypt', 'mail-letsencrypt'): return [ # current ISRG Root X1 (RSA 4096, O = Internet Security Research Group, CN = ISRG Root X1) @20210902 f'_25._tcp.{hostname}. 86400 IN TLSA 2 1 1 0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3', diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index 5262032b..a3b78204 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -81,8 +81,7 @@ def domain_download_zonefile(domain_name): txt = ' '.join(f'"{txt[p:p+250]}"' for p in range(0, len(txt), 250)) res.append(f'{record} {txt}') res.append(domain.dns_dmarc) - for tlsa in domain.dns_tlsa: - res.append(tlsa) + res.extend(domain.dns_tlsa) res.extend(domain.dns_autoconfig) res.append("") return flask.Response( From 58b1738d8c66fbb00010da0f117c1fdf71989bcd Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 11 Mar 2024 11:15:15 +0100 Subject: [PATCH 4/5] api --- core/admin/mailu/api/v1/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/api/v1/domain.py b/core/admin/mailu/api/v1/domain.py index 80ea75b5..b45cfb9a 100644 --- a/core/admin/mailu/api/v1/domain.py +++ b/core/admin/mailu/api/v1/domain.py @@ -42,7 +42,7 @@ domain_fields_get = api.model('DomainGet', { 'dns_dkim': fields.String(Description='DKIM records for domain'), 'dns_dmarc': fields.String(Description='DMARC record for domain'), 'dns_dmarc_report': fields.String(Description='DMARC report record for domain'), - 'dns_tlsa': fields.String(Description='TLSA records for domain'), + 'dns_tlsa': fields.List(fields.String(Description='TLSA records for domain')), }) domain_fields_dns = api.model('DomainDNS', { From a1d8ff630f0362fe1450bae5cf48289a37a13197 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Mon, 11 Mar 2024 14:45:59 +0100 Subject: [PATCH 5/5] review2 --- core/admin/mailu/api/v1/domain.py | 2 +- core/admin/mailu/ui/templates/domain/details.html | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/core/admin/mailu/api/v1/domain.py b/core/admin/mailu/api/v1/domain.py index b45cfb9a..2edb10d2 100644 --- a/core/admin/mailu/api/v1/domain.py +++ b/core/admin/mailu/api/v1/domain.py @@ -52,7 +52,7 @@ domain_fields_dns = api.model('DomainDNS', { 'dns_dkim': fields.String(Description='DKIM records for domain'), 'dns_dmarc': fields.String(Description='DMARC record for domain'), 'dns_dmarc_report': fields.String(Description='DMARC report record for domain'), - 'dns_tlsa': fields.String(Description='TLSA records for domain'), + 'dns_tlsa': fields.List(fields.String(Description='TLSA records for domain')), }) manager_fields = api.model('Manager', { diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index 183f7d1c..d32cf740 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -51,11 +51,7 @@ {%- if domain.dns_tlsa|length > 0 %} {% trans %}DNS TLSA entry{% endtrans %}
Let's Encrypt ISRG Roots - {{ macros.clip("dns_tlsa") }}
-{%- for line in domain.dns_tlsa %}
-{{ line }}
-{%- endfor -%}
-  
+ {{ macros.clip("dns_tlsa") }}
{{ domain.dns_tlsa | join("\n") }}
{%- endif %}