SETTING UP AND HARDENING POSTFIX

INSTALL

see INSTALLING POSTFIX

SYSTEM-WIDE SETUP

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

vipw

root@xc

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

# Basic system aliases -- these MUST be present
MAILER-DAEMON:  postmaster
postmaster:     root

# General redirections for pseudo accounts
bin:            root
daemon:         root
named:          root
nobody:         root
uucp:           root
www:            root
ftp-bugs:       root
postfix:        root

# Put your local aliases here.
root:           REAL-USER
SOMEUSER:   root
ALTUSER:    root

support:        root
contact:        root
info:           root
sales:      root
xen:        root

# Well-known aliases
manager:        root
dumper:         root
operator:       root
abuse:          postmaster

# trap decode to catch security attacks
decode:         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 # differs
diff -bu master.cf.proto master.cf # identical

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

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

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 v3.5.7 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,

SUPPORTING FILES

NETWORK

vi /etc/postfix/access.client

.compute.amazonaws.com      REJECT too much SPAM from compute.amazonaws.com
compute.amazonaws.com       REJECT too much SPAM from compute.amazonaws.com

.smtpout.orange.fr              OK
smtpout.orange.fr               OK

.g7.fr                          OK
g7.fr                           OK

postmap /etc/postfix/access.client

EHLO

vi /etc/postfix/access.helo.regexp

/^localhost$/       550 you are not me
/^xc$/          550 you are not me
/^xc\.nethence\.com$/   550 you are not me
/^nethence\.com$/   550 you are not me

MAIL FROM

vi /etc/postfix/access.sender

online.net              OK
ovh.com                 OK

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

SANE DEFAULTS

postfix versions and offered defaults vary across systems

less /etc/postfix/main.cf

rhel & slackware

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

slackware

here’s what differs on slackware vs. netbsd’s built-in postfix

smtputf8_enable=no
inet_protocols = all

enable SMTPUTF8 otherwise you would get

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

debian & ubuntu

need to fix those defaults

smtpd_banner = $myhostname ESMTP
compatibility_level = 3.5

(remove all smtp*tls smtpd*tls relayhost)
(displace smtpd_relay_restrictions myhostname mynetworks)

A GOOD START

eventhough we have 3.5, we want the new detauls compatibility_level namely 3.6

note mailbox_size_limit for happy procmail

smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 3.6
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

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 = xc.nethence.com
myorigin = nethence.com
mydomain = nethence.com
mydestination = localhost
    xc.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 [::1]/128 172.17.0.0/16
    FRIENDLY-CIDR

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

CASUAL

nothing fancy so far, while disabling SASL on port 25

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

# unused when mbox or procmail
#home_mailbox = Maildir/

strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes
enable_long_queue_ids = yes
smtpd_sasl_auth_enable = no

NETWORK

# slow down inbound on errors
# default is 10
smtpd_soft_error_limit = 5

# reduce inbound errors
# default is 20
smtpd_hard_error_limit = 10

# bounce faster when messages get stuck
# graylisting should be fine within 5 hours delay
# default is 5d
bounce_queue_lifetime = 5h
maximal_queue_lifetime = 6h

smtpd_client_restrictions = permit_mynetworks, reject_unauth_pipelining,
    reject_unknown_client_hostname,
    check_client_access hash:/etc/postfix/access.client,
    reject_rbl_client bl.spamcop.net,
    reject_rbl_client cbl.abuseat.org,
    reject_rbl_client psbl.surriel.com,
    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 hh.ru
#        reject_rbl_client truncate.gbudb.net,

# 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

DKIM

see dkim

READY TO GO

this won’t harm – although everything should be fine already

postfix set-permissions
postfix upgrade-configuration

debian/ubuntu

systemctl restart opendkim
systemctl status opendkim

systemctl restart postfix
systemctl status postfix

slackware

start and enable

chmod +x /etc/rc.d/rc.postfix
/etc/rc.d/rc.postfix restart

from source

start and enable

vi /etc/rc.local

#self verbose
/usr/local/sbin/postfix start

status

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

logs

vi logmail

tail -F /var/log/maillog /var/log/secure

chmod +x logmail

SASL

see POSTFIX AND SASL

OPERATIONS & ACCEPTANCE

always check the configuration syntax before restart

postfix check && echo ok

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.

log-aware-host-based-ips

eventually enable fail2ban or sshguard as an attempt to protect yourself from bot nets.

however a parser going through logs is less than ideal.

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

vdukhovni / postfix (unofficial mirror) https://github.com/vdukhovni/postfix

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

acls

http://www.postfix.org/postconf.5.html#smtpd_client_restrictions

http://www.postfix.org/access.5.html

http://ftp.uma.es/mirror/postfix/doc/SMTPD_ACCESS_README.html

http://www.postfix.org/ADDRESS_VERIFICATION_README.html

troubles

POSTFIX LOGGING HOWTO http://rob0.nodns4.us/postfix-logging

dns rbl

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 | LECTURES | LAB | SMTP HEALTH | HTML5
Copyright © 2022 Pierre-Philipp Braun