1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2026-03-05 15:57:23 +01:00

Publish MTA-STS policy for incoming mail (#1731)

Co-authored-by: Daniel Mabbett <triumph_2500@hotmail.com>
This commit is contained in:
A. Schippers
2020-05-29 21:30:07 +02:00
committed by GitHub
parent 7de8fc9bc0
commit afc9f9686a
8 changed files with 81 additions and 3 deletions

View File

@@ -9,8 +9,9 @@ import ipaddress
import rtyaml
import dns.resolver
from mailconfig import get_mail_domains
from mailconfig import get_mail_domains, get_mail_aliases
from utils import shell, load_env_vars_from_file, safe_domain_name, sort_domains
from ssl_certificates import get_ssl_certificates, check_certificate
# From https://stackoverflow.com/questions/3026957/how-to-validate-a-domain-name-using-regex-php/16491074#16491074
# This regular expression matches domain names according to RFCs, it also accepts fqdn with an leading dot,
@@ -303,6 +304,42 @@ def build_zone(domain, all_domains, additional_records, www_redirect_domains, en
if not has_rec(qname, rtype):
records.append((qname, rtype, value, explanation))
# If this is a domain name that there are email addresses configured for, i.e. "something@"
# this domain name, then the domain name is a MTA-STS (https://tools.ietf.org/html/rfc8461)
# Policy Domain.
#
# A "_mta-sts" TXT record signals the presence of a MTA-STS policy, and an effectively random policy
# ID is used to signal that a new policy may (or may not) be deployed any time the DNS is
# updated.
#
# The policy itself is served at the "mta-sts" (no underscore) subdomain over HTTPS. The
# TLS certificate used by Postfix for STARTTLS must be a valid certificate for the MX
# name (PRIMARY_HOSTNAME), so we do not set an MTA-STS policy if the certificate is not
# valid (e.g. because it is self-signed and a valid certificate has not yet been provisioned).
get_prim_cert = get_ssl_certificates(env)[env['PRIMARY_HOSTNAME']]
response = check_certificate(env['PRIMARY_HOSTNAME'], get_prim_cert['certificate'],get_prim_cert['private-key'])
if response[0] == 'OK' and domain in get_mail_domains(env):
mta_sts_records = [
("mta-sts", "A", env["PUBLIC_IP"], "Provides MTA-STS support"),
("mta-sts", "AAAA", env.get('PUBLIC_IPV6'), "Provides MTA-STS support"),
("_mta-sts", "TXT", "v=STSv1; id=%sZ" % datetime.datetime.now().strftime("%Y%m%d%H%M%S"), "Enables MTA-STS support")
]
# Rules can be custom configured accoring to https://tools.ietf.org/html/rfc8460.
# Skip if the rules below if the user has set a custom _smtp._tls record.
if not has_rec("_smtp._tls", "TXT", prefix="v=TLSRPTv1;"):
# if the alias 'tlsrpt@PRIMARY_HOSTNAME' is configured, automaticly, reporting will be enabled to this email address
tls_rpt_email = "tlsrpt@%s" % env['PRIMARY_HOSTNAME']
tls_rpt_string = ""
for alias in get_mail_aliases(env):
if alias[0] == tls_rpt_email:
tls_rpt_string = " rua=mailto:%s" % tls_rpt_email
mta_sts_records.append(("_smtp._tls", "TXT", "v=TLSRPTv1;%s" % tls_rpt_string, "For reporting, add an email alias: 'tlsrpt@%s' or add a custom TXT record like 'v=TLSRPTv1; rua=mailto:[youremail]@%s' for reporting" % (env["PRIMARY_HOSTNAME"], env["PRIMARY_HOSTNAME"])))
for qname, rtype, value, explanation in mta_sts_records:
if value is None or value.strip() == "": continue # skip IPV6 if not set
if not has_rec(qname, rtype):
records.append((qname, rtype, value, explanation))
# Sort the records. The None records *must* go first in the nsd zone file. Otherwise it doesn't matter.
records.sort(key = lambda rec : list(reversed(rec[0].split(".")) if rec[0] is not None else ""))

View File

@@ -30,6 +30,9 @@ def get_web_domains(env, include_www_redirects=True, exclude_dns_elsewhere=True)
domains |= set('autoconfig.' + maildomain for maildomain in get_mail_domains(env))
domains |= set('autodiscover.' + maildomain for maildomain in get_mail_domains(env))
# 'mta-sts.' for MTA-STS support.
domains |= set('mta-sts.' + maildomain for maildomain in get_mail_domains(env))
if exclude_dns_elsewhere:
# ...Unless the domain has an A/AAAA record that maps it to a different
# IP address than this box. Remove those domains from our list.