From 4f0eb0ef359ba4e15638488dd79d40ab8348f5d8 Mon Sep 17 00:00:00 2001 From: Jumper78 <52802286+Jumper78@users.noreply.github.com> Date: Sun, 21 Jul 2024 22:01:20 +0000 Subject: [PATCH 1/4] DKIM signing of alternative domains When rspamd looks up the DKIM key of the domains, also the alternative domains are queried. In case there is a match, the admin container is providing the DKIM key of the domain belonging to the alternative domain. file modified: core/admin/mailu/internal/views/rspamd.py --- core/admin/mailu/internal/views/rspamd.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/admin/mailu/internal/views/rspamd.py b/core/admin/mailu/internal/views/rspamd.py index b6ead86b..4b17297a 100644 --- a/core/admin/mailu/internal/views/rspamd.py +++ b/core/admin/mailu/internal/views/rspamd.py @@ -24,6 +24,15 @@ def rspamd_dkim_key(domain_name): 'selector': flask.current_app.config.get('DKIM_SELECTOR', 'dkim'), } ) + elif domain := models.Alternative.query.get(domain_name): + if key := domain.domain.dkim_key: + selectors.append( + { + 'domain' : domain.name, + 'key' : key.decode('utf8'), + 'selector': flask.current_app.config.get('DKIM_SELECTOR', 'dkim'), + } + ) return flask.jsonify({'data': {'selectors': selectors}}) @internal.route("/rspamd/local_domains", methods=['GET']) From 189689565c3049ba81f73318248be342c490f569 Mon Sep 17 00:00:00 2001 From: Jumper78 <52802286+Jumper78@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:16:38 +0000 Subject: [PATCH 2/4] adding section for the alternative domain names to the details page of the domain code goes through all of the alternative domain names and displays: - name of the alternative domain - DNS MX entry - DNS SPF entry - if main domain has DKIM key: DNS DKIM entry - if main domain has DKIM key: DNS DMARC entry file modified: core/admin/mailu/models.py file modified: core/admin/mailu/ui/templates/domain/details.html --- core/admin/mailu/models.py | 48 +++++++++++++++++++ .../mailu/ui/templates/domain/details.html | 32 +++++++++++++ 2 files changed, 80 insertions(+) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index f73bf0b7..78d5262a 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -355,6 +355,54 @@ class Alternative(Base): domain = db.relationship(Domain, backref=db.backref('alternatives', cascade='all, delete-orphan')) + @property + def dns_dkim(self): + """ return DKIM record for domain """ + if self.domain.dkim_key: + selector = app.config['DKIM_SELECTOR'] + return f'{selector}._domainkey.{self.name}. 600 IN TXT "v=DKIM1; k=rsa; p={self.domain.dkim_publickey}"' + + @cached_property + def dns_dmarc(self): + """ return DMARC record for domain """ + if self.domain.dkim_key: + domain = app.config['DOMAIN'] + rua = app.config['DMARC_RUA'] + rua = f' rua=mailto:{rua}@{domain};' if rua else '' + ruf = app.config['DMARC_RUF'] + ruf = f' ruf=mailto:{ruf}@{domain};' if ruf else '' + return f'_dmarc.{self.name}. 600 IN TXT "v=DMARC1; p=reject;{rua}{ruf} adkim=s; aspf=s"' + + @cached_property + def dns_dmarc_report(self): + """ return DMARC report record for mailu server """ + if self.domain.dkim_key: + domain = app.config['DOMAIN'] + return f'{self.name}._report._dmarc.{domain}. 600 IN TXT "v=DMARC1;"' + + @cached_property + def dns_mx(self): + """ return MX record for domain """ + hostname = app.config['HOSTNAME'] + return f'{self.name}. 600 IN MX 10 {hostname}.' + + @cached_property + def dns_spf(self): + """ return SPF record for domain """ + hostname = app.config['HOSTNAME'] + return f'{self.name}. 600 IN TXT "v=spf1 mx a:{hostname} ~all"' + + def check_mx(self): + """ checks if MX record for domain points to mailu host """ + try: + hostnames = set(app.config['HOSTNAMES'].split(',')) + return any( + rset.exchange.to_text().rstrip('.') in hostnames + for rset in dns.resolver.resolve(self.name, 'MX') + ) + except dns.exception.DNSException: + return False + class Relay(Base): """ Relayed mail domain. diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index d32cf740..035ba7ae 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -63,4 +63,36 @@ {%- endcall %} + +{%- for alternative in domain.alternatives %} + +{%- call macros.table(datatable=False) %} + + {% trans %}Alternative Domain name{% endtrans %} + {{ alternative.name }} + + + {% trans %}DNS MX entry{% endtrans %} + {{ macros.clip("dns_mx") }}
{{ alternative.dns_mx }}
+ + + {% trans %}DNS SPF entries{% endtrans %} + {{ macros.clip("dns_spf") }}
{{ alternative.dns_spf }}
+ + +{%- if alternative.domain.dkim_publickey %} + + {% trans %}DNS DKIM entry{% endtrans %} + {{ macros.clip("dns_dkim") }}
{{ alternative.dns_dkim }}
+ + + {% trans %}DNS DMARC entry{% endtrans %} + + {{ macros.clip("dns_dmarc") }}
{{ alternative.dns_dmarc }}
+ {{ macros.clip("dns_dmarc_report") }}
{{ alternative.dns_dmarc_report }}
+ + +{%- endif %} +{%- endcall %} +{%- endfor %} {%- endblock %} From 2a49300ba709311300430947fdc5646b10541615 Mon Sep 17 00:00:00 2001 From: Jumper78 <52802286+Jumper78@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:37:27 +0200 Subject: [PATCH 3/4] add 3350.feature to the newsfragments --- towncrier/newsfragments/3350.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/3350.feature diff --git a/towncrier/newsfragments/3350.feature b/towncrier/newsfragments/3350.feature new file mode 100644 index 00000000..67c4d210 --- /dev/null +++ b/towncrier/newsfragments/3350.feature @@ -0,0 +1 @@ +Add DKIM support for alternative domains: alternative domains use the same DKIM key as the main domain. From 89a6d5720713b03e78871a2099a01dea269c9c07 Mon Sep 17 00:00:00 2001 From: Jumper78 <52802286+Jumper78@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:42:21 +0000 Subject: [PATCH 4/4] add translation for German that fits to the added lines of the detailed view of the domains file modified: core/admin/mailu/translations/de/LC_MESSAGES/messages.po --- core/admin/mailu/translations/de/LC_MESSAGES/messages.po | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/admin/mailu/translations/de/LC_MESSAGES/messages.po b/core/admin/mailu/translations/de/LC_MESSAGES/messages.po index 0f77e563..b35e7123 100644 --- a/core/admin/mailu/translations/de/LC_MESSAGES/messages.po +++ b/core/admin/mailu/translations/de/LC_MESSAGES/messages.po @@ -545,6 +545,10 @@ msgstr "DNS TLSA Eintrag" msgid "DNS client auto-configuration entries" msgstr "DNS Einträge für die automatische Client-Konfiguration" +#: mailu/ui/templates/domain/details.html:71 +msgid "Alternative Domain name" +msgstr "Alternativer Domain Name" + #: mailu/ui/templates/domain/edit.html:4 msgid "Edit domain" msgstr "Domain bearbeiten"