mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2024-11-25 02:47:04 +00:00
Improve DMARC and SPF record descriptions
This commit is contained in:
parent
45d47818ca
commit
7b9b978a6d
@ -24,7 +24,7 @@ def get_dns_zones(env):
|
|||||||
# What domains should we create DNS zones for? Never create a zone for
|
# What domains should we create DNS zones for? Never create a zone for
|
||||||
# a domain & a subdomain of that domain.
|
# a domain & a subdomain of that domain.
|
||||||
domains = get_dns_domains(env)
|
domains = get_dns_domains(env)
|
||||||
|
|
||||||
# Exclude domains that are subdomains of other domains we know. Proceed
|
# Exclude domains that are subdomains of other domains we know. Proceed
|
||||||
# by looking at shorter domains first.
|
# by looking at shorter domains first.
|
||||||
zone_domains = set()
|
zone_domains = set()
|
||||||
@ -49,7 +49,7 @@ def get_dns_zones(env):
|
|||||||
zonefiles.sort(key = lambda zone : zone_order.index(zone[0]) )
|
zonefiles.sort(key = lambda zone : zone_order.index(zone[0]) )
|
||||||
|
|
||||||
return zonefiles
|
return zonefiles
|
||||||
|
|
||||||
def do_dns_update(env, force=False):
|
def do_dns_update(env, force=False):
|
||||||
# What domains (and their zone filenames) should we build?
|
# What domains (and their zone filenames) should we build?
|
||||||
domains = get_dns_domains(env)
|
domains = get_dns_domains(env)
|
||||||
@ -247,17 +247,17 @@ def build_zone(domain, all_domains, additional_records, env, is_zone=True):
|
|||||||
# Append a DMARC record.
|
# Append a DMARC record.
|
||||||
# Skip if the user has set a DMARC record already.
|
# Skip if the user has set a DMARC record already.
|
||||||
if not has_rec("_dmarc", "TXT", prefix="v=DMARC1; "):
|
if not has_rec("_dmarc", "TXT", prefix="v=DMARC1; "):
|
||||||
records.append(("_dmarc", "TXT", 'v=DMARC1; p=quarantine', "Optional. Specifies that mail that does not originate from the box but claims to be from @%s is suspect and should be quarantined by the recipient's mail system." % domain))
|
records.append(("_dmarc", "TXT", 'v=DMARC1; p=quarantine', "Recommended. Specifies that mail that does not originate from the box but claims to be from @%s or which does not have a valid DKIM signature is suspect and should be quarantined by the recipient's mail system." % domain))
|
||||||
|
|
||||||
# For any subdomain with an A record but no SPF or DMARC record, add strict policy records.
|
# For any subdomain with an A record but no SPF or DMARC record, add strict policy records.
|
||||||
all_resolvable_qnames = set(r[0] for r in records if r[1] in ("A", "AAAA"))
|
all_resolvable_qnames = set(r[0] for r in records if r[1] in ("A", "AAAA"))
|
||||||
for qname in all_resolvable_qnames:
|
for qname in all_resolvable_qnames:
|
||||||
if not has_rec(qname, "TXT", prefix="v=spf1 "):
|
if not has_rec(qname, "TXT", prefix="v=spf1 "):
|
||||||
records.append((qname, "TXT", 'v=spf1 a mx -all', "Prevents unauthorized use of this domain name for outbound mail by requiring outbound mail to originate from the indicated host(s)."))
|
records.append((qname, "TXT", 'v=spf1 a mx -all', "Recommended. Prevents unauthorized use of this domain name for outbound mail by specifying that only servers pointed to by a parallel A or MX record are valid sources for mail from @%s." % (qname + "." + domain)))
|
||||||
dmarc_qname = "_dmarc" + ("" if qname is None else "." + qname)
|
dmarc_qname = "_dmarc" + ("" if qname is None else "." + qname)
|
||||||
if not has_rec(dmarc_qname, "TXT", prefix="v=DMARC1; "):
|
if not has_rec(dmarc_qname, "TXT", prefix="v=DMARC1; "):
|
||||||
records.append((dmarc_qname, "TXT", 'v=DMARC1; p=reject', "Prevents unauthorized use of this domain name for outbound mail by requiring a valid DKIM signature."))
|
records.append((dmarc_qname, "TXT", 'v=DMARC1; p=reject', "Recommended. Prevents unauthorized use of this domain name for outbound mail by specifying that the SPF rule should be honoured for mail from @%s." % (qname + "." + domain)))
|
||||||
|
|
||||||
|
|
||||||
# Sort the records. The None records *must* go first in the nsd zone file. Otherwise it doesn't matter.
|
# 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 ""))
|
records.sort(key = lambda rec : list(reversed(rec[0].split(".")) if rec[0] is not None else ""))
|
||||||
@ -325,7 +325,7 @@ def build_sshfp_records():
|
|||||||
# Lots of things can go wrong. Don't let it disturb the DNS
|
# Lots of things can go wrong. Don't let it disturb the DNS
|
||||||
# zone.
|
# zone.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
def write_nsd_zone(domain, zonefile, records, env, force):
|
def write_nsd_zone(domain, zonefile, records, env, force):
|
||||||
@ -435,7 +435,7 @@ def write_nsd_conf(zonefiles, additional_records, env):
|
|||||||
# Write the list of zones to a configuration file.
|
# Write the list of zones to a configuration file.
|
||||||
nsd_conf_file = "/etc/nsd/zones.conf"
|
nsd_conf_file = "/etc/nsd/zones.conf"
|
||||||
nsdconf = ""
|
nsdconf = ""
|
||||||
|
|
||||||
# Append the zones.
|
# Append the zones.
|
||||||
for domain, zonefile in zonefiles:
|
for domain, zonefile in zonefiles:
|
||||||
nsdconf += """
|
nsdconf += """
|
||||||
@ -492,7 +492,7 @@ def sign_zone(domain, zonefile, env):
|
|||||||
# a new .key file with a DNSSEC record for the specific domain. We
|
# a new .key file with a DNSSEC record for the specific domain. We
|
||||||
# can reuse the same key, but it won't validate without a DNSSEC
|
# can reuse the same key, but it won't validate without a DNSSEC
|
||||||
# record specifically for the domain.
|
# record specifically for the domain.
|
||||||
#
|
#
|
||||||
# Copy the .key and .private files to /tmp to patch them up.
|
# Copy the .key and .private files to /tmp to patch them up.
|
||||||
#
|
#
|
||||||
# Use os.umask and open().write() to securely create a copy that only
|
# Use os.umask and open().write() to securely create a copy that only
|
||||||
@ -691,8 +691,8 @@ def write_custom_dns_config(config, env):
|
|||||||
if len(values) == 1:
|
if len(values) == 1:
|
||||||
values = values[0]
|
values = values[0]
|
||||||
dns[qname][rtype] = values
|
dns[qname][rtype] = values
|
||||||
|
|
||||||
# Write.
|
# Write.
|
||||||
config_yaml = rtyaml.dump(dns)
|
config_yaml = rtyaml.dump(dns)
|
||||||
with open(os.path.join(env['STORAGE_ROOT'], 'dns/custom.yaml'), "w") as f:
|
with open(os.path.join(env['STORAGE_ROOT'], 'dns/custom.yaml'), "w") as f:
|
||||||
f.write(config_yaml)
|
f.write(config_yaml)
|
||||||
|
Loading…
Reference in New Issue
Block a user