mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-05-31 17:40:54 +00:00
Merge b41c34034f
into 05c2f3c9a2
This commit is contained in:
commit
ca361f3f4b
@ -283,7 +283,7 @@ def run_network_checks(env, output):
|
|||||||
# 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.
|
||||||
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+get_spamhaus_query_url(env, 'zen'), 'A', nxdomain=None)
|
||||||
evaluate_spamhaus_lookup(env['PUBLIC_IP'], 'IPv4', rev_ip4, output, zen)
|
evaluate_spamhaus_lookup(env['PUBLIC_IP'], 'IPv4', rev_ip4, output, zen)
|
||||||
|
|
||||||
if not env['PUBLIC_IPV6']:
|
if not env['PUBLIC_IPV6']:
|
||||||
@ -292,8 +292,26 @@ def run_network_checks(env, output):
|
|||||||
from ipaddress import IPv6Address
|
from ipaddress import IPv6Address
|
||||||
|
|
||||||
rev_ip6 = ".".join(reversed(IPv6Address(env['PUBLIC_IPV6']).exploded.split(':')))
|
rev_ip6 = ".".join(reversed(IPv6Address(env['PUBLIC_IPV6']).exploded.split(':')))
|
||||||
zen = query_dns(rev_ip6+'.zen.spamhaus.org', 'A', nxdomain=None)
|
zen = query_dns(rev_ip6+get_spamhaus_query_url(env, 'zen'), 'A', nxdomain=None)
|
||||||
evaluate_spamhaus_lookup(env['PUBLIC_IPV6'], 'IPv6', rev_ip6, output, zen)
|
evaluate_spamhaus_lookup(env['PUBLIC_IPV6'], 'IPv6', rev_ip6, output, zen)
|
||||||
|
|
||||||
|
|
||||||
|
def get_spamhaus_query_url(env, selector):
|
||||||
|
# Filter on valid selectors
|
||||||
|
if not selector in ('zen', 'dbl'):
|
||||||
|
# Set default so at least something is returned
|
||||||
|
selector = 'zen'
|
||||||
|
|
||||||
|
# Default public block list
|
||||||
|
spamhaus_url = '.'+selector+'.spamhaus.org'
|
||||||
|
|
||||||
|
# Check if system makes use of Spamhaus Data Query Service, see https://portal.spamhaus.com/dqs/?ft=1#3.1
|
||||||
|
env_key = 'SPAMHAUS_DQS_KEY'
|
||||||
|
if env_key in env and len(env[env_key]) > 0:
|
||||||
|
dqs_key = env[env_key]
|
||||||
|
spamhaus_url = '.'+dqs_key+'.'+selector+'.dq.spamhaus.net'
|
||||||
|
|
||||||
|
return spamhaus_url
|
||||||
|
|
||||||
|
|
||||||
def evaluate_spamhaus_lookup(lookupaddress, lookuptype, lookupdomain, output, zen):
|
def evaluate_spamhaus_lookup(lookupaddress, lookuptype, lookupdomain, output, zen):
|
||||||
@ -766,7 +784,8 @@ def check_mail_domain(domain, env, output):
|
|||||||
|
|
||||||
# See https://www.spamhaus.org/news/article/807/using-our-public-mirrors-check-your-return-codes-now. for
|
# See https://www.spamhaus.org/news/article/807/using-our-public-mirrors-check-your-return-codes-now. for
|
||||||
# information on spamhaus return codes
|
# information on spamhaus return codes
|
||||||
dbl = query_dns(domain+'.dbl.spamhaus.org', "A", nxdomain=None)
|
dbl = query_dns(domain+get_spamhaus_query_url(env, 'dbl'), "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]":
|
||||||
|
@ -223,10 +223,12 @@ tools/editconf.py /etc/postfix/main.cf -e lmtp_destination_recipient_limit=
|
|||||||
# * `reject_non_fqdn_sender`: Reject not-nice-looking return paths.
|
# * `reject_non_fqdn_sender`: Reject not-nice-looking return paths.
|
||||||
# * `reject_unknown_sender_domain`: Reject return paths with invalid domains.
|
# * `reject_unknown_sender_domain`: Reject return paths with invalid domains.
|
||||||
# * `reject_authenticated_sender_login_mismatch`: Reject if mail FROM address does not match the client SASL login
|
# * `reject_authenticated_sender_login_mismatch`: Reject if mail FROM address does not match the client SASL login
|
||||||
# * `reject_rhsbl_sender`: Reject return paths that use blacklisted domains.
|
|
||||||
# * `permit_sasl_authenticated`: Authenticated users (i.e. on port 587) can skip further checks.
|
# * `permit_sasl_authenticated`: Authenticated users (i.e. on port 587) can skip further checks.
|
||||||
# * `permit_mynetworks`: Mail that originates locally can skip further checks.
|
# * `permit_mynetworks`: Mail that originates locally can skip further checks.
|
||||||
# * `reject_rbl_client`: Reject connections from IP addresses blacklisted in zen.spamhaus.org
|
# * `reject_rbl_client`: Reject connections from IP addresses blacklisted in zen.spamhaus.org
|
||||||
|
# * `reject_rhsbl_sender`: Reject the request when the MAIL FROM domain is listed in spamhaus.org
|
||||||
|
# * `reject_rhsbl_helo`: Reject the request when the HELO or EHLO hostname is listed in spamhaus.org
|
||||||
|
# * `reject_rhsbl_reverse_client`: Reject the request when the unverified reverse client hostname is listed in spamhaus.org
|
||||||
# * `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.
|
||||||
#
|
#
|
||||||
@ -236,9 +238,91 @@ tools/editconf.py /etc/postfix/main.cf -e lmtp_destination_recipient_limit=
|
|||||||
# 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 \
|
# In case the Spamhaus Data Query Service is used, slightly different configuration is needed. Source: https://portal.spamhaus.com/dqs/?ft=1#3.1.2
|
||||||
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]" \
|
# Zero Reputation Domain (ZRD) blocklist is limited to two hour old domains, not 24 like suggested by Spamhaus.
|
||||||
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,check_policy_service inet:127.0.0.1:12340"
|
|
||||||
|
# smtpd_recipient_restrictions is different whether Spamhaus DQS is used or not.
|
||||||
|
# Start definition of the configuration here
|
||||||
|
CONF_SMTPD_RECIPIENT_RESTRICTIONS=$(cat <<-END
|
||||||
|
permit_sasl_authenticated,
|
||||||
|
permit_mynetworks,
|
||||||
|
check_sender_access hash:/etc/postfix/sender_access,
|
||||||
|
check_recipient_access hash:/etc/postfix/recipient_access,
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ -z "${SPAMHAUS_DQS_KEY:-}" ]; then
|
||||||
|
# Public spamhaus blocklist servers queried
|
||||||
|
DBL_QUERY=dbl.spamhaus.org
|
||||||
|
ZEN_QUERY=zen.spamhaus.org
|
||||||
|
|
||||||
|
CONF_SMTPD_RECIPIENT_RESTRICTIONS=$(cat <<-END
|
||||||
|
$CONF_SMTPD_RECIPIENT_RESTRICTIONS
|
||||||
|
reject_rbl_client $ZEN_QUERY=127.0.0.[2..11],
|
||||||
|
reject_rhsbl_sender $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
reject_rhsbl_helo $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
reject_rhsbl_reverse_client $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
warn_if_reject reject_rbl_client $ZEN_QUERY=127.255.255.[1..255],
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
# Cleanup dnsbl reply mapping, potentially set when DQS was enabled previously
|
||||||
|
tools/editconf.py /etc/postfix/main.cf -e rbl_reply_maps=
|
||||||
|
|
||||||
|
rm -rf /etc/postfix/dnsbl-reply-map
|
||||||
|
else
|
||||||
|
# Use Data Query Service for blocklist query URLs
|
||||||
|
DBL_QUERY=$SPAMHAUS_DQS_KEY.dbl.dq.spamhaus.net
|
||||||
|
ZEN_QUERY=$SPAMHAUS_DQS_KEY.zen.dq.spamhaus.net
|
||||||
|
ZRD_QUERY=$SPAMHAUS_DQS_KEY.zrd.dq.spamhaus.net
|
||||||
|
|
||||||
|
CONF_SMTPD_RECIPIENT_RESTRICTIONS=$(cat <<-END
|
||||||
|
$CONF_SMTPD_RECIPIENT_RESTRICTIONS
|
||||||
|
reject_rhsbl_sender $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
reject_rhsbl_helo $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
reject_rhsbl_reverse_client $DBL_QUERY=127.0.1.[2..99],
|
||||||
|
reject_rhsbl_sender $ZRD_QUERY=127.0.2.2,
|
||||||
|
reject_rhsbl_helo $ZRD_QUERY=127.0.2.2,
|
||||||
|
reject_rhsbl_reverse_client $ZRD_QUERY=127.0.2.2,
|
||||||
|
reject_rbl_client $ZEN_QUERY=127.0.0.[2..255],
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
# Setup dnsbl reply mapping, to avoid leaking your DQS key in reject messages
|
||||||
|
cat > /etc/postfix/dnsbl-reply-map <<- EOF;
|
||||||
|
$ZEN_QUERY=127.0.0.[2..255] \$rbl_code Service unavailable; \$rbl_class [\$rbl_what] blocked using zen.spamhaus.org\${rbl_reason?; \$rbl_reason}
|
||||||
|
$DBL_QUERY=127.0.1.[2..99] \$rbl_code Service unavailable; \$rbl_class [\$rbl_what] blocked using dbl.spamhaus.org\${rbl_reason?; \$rbl_reason}
|
||||||
|
$ZRD_QUERY=127.0.2.2 \$rbl_code Service unavailable; \$rbl_class [\$rbl_what] blocked using zrd.spamhaus.org\${rbl_reason?; \$rbl_reason}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
postmap hash:/etc/postfix/dnsbl-reply-map
|
||||||
|
|
||||||
|
tools/editconf.py /etc/postfix/main.cf \
|
||||||
|
rbl_reply_maps=hash:/etc/postfix/dnsbl-reply-map
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define configuration for smtpd_sender_restrictions
|
||||||
|
CONF_SMTPD_SENDER_RESTRICTIONS=$(cat <<-END
|
||||||
|
reject_non_fqdn_sender,
|
||||||
|
reject_unknown_sender_domain,
|
||||||
|
reject_authenticated_sender_login_mismatch,
|
||||||
|
reject_rhsbl_sender $DBL_QUERY=127.0.1.[2..99]
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
# Finalize configuration for smtpd_recipient_restrictions
|
||||||
|
CONF_SMTPD_RECIPIENT_RESTRICTIONS=$(cat <<-END
|
||||||
|
$CONF_SMTPD_RECIPIENT_RESTRICTIONS
|
||||||
|
reject_unlisted_recipient,
|
||||||
|
check_policy_service inet:127.0.0.1:10023,
|
||||||
|
check_policy_service inet:127.0.0.1:12340
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
# Apply configuration
|
||||||
|
tools/editconf.py /etc/postfix/main.cf -w \
|
||||||
|
smtpd_sender_restrictions="$CONF_SMTPD_SENDER_RESTRICTIONS" \
|
||||||
|
smtpd_recipient_restrictions="$CONF_SMTPD_RECIPIENT_RESTRICTIONS"
|
||||||
|
|
||||||
# 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).
|
||||||
|
@ -141,6 +141,35 @@ tools/editconf.py /etc/spamassassin/local.cf -s \
|
|||||||
mkdir -p "$STORAGE_ROOT/mail/spamassassin"
|
mkdir -p "$STORAGE_ROOT/mail/spamassassin"
|
||||||
chown -R spampd:spampd "$STORAGE_ROOT/mail/spamassassin"
|
chown -R spampd:spampd "$STORAGE_ROOT/mail/spamassassin"
|
||||||
|
|
||||||
|
## Configure usage of Spamhaus DQS Key (see https://github.com/spamhaus/spamassassin-dqs?tab=readme-ov-file#instructions-for-spamassassin-341-to-346)
|
||||||
|
|
||||||
|
if [ -z "${SPAMHAUS_DQS_KEY:-}" ]; then
|
||||||
|
# Using public spamhaus servers, cleanup possible dqs configuration
|
||||||
|
rm -f /etc/spamassassin/SH.pm
|
||||||
|
rm -f /etc/spamassassin/sh.cf
|
||||||
|
rm -f /etc/spamassassin/sh.pre
|
||||||
|
rm -f /etc/spamassassin/sh_scores.cf
|
||||||
|
else
|
||||||
|
# Using Spamhaus DQS servers
|
||||||
|
|
||||||
|
# Get the source files
|
||||||
|
wget_verify https://raw.githubusercontent.com/spamhaus/spamassassin-dqs/f1baa2597443bc99b2777050383717de50eca2ce/3.4.1%2B/SH.pm 8e58b56e8a34899b50ba1a7e3d047ad1bef2e69c /tmp/SH.pm
|
||||||
|
wget_verify https://raw.githubusercontent.com/spamhaus/spamassassin-dqs/f1baa2597443bc99b2777050383717de50eca2ce/3.4.1%2B/sh.cf bdee2576b2400e3b284f5ab4b9c99faa39ad49c7 /tmp/sh.cf
|
||||||
|
wget_verify https://raw.githubusercontent.com/spamhaus/spamassassin-dqs/f1baa2597443bc99b2777050383717de50eca2ce/3.4.1%2B/sh.pre c73b2d9b5dae37864acf5479966f248dc6be4ee9 /tmp/sh.pre
|
||||||
|
wget_verify https://raw.githubusercontent.com/spamhaus/spamassassin-dqs/f1baa2597443bc99b2777050383717de50eca2ce/3.4.1%2B/sh_scores.cf 0e7360514245760754ee92172c275545a77a5860 /tmp/sh_scores.cf
|
||||||
|
|
||||||
|
# Insert the DQS Key
|
||||||
|
sed -i -e 's/your_DQS_key/'$SPAMHAUS_DQS_KEY'/g' /tmp/sh.cf
|
||||||
|
|
||||||
|
# Modify the configuration directory
|
||||||
|
sed -i -e 's/<config_directory>/\/etc\/spamassassin/g' /tmp/sh.pre
|
||||||
|
|
||||||
|
mv -f /tmp/SH.pm /etc/spamassassin/
|
||||||
|
mv -f /tmp/sh.cf /etc/spamassassin/
|
||||||
|
mv -f /tmp/sh.pre /etc/spamassassin/
|
||||||
|
mv -f /tmp/sh_scores.cf /etc/spamassassin/
|
||||||
|
fi
|
||||||
|
|
||||||
# To mark mail as spam or ham, just drag it in or out of the Spam folder. We'll
|
# To mark mail as spam or ham, just drag it in or out of the Spam folder. We'll
|
||||||
# use the Dovecot antispam plugin to detect the message move operation and execute
|
# use the Dovecot antispam plugin to detect the message move operation and execute
|
||||||
# a shell script that invokes learning.
|
# a shell script that invokes learning.
|
||||||
|
Loading…
Reference in New Issue
Block a user