HARDENING POSTFIX

SYSTEM-WIDE SETUP

give a name to your root account (something that helps identify the system)

vipw

root@slackmx

proceed with system-wide mail setup

# Old-school Sendmail
cp -pi /etc/mail/aliases /etc/mail/aliases.dist
vi /etc/mail/aliases

# Postfix
cp -pi /etc/aliases /etc/aliases.dist
vi /etc/aliases

we don’t want redirections here, for once, as we’re actually hosting the messages locally. Note the abuse mail alias SHOULD be defined

root:           REAL-USER
contact:        root
info:           root
abuse:          root
postmaster:     root
MAILER-DAEMON:  root
hostmaster:     root
www:            root
webmaster:      root

eventually get rid of the root alias so you read the bounces locally e.g. w/ Alpine and w/o mixup those up with other messages.

and apply

newaliases
#postalias /etc/mail/aliases
#postalias /etc/aliases
ls -lF /etc/mail/aliases*
ls -lF /etc/aliases*

START CLEAN

cd /etc/postfix/
diff -bu main.cf.proto main.cf | less
diff -bu master.cf.proto master.cf # identical

mv -i main.cf main.cf.dist
grep -vE '^[[:space:]]*(#|$)' main.cf.dist > main.cf
grep -vE '^[[:space:]]*(#|$)' main.cf.dist > main.cf.dist.clean

mv -i master.cf master.cf.dist
sed '/^#/d; /^$/d' master.cf.dist > master.cf
sed '/^#/d; /^$/d' master.cf.dist > master.cf.dist.clean

WARNING

always check the configuration manual for accuracy of the features. those merely depend on the exact Postfix version you are using. we are talking Postfix 3.1.0, 3.1.4, 3.3.0 here.

postconf -d | grep version
man 5 postconf

if you are unsure about some restriction, you can evaluate it even on production with

        warn_if_reject,

and always check the configuration syntax before restart

postfix check && echo ok

SUPPORTING FILES

NETWORK

cat > /etc/postfix/access.network <<-EOF
compute.amazonaws.com   REJECT too much SPAM from compute.amazonaws.com
.compute.amazonaws.com  REJECT too much SPAM from compute.amazonaws.com
EOF
postmap /etc/postfix/access.network

EHLO

cat > /etc/postfix/access.helo.regexp <<-EOF
/^slackmx\.nethence\.com$/      550 you are not me
/^nethence\.com$/               550 you are not me
EOF
cat /etc/postfix/access.helo.regexp 

MAIL FROM

cat > /etc/postfix/access.sender <<-EOF
#securityfocus.com       OK
online.net              OK
ovh.com                 OK
EOF
postmap /etc/postfix/access.sender

Make sure the DNSRBL lists you are targeting are still alive

for zone in bl.spamcop.net cbl.abuseat.org psbl.surriel.com truncate.gbudb.net db.wpbl.info spam.spamrats.com dnsbl.dronebl.org ix.dnsbl.manitu.net bl.blocklist.de dnsbl.sorbs.net dnsbl-1.uceprotect.net b.barracudacentral.org zen.spamhaus.org; do
    echo $zone
    host 2.0.0.127.$zone
    echo
done; unset zone

DEFAULTS

vi /etc/postfix/main.cf

we are starting with those defaults on v3.5.2 from source on slackware-current

compatibility_level = 2
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
unknown_local_recipient_reject_code = 550
debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
#distro
#manpage_directory = /usr/man
#from scratch
manpage_directory = /usr/local/man
sample_directory = /etc/postfix
readme_directory = no
inet_protocols = ipv4
meta_directory = /etc/postfix
shlib_directory = no

some defaults differ from netbsd’s built-in postfix

smtputf8_enable=no
inet_protocols = all

TODO consider SMTPUTF8 otherwise you would get

SMTPUTF8 is required, but was not offered by host ...

or with those defaults on bionic/3.3.0

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

we are only fixing those (if not already disabled)

html_directory = no
sample_directory = no
readme_directory = no
shlib_directory = no

and adding those

# BSD
alias_database = hash:/etc/mail/aliases
alias_maps = hash:/etc/mail/aliases

# GNU/Linux
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases

MAIN CONFIG & RELAY

eventually add space-separated CIDRs to mynetworks e.g. for Docker (172.17.0.0/16) or local subnets

note myorigin defaults to myhostname and mydomain defaults to FQDN minus the first component

note we are using the simple form of myorigin, pointing to the FQDN, because we are using pools for outbound, so it’s best to differenciate relays.

myhostname = slackmx.nethence.com
myorigin = slackmx.nethence.com
mydomain = nethence.com
mydestination = slackmx.nethence.com, nethence.com

# bypass any blacklists and restrictions - we want our own hosts to be able to
# deliver daily reports
mynetworks = 127.0.0.1/32,
    FRIENDLY-IP/32

#w/o permit_sasl_authenticated, we use a dedicated port for that
smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination

CASUAL

we are now adding casual settings, nothing fancy so far, and disabling SASL on port 25

