Postfix Hardening Guide for Security and Privacy

Postfix Security and Privacy

Postfix is one of the most used components on a server that needs to receive or send emails. With all its options available, it is easy to have a weak configuration. This security guide looks into Postfix hardening, to increase the defenses against spam, abuse, and leaking sensitive data. Time to start!

Guide overview

  • Why Postfix hardening
  • Preparation
    • Test the existing Postfix configuration
    • Backup your Postfix configuration
    • Find your Postfix version
  • Hardening steps
    • Basic hardening
      • Disable VRFY
      • Network interfaces
    • Prevent unwanted email relaying
      • Networks
      • Domains
    • Incoming email configuration
      • Enable HELO
    • Outgoing email configuration
      • Configure authenticated relaying with a smarthost

Why Postfix hardening?

Every service that is connected to the internet is sooner or later to be abused by automated scripts. For example, an incorrectly Postfix might send messages for everyone, instead of just your network systems. This type of configuration is called an “open relay” and quickly will get your system ending up on multiple blacklists. If it is just a test system, then you are lucky. If your customers are depending on it, then you have something to explain.

Another reason for Postfix hardening is the increasing need for privacy. Most of the legacy protocols, SMTP for email delivery included, did not have a place for security or privacy on the priority list. These protocols may share data with other systems without any form of protection. This may result in unauthorized people snooping on data, from your local IT administrator to possibly the CIA or NSA.

Preparation

Time to get technical and get the configuration tested. Many hardening guides and blogs forget an important part of system hardening: the preparation. So let’s start with that, before making any changes.

Test the existing Postfix configuration

Your current configuration may have errors without you even knowing. So let’s first test for that.

postconf 1> /dev/null

The postconf command can be used to display the Postfix configuration, or make changes. In this case, we redirect all normal output (stdout) to the digital trash bin (/dev/null). If your configuration has any errors or warnings, they will show up. Guess what, one of our systems had actually a warning. This was discovered when we implemented a related test in our own auditing tool Lynis.

The postconf command showing warnings in existing Postfix configuration

If you get any output, then it is wise to solve these first and restart your Postfix service to see if the error or warning is gone.

Backup your Postfix configuration

It goes without saying, but too often this step is skipped. If you do system hardening, make a backup first. The first backup is to create a copy of the /etc/postfix directory.

tar czf /root/postfix-$(date "+%F").tar.gz /etc/postfix

For later troubleshooting or comparing configurations, it is also wise to use postconf to store a copy. This one we can easily use together with the diff command.

postconf > /root/postconf-$(date "+%F")

Find your Postfix version

postconf mail_version | awk -F" = " '{print $2}'

An alternative is to use your package manager to find the version of the ‘postfix’ package. For Debian and Ubuntu users, this can be achieved with the dpkg command.

dpkg -l postfix

Hardening steps

With all the preparations taken, it is time to start with the Postfix hardening steps. Each of the steps will change a particular area within Postfix. Some are to prevent information disclosure, others to enhance stability or increase the privacy of the content being sent.

Basic hardening

Disable VRFY (verify)

The VRFY command is short for ‘verify’. It can be used to see if an email address is valid on the mail server. While this is great for troubleshooting, it also allows others to make educated guesses if an account exists and deliver possibly spam. The VRFY command is not normally not needed for delivery between two mail servers

postconf -e disable_vrfy_command=yes

Note: after changing each item, restart or reload Postfix and monitor Postfix for errors. One way to do this is by keeping a watch on the log file.

Network interfaces (inet_interfaces)

The first setting to check is the interfaces Postfix is listening to. This setting is called inet_interfaces and by default configured with all. If you just want to relay messages to other systems, like sending outgoing emails, then there is no needed to listen on all network interfaces. Configure Postfix to listen only on the local interface. This can be achieved by setting inet_interface to loopback-only.

postconf -e inet_interfaces=loopback-only

Test your configuration after restarting Postfix. In this case, we can use the output from netstat or ss.

Output of ss command to display network ports that Postfix is listening to

Important notes:

  • Some changes need a restart of Postfix. A reload is not enough when changing the inet_interfaces setting.
  • If you are configuring a system that relays for other systems, then most likely you want to listen on all network interfaces, or just on localhost and the primary network interface where requests come from.

Prevent unwanted email relaying

The first rule when putting a mail server up is to avoid being an open relay system. This is a system that accepts email from all systems and forwards them. Spammers will quickly find your host and abuse it to send out their messages.

Networks

Relaying is configured with several parameters. The first one is the mynetworks setting, which typically only includes the network addresses of the local network interface (lo).

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

