Hardening Postfix: Restrict Mail Transport

This article describes a procedure to reduce unwanted mails and mail system abuse. It creates rules that will prevent your server from accepting emails from your own domains, sent to them from external servers.

Description

E-mail from outside your environment:

  • are only allowed to be forwarded via port 25 (smtp) if the recipient is inside your environment (this is already default - no open relaying).
  • are blocked1, if both mail addresses - recipient as well as sender - are inside your environment and port 25 is used. These e-mails should be delivered via port 465 (ssl smtp) or port 587 (tls smtp).
    1 in the current configuration instead of blocking these e-mails they are only logged to ‘/var/log/mail.log’. You should check if the configuration also fits your needs and environment before rejecting e-mails!

E-mails from inside your environment:

  • are excepted via port 25 from all DC’s (if needed, from other systems too) except they are send from an outside mail address. Not configured systems (like all Clients) are not allowed to use this port - they should use port 465 (ssl smtp) or port 587 (tls smtp).

Instructions

  1. backup and reset the current smtp restrictions
root@ucs:~# ucr search --brief mail/postfix/smtpd/restrictions/recipient/ \
>smtpd_restrictions.backup

root@ucs:~# ucr unset $(ucr --keys-only search mail/postfix/smtpd/restrictions/recipient | egrep '\w$')
  1. write new smtp restrictions
root@ucs:~#  if [ -n "$(ucr get mail/dovecot)" ]; then \
    ucr set mail/postfix/smtpd/restrictions/recipient/80="check_policy_service inet:127.0.0.1:12340"; \
  fi
  1. create ‘/etc/postfix/check_custom_sender_access’ (read mail domains and add config)
root@ucs:~# touch /etc/postfix/check_custom_sender_access
root@ucs:~# for md in $(ucr get mail/hosteddomains); do \
  echo "$md WARN *** Invalid Inbound Sender ***" >>/etc/postfix/check_custom_sender_access; \
  echo ".$md WARN *** Invalid Inbound Sender ***" >>/etc/postfix/check_custom_sender_access; \
  done
root@ucs:~# postmap /etc/postfix/check_custom_sender_access

Here, both echo lines contains the mail domain, a command and the custom message. You might change the behavior to '… REJECT 5.7.1 Delivery not authorized, message refused’2 to really block these e-mails:

root@ucs:~# touch /etc/postfix/check_custom_sender_access
root@ucs:~# for md in $(ucr get mail/hosteddomains); do \
  echo "$md REJECT 5.7.1 Delivery not authorized, message refused" >>/etc/postfix/check_custom_sender_access; \
  echo ".$md REJECT 5.7.1 Delivery not authorized, message refused" >>/etc/postfix/check_custom_sender_access; \
  done
root@ucs:~# postmap /etc/postfix/check_custom_sender_access

2 See also https://tools.ietf.org/html/rfc3463#page-12.

  1. allow all DC’s to relay internal mails. Take care to leave the local network (127.0.0.1/8) untouched and manually add all listed ip address afterwards, seperated by comma.
root@ucs:~# univention-ldapsearch -LLL "(objectClass=univentionDomainController)" aRecord
ucr get mail/postfix/mynetworks
# mail/postfix/mynetworks: 127.0.0.0/8,...
  1. backup master.cf and add new options
root@ucs:~# cp /etc/postfix/master.cf /etc/postfix/master.cf.backup

root@ucs:~# ucr set mail/postfix/mastercf/options/smtps/syslog_name="postfix/smtps" \
  mail/postfix/mastercf/options/smtps/smtpd_sender_login_maps="ldap:/etc/postfix/ldap.saslusermapping" \
  mail/postfix/mastercf/options/smtps/smtpd_tls_wrappermode="yes" \
  mail/postfix/mastercf/options/smtps/smtpd_sasl_auth_enable="yes"

ucr set mail/postfix/mastercf/options/submission/syslog_name="postfix/submission" \
  mail/postfix/mastercf/options/submission/smtpd_sender_login_maps="ldap:/etc/postfix/ldap.saslusermapping" \
  mail/postfix/mastercf/options/submission/smtpd_sasl_auth_enable="yes" \
  mail/postfix/mastercf/options/submission/smtpd_enforce_tls="yes"

ucr set mail/postfix/submission/restrictions/recipient/10="reject_sender_login_mismatch"\
  mail/postfix/submission/restrictions/recipient/20="reject_unknown_recipient_domain"\
  mail/postfix/submission/restrictions/recipient/30="permit_sasl_authenticated"\
  mail/postfix/submission/restrictions/recipient/99="reject"

ucr set mail/postfix/mastercf/options/smtps/smtpd_recipient_restrictions="\$submission_recipient_restrictions" \
             mail/postfix/mastercf/options/submission/smtpd_recipient_restrictions="\$submission_recipient_restrictions" \

root@ucs:~# ucr commit /etc/postfix/master.cf
  1. finally reload the postfix configuration
root@ucs:~# postfix reload

in case some settings are not properly written to the postfix configuration it mostly helps to perform a full commit:

root@ucs:~# ucr commit /etc/postfix/*

Due to the fact that every environment is unique - in the one way or the other - and a mail server never should drop e-mails - which also has juristical reasons - you first need to check if everything works fine in your environment before rejecting e-mails. There are also other measures like Amavis, Antispam, SPF, DKIM, Mailcluster,… by which you can realise further requirements.

Testing

you might use swaks to test the configuration, you can install swaks via the unmaintained repository:

root@ucs:~# ucr set repository/online/unmaintained=yes
root@ucs:~# apt-get clean && apt-get -qq update
root@ucs:~# apt-get install swaks

to send a test e-mail via swaks you might use the following syntax:

#SYNTAX: swaks --server <MAIL SERVER IP> --port 25 --to <MAIL ADDRESS> --from <MAIL ADDRESS> --h-Subject "<SUBJECT LINE>"

root@ucs:~# swaks --server 192.168.1.3 --port 25 --to sales@company.local --from customer@important.value --h-Subject "My FAKE Order"

root@ucs:~# swaks --server 192.168.1.3 --port 25 --to employee@company.my --from boss@company.my --h-Subject "raise of salary"

Also be sure to test all use cases from a computer outside your network, at least its IP address must not be listed in/covered by the UCR variable mail/postfix/mynetworks.

1 Like
Mastodon