Take spamhaus return codes into account in status check and postfix config (#2332)
This commit is contained in:
parent
1b8cdeb644
commit
0b1d92388a
|
@ -306,14 +306,23 @@ def run_network_checks(env, output):
|
||||||
# The user might have ended up on an IP address that was previously in use
|
# The user might have ended up on an IP address that was previously in use
|
||||||
# by a spammer, or the user may be deploying on a residential network. We
|
# by a spammer, or the user may be deploying on a residential network. We
|
||||||
# will not be able to reliably send mail in these cases.
|
# will not be able to reliably send mail in these cases.
|
||||||
|
|
||||||
|
# See https://www.spamhaus.org/news/article/807/using-our-public-mirrors-check-your-return-codes-now. for
|
||||||
|
# information on spamhaus return codes
|
||||||
rev_ip4 = ".".join(reversed(env['PUBLIC_IP'].split('.')))
|
rev_ip4 = ".".join(reversed(env['PUBLIC_IP'].split('.')))
|
||||||
zen = query_dns(rev_ip4+'.zen.spamhaus.org', 'A', nxdomain=None)
|
zen = query_dns(rev_ip4+'.zen.spamhaus.org', 'A', nxdomain=None)
|
||||||
if zen is None:
|
if zen is None:
|
||||||
output.print_ok("IP address is not blacklisted by zen.spamhaus.org.")
|
output.print_ok("IP address is not blacklisted by zen.spamhaus.org.")
|
||||||
elif zen == "[timeout]":
|
elif zen == "[timeout]":
|
||||||
output.print_warning("Connection to zen.spamhaus.org timed out. We could not determine whether your server's IP address is blacklisted. Please try again later.")
|
output.print_warning("Connection to zen.spamhaus.org timed out. Could not determine whether this box's IP address is blacklisted. Please try again later.")
|
||||||
elif zen == "[Not Set]":
|
elif zen == "[Not Set]":
|
||||||
output.print_warning("Could not connect to zen.spamhaus.org. We could not determine whether your server's IP address is blacklisted. Please try again later.")
|
output.print_warning("Could not connect to zen.spamhaus.org. Could not determine whether this box's IP address is blacklisted. Please try again later.")
|
||||||
|
elif zen == "127.255.255.252":
|
||||||
|
output.print_warning("Incorrect spamhaus query: %s. Could not determine whether this box's IP address is blacklisted." % (rev_ip4+'.zen.spamhaus.org'))
|
||||||
|
elif zen == "127.255.255.254":
|
||||||
|
output.print_warning("Mail-in-a-Box is configured to use a public DNS server. This is not supported by spamhaus. Could not determine whether this box's IP address is blacklisted.")
|
||||||
|
elif zen == "127.255.255.255":
|
||||||
|
output.print_warning("Too many queries have been performed on the spamhaus server. Could not determine whether this box's IP address is blacklisted.")
|
||||||
else:
|
else:
|
||||||
output.print_error("""The IP address of this machine {} is listed in the Spamhaus Block List (code {}),
|
output.print_error("""The IP address of this machine {} is listed in the Spamhaus Block List (code {}),
|
||||||
which may prevent recipients from receiving your email. See http://www.spamhaus.org/query/ip/{}.""".format(env['PUBLIC_IP'], zen, env['PUBLIC_IP']))
|
which may prevent recipients from receiving your email. See http://www.spamhaus.org/query/ip/{}.""".format(env['PUBLIC_IP'], zen, env['PUBLIC_IP']))
|
||||||
|
@ -451,7 +460,7 @@ def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles):
|
||||||
if ip == env['PUBLIC_IP'] and not (ipv6 and env['PUBLIC_IPV6'] and ipv6 != normalize_ip(env['PUBLIC_IPV6'])):
|
if ip == env['PUBLIC_IP'] and not (ipv6 and env['PUBLIC_IPV6'] and ipv6 != normalize_ip(env['PUBLIC_IPV6'])):
|
||||||
output.print_ok("Domain resolves to box's IP address. [{} ↦ {}]".format(env['PRIMARY_HOSTNAME'], my_ips))
|
output.print_ok("Domain resolves to box's IP address. [{} ↦ {}]".format(env['PRIMARY_HOSTNAME'], my_ips))
|
||||||
else:
|
else:
|
||||||
output.print_error("""This domain must resolve to your box's IP address ({}) in public DNS but it currently resolves
|
output.print_error("""This domain must resolve to this box's IP address ({}) in public DNS but it currently resolves
|
||||||
to {}. It may take several hours for public DNS to update after a change. This problem may result from other
|
to {}. It may take several hours for public DNS to update after a change. This problem may result from other
|
||||||
issues listed above.""".format(my_ips, ip + ((" / " + ipv6) if ipv6 is not None else "")))
|
issues listed above.""".format(my_ips, ip + ((" / " + ipv6) if ipv6 is not None else "")))
|
||||||
|
|
||||||
|
@ -463,11 +472,11 @@ def check_primary_hostname_dns(domain, env, output, dns_domains, dns_zonefiles):
|
||||||
if existing_rdns_v4 == domain and existing_rdns_v6 in {None, domain}:
|
if existing_rdns_v4 == domain and existing_rdns_v6 in {None, domain}:
|
||||||
output.print_ok("Reverse DNS is set correctly at ISP. [{} ↦ {}]".format(my_ips, env['PRIMARY_HOSTNAME']))
|
output.print_ok("Reverse DNS is set correctly at ISP. [{} ↦ {}]".format(my_ips, env['PRIMARY_HOSTNAME']))
|
||||||
elif existing_rdns_v4 == existing_rdns_v6 or existing_rdns_v6 is None:
|
elif existing_rdns_v4 == existing_rdns_v6 or existing_rdns_v6 is None:
|
||||||
output.print_error(f"""Your box's reverse DNS is currently {existing_rdns_v4}, but it should be {domain}. Your ISP or cloud provider will have instructions
|
output.print_error(f"""This box's reverse DNS is currently {existing_rdns_v4}, but it should be {domain}. Your ISP or cloud provider will have instructions
|
||||||
on setting up reverse DNS for your box.""" )
|
on setting up reverse DNS for this box.""" )
|
||||||
else:
|
else:
|
||||||
output.print_error(f"""Your box's reverse DNS is currently {existing_rdns_v4} (IPv4) and {existing_rdns_v6} (IPv6), but it should be {domain}. Your ISP or cloud provider will have instructions
|
output.print_error(f"""This box's reverse DNS is currently {existing_rdns_v4} (IPv4) and {existing_rdns_v6} (IPv6), but it should be {domain}. Your ISP or cloud provider will have instructions
|
||||||
on setting up reverse DNS for your box.""" )
|
on setting up reverse DNS for this box.""" )
|
||||||
|
|
||||||
# Check the TLSA record.
|
# Check the TLSA record.
|
||||||
tlsa_qname = "_25._tcp." + domain
|
tlsa_qname = "_25._tcp." + domain
|
||||||
|
@ -736,13 +745,22 @@ def check_mail_domain(domain, env, output):
|
||||||
# Stop if the domain is listed in the Spamhaus Domain Block List.
|
# Stop if the domain is listed in the Spamhaus Domain Block List.
|
||||||
# The user might have chosen a domain that was previously in use by a spammer
|
# The user might have chosen a domain that was previously in use by a spammer
|
||||||
# and will not be able to reliably send mail.
|
# and will not be able to reliably send mail.
|
||||||
|
|
||||||
|
# See https://www.spamhaus.org/news/article/807/using-our-public-mirrors-check-your-return-codes-now. for
|
||||||
|
# information on spamhaus return codes
|
||||||
dbl = query_dns(domain+'.dbl.spamhaus.org', "A", nxdomain=None)
|
dbl = query_dns(domain+'.dbl.spamhaus.org', "A", nxdomain=None)
|
||||||
if dbl is None:
|
if dbl is None:
|
||||||
output.print_ok("Domain is not blacklisted by dbl.spamhaus.org.")
|
output.print_ok("Domain is not blacklisted by dbl.spamhaus.org.")
|
||||||
elif dbl == "[timeout]":
|
elif dbl == "[timeout]":
|
||||||
output.print_warning(f"Connection to dbl.spamhaus.org timed out. We could not determine whether the domain {domain} is blacklisted. Please try again later.")
|
output.print_warning(f"Connection to dbl.spamhaus.org timed out. Could not determine whether the domain {domain} is blacklisted. Please try again later.")
|
||||||
elif dbl == "[Not Set]":
|
elif dbl == "[Not Set]":
|
||||||
output.print_warning(f"Could not connect to dbl.spamhaus.org. We could not determine whether the domain {domain} is blacklisted. Please try again later.")
|
output.print_warning(f"Could not connect to dbl.spamhaus.org. Could not determine whether the domain {domain} is blacklisted. Please try again later.")
|
||||||
|
elif dbl == "127.255.255.252":
|
||||||
|
output.print_warning("Incorrect spamhaus query: %s. Could not determine whether the domain %s is blacklisted." % (domain+'.dbl.spamhaus.org', domain))
|
||||||
|
elif dbl == "127.255.255.254":
|
||||||
|
output.print_warning("Mail-in-a-Box is configured to use a public DNS server. This is not supported by spamhaus. Could not determine whether the domain {} is blacklisted.".format(domain))
|
||||||
|
elif dbl == "127.255.255.255":
|
||||||
|
output.print_warning("Too many queries have been performed on the spamhaus server. Could not determine whether the domain {} is blacklisted.".format(domain))
|
||||||
else:
|
else:
|
||||||
output.print_error(f"""This domain is listed in the Spamhaus Domain Block List (code {dbl}),
|
output.print_error(f"""This domain is listed in the Spamhaus Domain Block List (code {dbl}),
|
||||||
which may prevent recipients from receiving your mail.
|
which may prevent recipients from receiving your mail.
|
||||||
|
@ -760,7 +778,7 @@ def check_web_domain(domain, rounded_time, ssl_certificates, env, output):
|
||||||
if value == normalize_ip(expected):
|
if value == normalize_ip(expected):
|
||||||
ok_values.append(value)
|
ok_values.append(value)
|
||||||
else:
|
else:
|
||||||
output.print_error(f"""This domain should resolve to your box's IP address ({rtype} {expected}) if you would like the box to serve
|
output.print_error(f"""This domain should resolve to this box's IP address ({rtype} {expected}) if you would like the box to serve
|
||||||
webmail or a website on this domain. The domain currently resolves to {value} in public DNS. It may take several hours for
|
webmail or a website on this domain. The domain currently resolves to {value} in public DNS. It may take several hours for
|
||||||
public DNS to update after a change. This problem may result from other issues listed here.""")
|
public DNS to update after a change. This problem may result from other issues listed here.""")
|
||||||
return
|
return
|
||||||
|
|
|
@ -224,14 +224,15 @@ tools/editconf.py /etc/postfix/main.cf -e lmtp_destination_recipient_limit=
|
||||||
# * `reject_unlisted_recipient`: Although Postfix will reject mail to unknown recipients, it's nicer to reject such mail ahead of greylisting rather than after.
|
# * `reject_unlisted_recipient`: Although Postfix will reject mail to unknown recipients, it's nicer to reject such mail ahead of greylisting rather than after.
|
||||||
# * `check_policy_service`: Apply greylisting using postgrey.
|
# * `check_policy_service`: Apply greylisting using postgrey.
|
||||||
#
|
#
|
||||||
|
# Note the spamhaus rbl return codes are taken into account as adviced here: https://docs.spamhaus.com/datasets/docs/source/40-real-world-usage/PublicMirrors/MTAs/020-Postfix.html
|
||||||
# Notes: #NODOC
|
# Notes: #NODOC
|
||||||
# permit_dnswl_client can pass through mail from whitelisted IP addresses, which would be good to put before greylisting #NODOC
|
# permit_dnswl_client can pass through mail from whitelisted IP addresses, which would be good to put before greylisting #NODOC
|
||||||
# so these IPs get mail delivered quickly. But when an IP is not listed in the permit_dnswl_client list (i.e. it is not #NODOC
|
# so these IPs get mail delivered quickly. But when an IP is not listed in the permit_dnswl_client list (i.e. it is not #NODOC
|
||||||
# whitelisted) then postfix does a DEFER_IF_REJECT, which results in all "unknown user" sorts of messages turning into #NODOC
|
# whitelisted) then postfix does a DEFER_IF_REJECT, which results in all "unknown user" sorts of messages turning into #NODOC
|
||||||
# "450 4.7.1 Client host rejected: Service unavailable". This is a retry code, so the mail doesn't properly bounce. #NODOC
|
# "450 4.7.1 Client host rejected: Service unavailable". This is a retry code, so the mail doesn't properly bounce. #NODOC
|
||||||
tools/editconf.py /etc/postfix/main.cf \
|
tools/editconf.py /etc/postfix/main.cf \
|
||||||
smtpd_sender_restrictions="reject_non_fqdn_sender,reject_unknown_sender_domain,reject_authenticated_sender_login_mismatch,reject_rhsbl_sender dbl.spamhaus.org" \
|
smtpd_sender_restrictions="reject_non_fqdn_sender,reject_unknown_sender_domain,reject_authenticated_sender_login_mismatch,reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99]" \
|
||||||
smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,"reject_rbl_client zen.spamhaus.org",reject_unlisted_recipient,"check_policy_service inet:127.0.0.1:10023"
|
smtpd_recipient_restrictions="permit_sasl_authenticated,permit_mynetworks,reject_rbl_client zen.spamhaus.org=127.0.0.[2..11],reject_unlisted_recipient,check_policy_service inet:127.0.0.1:10023"
|
||||||
|
|
||||||
# Postfix connects to Postgrey on the 127.0.0.1 interface specifically. Ensure that
|
# Postfix connects to Postgrey on the 127.0.0.1 interface specifically. Ensure that
|
||||||
# Postgrey listens on the same interface (and not IPv6, for instance).
|
# Postgrey listens on the same interface (and not IPv6, for instance).
|
||||||
|
|
Loading…
Reference in New Issue