If you want to extend this list, simply add network segments or individual systems. Specify the related network mask, which is /32 for a single IPv4 address, or /128 for IPv6.

Due to the spaces in this setting, add quotes when using the postconf command.

postconf -e mynetworks="127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"

Domains

The second layer to define what emails to accept. This is called relaying and one of the options is by looking at the destination domain. The related setting for this is relay_domains, which specifies for which domains to accept email in the first place.

 

Test Postfix relaying

You can test if your configuration is correctly set up by setting up a connection to the other system. Telnet to the other system, and run the following commands

  • helo yourdomain.com
  • mail from:<your.alias@yourdomain.com>
  • rcpt to:<your.personal.mailbox@gmail-or-hostmail.com>
  • data
  • Type a test line and press CTRL+D twice
  • quit

Replace the addresses and see if you can relay a message to an address outside your own domain. For example, you could use a Gmail or Hotmail address as the receiver.

If things are properly configured to avoid an open relay, you should be getting a relay access denied message.

Relay access denied (in reply to RCPT TO command)

 

Incoming email configuration

Configuration items starting with smtpd refer to the SMTP daemon. This is the daemon that deals with incoming requests.

Enable HELO

People usually greet each other by saying ‘hello’ or something similar. Mail servers do this with a HELO command, or EHLO, the extended version. Servers that are not using this are typically not properly configured, or simply sending spam.

postconf -e smtpd_helo_required=yes

 

Outgoing email configuration

Typically only a few machines will accept incoming email and all other servers need to send out emails. This might be a system notification from the daily cronjobs. Another typical example is a web application that needs to send emails for account activation or password resets.

Configure authenticated relaying with a smarthost

The first step is to define which system will accept the email. This system is the so-called smarthost, or relayhost in Postfix terms. Use the postconf command to set these settings from the command line, or edit main.cf directly.

relayhost = [hostname.example.org]:587

Use the brackets around the hostname or IP address, to prevent MX lookups. The port number can be changed, depending on the required configuration. Some providers use an alternative SMTP port.

Next step is to enable SASL authentication.

# Enable SASL authentication
smtp_sasl_auth_enable = yes
# Disallow any methods that do allow anonymous authentication
smtp_sasl_security_options = noanonymous
# Define the sasl_passwd file location
smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd

Now we will edit the /etc/postfix/sasl/sasl_passwd file.

[mail.example.org]:587 username:password

This file can be parsed by postmap to created an optimized version, which is used as the database for lookups.

postmap /etc/postfix/sasl/sasl_passwd

The last part is configuring encryption. To enable this, we have to configure this separately.

# Enable STARTTLS encryption
smtp_use_tls = yes
# Location of CA certificates
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

Now restart Postfix, and send a test email.

echo “test” | mail -s “test” me@example.org

Related and useful commands

  • postqueue -f (flush mail queue and retry delivering all emails)

 

Cryptography, encryption, and privacy

Enable TLS logging

To see the details from TLS, increase the level of Postfix logging. Set smtp_tls_loglevel (outgoing) or  smtpd_tls_loglevel (incoming) to the value one (1).

postconf -e smtp_tls_loglevel=1

Testing keys

With OpenSSL you can easily test your SMTP configuration and related ciphers. One of the areas to test is the strength of the initial connection handshake. This is typically done with the DiffieHellman (DH) algorithm, that exchanges the cryptographic keys.

echo | openssl s_client -starttls smtp -connect localhost:25 -cipher "EDH" 2>/dev/null | grep -i -e "Server .* key"

Note: you need at least version 1.02 of OpenSSL, otherwise not all details are displayed. Use openssl version to double check that you are on a recent version.

This command should give you two lines of output. The first line is the temporary key and should be at least 1024 bits when using DH, to prevent the Logjam attack.

Server Temp Key: DH, 2048 bits

The second line is the public key size. This will typically be a 2048 bit key (or higher) on modern systems.

Server public key is 2048 bit

 

More to be coming…

One more thing...

Keep learning

So you are interested in Linux security? Join the Linux Security Expert training program, a practical and lab-based training ground. For those who want to become (or stay) a Linux security expert.

See training package




Lynis Enterprise screenshot to help with system hardeningSecurity scanning with Lynis and Lynis Enterprise

Run automated security scans and increase your defenses. Lynis is an open source security tool to perform in-depth audits. It helps with system hardening, vulnerability discovery, and compliance.


Download

Leave a Reply

Your email address will not be published. Required fields are marked *