#happy procmail https://www.mhonarc.org/archive/html/procmail/2003-01/msg00219.html
mailbox_size_limit = 0

#10MB --> 25MB
#message_size_limit (default: 10240000)
message_size_limit = 26214400

#home_mailbox = Maildir/
#defaults to $myhostname ESMTP $mail_name
smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes
enable_long_queue_ids = yes
smtpd_sasl_auth_enable = no

NETWORK

smtpd_soft_error_limit = 5 
smtpd_error_sleep_time = 3s
smtpd_hard_error_limit = 10

smtpd_client_restrictions = permit_mynetworks, reject_unauth_pipelining,
    reject_unknown_client_hostname,
    check_client_access hash:/etc/postfix/access.network,
    reject_rbl_client bl.spamcop.net,
    reject_rbl_client cbl.abuseat.org,
    reject_rbl_client psbl.surriel.com,
    reject_rbl_client truncate.gbudb.net,
    reject_rbl_client db.wpbl.info,
    reject_rbl_client dnsbl.dronebl.org,
    reject_rbl_client ix.dnsbl.manitu.net,
    reject_rbl_client bl.blocklist.de,
    reject_rbl_client b.barracudacentral.org,
    reject_rbl_client zen.spamhaus.org

#this blocks nine.pairlist.net / hackrf-dev-bounces@greatscottgadgets.com
#       reject_rbl_client spam.spamrats.com,

#this blocks orange.fr...
#       reject_rbl_client dnsbl.sorbs.net,
#       reject_rbl_client dnsbl-1.uceprotect.net,

# those are gone
#       reject_rbl_client dnsbl.inps.de,
#       reject_rbl_client public.sarbl.org,

# The RFC-Ignorant.org DNS lists are closed effective 2012-10-30.
#       reject_rhsbl_sender bogusmx.rfc-ignorant.org,
#       reject_rhsbl_sender dsn.rfc-ignorant.org,

# this is too restrictive
#       reject_rhsbl_sender dsn.rfc-clueless.org,

# apews is blocking online.net ip range
#       reject_rbl_client l2.apews.org,

#reject_unknown_client_hostname --> unknown_client_reject_code
#reject_unknown_reverse_client_hostname --> unknown_client_reject_code
unknown_client_reject_code   = 554

#smtpd_client_port_logging = yes

EHLO

smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks, reject_unauth_pipelining,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname,
    reject_unknown_helo_hostname,
    regexp:/etc/postfix/access.helo.regexp

#reject_unknown_helo_hostname --> unknown_hostname_reject_code
unknown_hostname_reject_code = 554

MAIL FROM & SPF

smtpd_sender_restrictions = permit_mynetworks, reject_unauth_pipelining,
    check_sender_access hash:/etc/postfix/access.sender,
    reject_non_fqdn_sender,
    reject_unknown_sender_domain,
    check_policy_service unix:private/policy

#deprecated: policy_time_limit = 3600
smtpd_policy_service_request_limit = 1

RCPT TO

smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_pipelining,
    reject_non_fqdn_recipient,
    reject_unknown_recipient_domain

#reject_unknown_sender_domain --> unknown_address_reject_code
#reject_unknown_recipient_domain --> unknown_address_reject_code
unknown_address_reject_code = 554

DATA

#client speaks too early
smtpd_data_restrictions = reject_unauth_pipelining

PROCMAIL

mailbox_command = /usr/bin/procmail
#mailbox_command = /usr/pkg/bin/procmail
#mailbox_command = /usr/local/bin/procmail

eventually see procmail for more details

STARTTLS

see postfix-tls

SPF OUTBOUND RECORDS

setup your MX and SPF DNS records accordingly

SPF INBOUND CHECKS

see SPF INBOUND for installing policyd-spf depending on your system

now enable the SPF inbound check and port 25 WITHOUT SASL

vi /etc/postfix/master.cf

policy    unix  -       n       n       -       0       spawn
    user=nobody argv=/usr/bin/policyd-spf
    #user=nobody argv=/usr/pkg/bin/policyd-spf

note check_policy_service unix:private/policy and smtpd_policy_service_request_limit above in smtpd_sender_restrictions

READY TO GO

start and enable

vi /etc/rc.local

#self verbose
/usr/sbin/postfix start

status

postfix status
ps auxfww | grep postfix | grep -v grep
ls -lF /var/spool/postfix/private/policy

OPERATIONS & ACCEPTANCE

finally operate the daemon and proceed with acceptance testing

ADDITIONAL NOTES

chroot

ls -lF /var/spool/postfix/etc/
diff /etc/localtime /var/spool/postfix/etc/localtime
diff /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
diff /etc/services /var/spool/postfix/etc/services

no symlink inside the chroot

#cp -f /etc/localtime /var/spool/postfix/etc/localtime

backup mx

Warning: I start to consider that this is a bad practice, as it is just too painful to maintain two MXes at once (otherwise spams come through your seconday MX server)

Play with relay_domains, transport_maps and do NOT list example.com into mydestination. Here’s a minimal setup

