Setup Email Server From Scratch Debian #2 - 10 Blocking Spam
We believe in data independence, and support others who want data independence.
Debian Email From Scratch version 2 finished 2025-07-30.
We are still adding to it but it all works!
#################
# Blocking Spam #
#################
# Change your smtpd banner to provide less information about your mail service
nano /etc/postfix/main.cf
# --- change this --
smtpd_banner = $myhostname ESMTP
# ---
# Reject email from hosts with invalid A Record or no PTR Record
# reject_unknown_sender_domain : no MX or A Record
# reject_unknown_client_hostname : no client A Record
# reject_unknown_reverse_client_hostname : NO PTR IPADDRESS -> NAME
nano /etc/postfix/main.cf
# --- edit at bottom of file
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_unknown_reverse_client_hostname
reject_unknown_client_hostname
# Reject invalid HELO/EHLO
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks
permit_sasl_authenticated
check_helo_access hash:/etc/postfix/helo_access
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = unix:opendkim/opendkim.sock,unix:opendmarc/opendmarc.sock
non_smtpd_milters = $smtpd_milters
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
# Pass bounces to milters so bounce messages also get DKIM signed are are not rejected
internal_mail_filter_classes = bounce
# ---
nano /etc/postfix/helo_access
# ---
# whitelist legitimate servers that don't conform to helo
optimus-webapi-prod-2.localdomain OK
va-massmail-02.rakutenmarketing.com OK
goodhost1.domain1.com OK
goodhost1.domain2.com OK
# ---
postmap /etc/postfix/helo_access
systemctl restart postfix
# Enable Greylisting in Postfix
# Quote from linuxbabe "As required by the SMTP protocol, any legitimate SMTP
# client must be able to re-send email if delivery fails. (By default, Postfix
# is configured to resend failed emails many times before it informs the sender
# that the message could not be delivered.) Many spammers usually just send once
# and would not retry."
apt install postgrey
systemctl enable postgrey
systemctl start postgrey
systemctl status postgrey
netstat -lnpt | grep postgrey
tcp 0 0 127.0.0.1:10023 0.0.0.0:* LISTEN 3861/postgrey --ine
tcp6 0 0 ::1:10023 :::* LISTEN 3861/postgrey --ine
# Add check_policy_service inet:127.0.0.1:10023 to smtpd_recipient_restrictions
nano /etc/postfix/main.cf
# ---
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
check_policy_service inet:127.0.0.1:10023
# ---
nano /etc/defaults/postgrey
# ---
POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=1"
POSTGREY_TEXT="4.7.1 Greylisted"
# ---
# To prevent postgrey from slowing down legitimate mails, use to 2 DNS entries so the
# mail server will first try the entry with priority 0 then after 1 second try the
# entry with priority 10, eg a resend and less likely to be spam.
# To prevent greylisting delay add 2 mx records to your DNS, like this.
MX mx.okdeb.com 0
MX mail.okdeb.com 10
systemctl restart postfix
# View postgrey logs, see what is being blocked, to see if new entries need to
# be added to whitelist.
journalctl -u postgrey.
# Postgrey default whitelist files are located in
# /etc/postgrey/whitelist_clients
# /etc/postgrey/whitelist_recipients
# Restart postgrey chaning postgrey whitelists
systemctl restart postgrey
# Real Time Blacklists - add the after check_policy_service inet:127.0.0.1:10023
nano /usr/local/etc/postfix/main.cf
# ---
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
check_policy_service inet:127.0.0.1:10023,
check_client_access hash:/etc/postfix/rbl_override,
reject_rhsbl_helo dbl.spamhaus.org,
reject_rhsbl_reverse_client dbl.spamhaus.org,
reject_rhsbl_sender dbl.spamhaus.org,
reject_rbl_client zen.spamhaus.org
# ---
# You can override the blacklists by adding domains to the rbl_override file.
nano /etc/postfix/rbl_override
# ---
domain1.com OK // ignore rbl for domain1.com
domain2.com OK // ignore rbl for domain2.com
# ---
postmap /etc/postfix/rbl_override
# Use a Public Whitelist
nano /usr/local/etc/postfix/main.cf
# ---
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf,
check_policy_service inet:127.0.0.1:10023,
check_client_access hash:/etc/postfix/rbl_override,
reject_rhsbl_helo dbl.spamhaus.org,
reject_rhsbl_reverse_client dbl.spamhaus.org,
reject_rhsbl_sender dbl.spamhaus.org,
permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3],
permit_dnswl_client swl.spamhaus.org,
reject_rbl_client zen.spamhaus.org
# ---
# Get Postfix Log Reports
apt install pflogsumm mutt
# test it
/usr/bin/journalctl --no-pager --since=yesterday -u postfix@-.service | /usr/sbin/pflogsumm -d yesterday
# Setup a crontab to send a report at 12:00am.
export EDITOR /usr/bin/nano
crontab -e
# ---
5 0 * * * /usr/bin/journalctl --no-pager --since=yesterday -u postfix@-.service | /usr/sbin/pflogsumm -d yesterday | mutt -s "Postfix log summary" -- postmaster@okdeb.com
# ---
# Make sure you are not an open relay
nano /usr/local/etc/postfix/main.cf
# ---
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
# ---
# We setup DMARC in a prevous page, make sure your 'myhostname' from postfix/main.cf
# is included in /etc/opendmarc.conf as TrustedAuthservIDs, mine is mx.okdeb.com.
grep myhostname /etc/postfix/main.cf
myhostname = mx.okdeb.com
nano /etc/opendmarc.conf
# ---
TrustedAuthservIDs mx.okdeb.com
# ---
nano /etc/opendmarc/ignore.hosts
# ---
127.0.0.1
147.135.65.9
2604:2dc0:202:300::3645
::1
localhost
# ---
# Dont DKIM check your own hosts
nano /etc/opendkim/trustedhosts
# ---
127.0.0.1
::1
localhost
15.204.113.148
2604:2dc0:202:300::3645
mx.okdeb.com
mx.coragarden.com
mail.okdeb.com
mail.coragarden.com
okdeb.com
coragarden.com
# ---
systemctl restart opendkim opendmarc postfix dovecot
# Check everything works
# If everything works, back it up.