Setup Email Server From Scratch On FreeBSD #2 - 10 Blocking Spam
09 Create Virtual Domains <- Intro -> 25 IMAPSYNC
We believe in data independence, and support others who want data independence.
This tutorial is partially complete 2025-08-07
This is version 2 and everthing works up to and including Roundcube.
#################
# Blocking Spam #
#################
nano /etc/postfix/main.cf
# Reject if no A Record
# Reject email from hosts with invalid A Record or no PTR Record
# sender MX or A
# client A
# reverse PTR
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unknown_sender_domain
reject_unknown_client_hostname
reject_unknown_reverse_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
nano /etc/postfix/helo_access
# ---
goodhost1.domain1.com OK
goodhost1.domain2.com OK
# ---
postmap /etc/postfix/helo_access
service postfix restart
# PostGrey
# 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."
# 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 smtp.okbsd.com 0
MX mail.okbsd.com 10
# Install PostGrey and enable and set the 1 second delay in /etc/rc.conf
pkg install postgrey
sysrc postgrey_enable="YES"
sysrc postgrey_flags=" --inet=10023 --delay=1 --greylist-text='greylisted'"
service postgrey start
service postgrey status
# Check if it is listening
sockstat | grep postgrey
postgrey perl 24350 4 dgram -> /var/run/log
postgrey perl 24350 5 tcp6 ::1:10023 *:*
postgrey perl 24350 6 tcp4 127.0.0.1:10023 *:*
# Add Postgrey port 10023 to postfix/main.cf
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
# ---
# Postgrey default whitelist files are located in
# /usr/local/etc/postfix/postgrey_whitelist_clients
# /usr/local/etc/postfix/postgrey_whitelist_recipients
service postfix restart
# Real Time Blacklists
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:/usr/local/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
nano /usr/local/etc/postfix/rbl_override
# ---
domain1.com OK // ignore rbl for domain1.com
domain2.com OK // ignore rbl for domain2.com
# ---
postmap /usr/local/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
# Postfix Log Reports
pkg install pflogsumm
pkg install mutt
# test it
pflogsumm /var/log/maillog -d today /var/log/maillog
# Setup a crontab to send a report at 12:30am. Initially I used maillog but it rotates
# by default at 12am so yesterday has been rotated by the time we read the log. So read
# the last compressed rotation and pipe that to pflogsumm and send the report.
crontab -e
# ---
30 0 * * * bzcat /var/log/maillog.0.bz2 | pflogsumm -d yesterday | /usr/local/bin/mutt -s "Postfix log summary" -- admin@okbsd.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, but make sure your myhostname in postfix/main.cf
# is included in TrustedAuthservIDs, mine is smtp.okbsd.com
nano /usr/local/etc/mail/opendmarc.conf
# ---
TrustedAuthservIDs localhost,smtp.okbsd.com,mail.okbsd.com
# ---
nano /usr/local/etc/mail/ignore.hosts
# ---
127.0.0.1
147.135.65.9
2604:2dc0:200:187::1
::1
localhost
smtp.okbsd.com
# ---
# Dont DKIM check your own hosts
nano /usr/local/etc/mail/trustedhosts
# ---
127.0.0.1
localhost
147.135.37.135
2604:2dc0:200:187::1
*.okbsd.com
okbsd.com
*.coragarden.com
coragarden.com
# ---
service postfix restart
# Check everything works
# If everything works back it up with tar like we did before.
# unbound
drill -k /usr/local/etc/unbound/root.key -S okbsd.com @127.0.0.1