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']) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 57c82c6b..75217166 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/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" 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) %} +
{{ alternative.dns_mx }}{{ alternative.dns_spf }}
+ {{ alternative.dns_dkim }}{{ alternative.dns_dmarc }}
+ {{ macros.clip("dns_dmarc_report") }}{{ alternative.dns_dmarc_report }}
+