#backup MX
smtpd_banner = ESMTP
relay_domains = nethence.com
myhostname = ssd.nethence.com
myorigin = ssd.nethence.com
mydestination = ssd.nethence.com
mynetworks = 127.0.0.1/32

You also have to enable outbound STARTTLS in case the primary MX enforces it. Otherwise you would get

530 5.7.0 Must issue a STARTTLS command first (in reply to MAIL FROM command)

Finally, on the other side (primary MX), eventually add the backup MX into mynetworks or fine tune everything to make sure the relaying works accordingly. SPF should pass through already, as long as you’ve setup the appropriate DNS record for the backup MX.

FAIL2BAN

eventually enable Fail2ban as an attempt to protect yourself from bot nets. but a parser going through logs is less than ideal – rather go for netbsd/blacklistd

TROUBLES

while using mail

postdrop: warning: unable to look up public/pickup: No such file or directory

==> you forgot to start postfix

TODO memcache

Postfix memcache client Howto http://www.postfix.org/MEMCACHE_README.html

TODO dovecot director / LMTP vs direct storage

Director https://wiki2.dovecot.org/Director

Dovecot mailstore performance tuning https://dovecot.org/pipermail/dovecot/2014-July/097120.html

How To Configure a Mail Server Using Postfix, Dovecot, MySQL, and SpamAssassin https://www.digitalocean.com/community/tutorials/how-to-configure-a-mail-server-using-postfix-dovecot-mysql-and-spamassassin

Difference btw. Dovecot Director and Dovecot Proxy https://dovecot.org/pipermail/dovecot/2014-July/097112.html

vs

Postfix feature overview –> Postfix file system requirements http://www.postfix.org/features.html

RESOURCES

Wietse Zweitze Venema http://www.porcupine.org/wietse/ http://www.porcupine.org/forensics/wietse.pgp

Postfix Basic Configuration http://www.postfix.org/BASIC_CONFIGURATION_README.html

Postfix Configuration Parameters http://www.postfix.org/postconf.5.html

master - Postfix master process configuration file format http://www.postfix.org/master.5.html

Changing the Postfix maximum email size https://www.electrictoolbox.com/postfix-email-size-limit/

Increasing Attachment Size in Posfix https://easyengine.io/tutorials/mail/postfix-attachment-size/

hardening

RFC2 Realtime List http://rfc-clueless.org/

Hardening Postfix For ISPConfig 3 https://www.howtoforge.com/hardening-postfix-for-ispconfig-3

How To Fight Spam Using Your Postfix Configuration https://www.howtoforge.com/virtual_postfix_antispam

Postfix SMTP relay and access control http://www.postfix.org/SMTPD_ACCESS_README.html

access - Postfix SMTP server access table http://www.postfix.org/access.5.html

DNSRBL

https://mxtoolbox.com/

https://web.archive.org/web/20140213185822/http://spamlinks.net/filter-dnsbl-dead.htm

https://www.spamhaus.org/faq/section/DNSBL%20Usage

https://www.dnsbl.com/2008/10/shutting-down-blacklists.html

Welcome to DNSBL.info https://www.dnsbl.info/

dnsbl resource https://www.dnsbl.com/

Which DNSBLs work well? https://www.dnsbl.com/2007/03/how-well-do-various-blacklists-work.html

What are spamtraps? https://www.spamresource.com/2007/02/what-are-spamtraps.html

Mail Spam Blacklists https://linuxreviews.org/Mail_Spam_Blacklists

w3bservice/Current Effective RBL Setup for Postfix 2017 https://gist.github.com/w3bservice/16f500e6c745aa6f3e6542ddc239c3c0

Postfix configure anti spam with blacklist https://www.cyberciti.biz/tips/postfix-spam-filtering-with-blacklists-howto.html

Blacklist & Whitelist with Postfix https://linuxlasse.net/linux/howtos/Blacklist_and_Whitelist_with_Postfix

Mimecast SMTP Error Codes https://community.mimecast.com/docs/DOC-1369

Prevent spam in Postfix https://support.rackspace.com/how-to/prevent-spam-in-postfix/

How-To: Fight SPAM with Postfix RBL https://www.debuntu.org/how-to-fight-spam-with-postfix-rbl/

https://www.linuxmagic.com/power_of_ip_reputation https://www.linuxmagic.com/products/bms/ https://www.linuxmagic.com/products/bms/blacklist_info https://www.linuxmagic.com/products/bms/mail_servers http://linuxmagic.ca/products/bms/install http://www.linuxmagic.ca/products/bms/whitelists

https://www.linuxmagic.com/products/bms/lookup https://www.spamrats.com/about.php https://www.mipspace.com/

alternatives

atech/postal https://github.com/atech/postal/wiki

Slackware Current - Sendmail - Moving forward https://www.linuxquestions.org/questions/slackware-14/slackware-current-sendmail-moving-forward-4175669439/

spf

Postfix SMTP Access Policy Delegation http://www.postfix.org/SMTPD_POLICY_README.html


HOME | GUIDES | BENCHMARKS | html