Configure Postfix Mail Server CentOS/RedHat

Postfix TLS block in main.cf: smtpd_use_tls, smtpd_tls_security_level = may, cert and key files, loglevel and session cache

This guide sets up Postfix on CentOS/Red Hat Enterprise Linux as an internal mailhub (smarthost) and outbound mail gateway: your servers and mail clients hand their mail to one Postfix box, and that box delivers it to the Internet. It was written for CentOS 6 and is republished here from the original blog with its screenshots; notes for current AlmaLinux, Rocky Linux and RHEL releases are at the end.

Postfix is a very secure, flexible mail server for relaying your email as an internal mailhub, or external mail gateway.

The Topology we are setting up is as follows:

Mail Clients –> Postfix Mailhub/Gateway –> Internet

Install and enable Postfix

Let’s get started, login, and su to root

Root shell prompt on the mailserver host

the very first thing we want to do is make a backup of the postfix configuration

cp /etc/postfix/main.cf /etc/postfix/main.cf.bk
cp /etc/postfix/main.cf /etc/postfix/main.cf.bk to back up the Postfix configuration

now let’s install the prerequisite packages necessary for troubleshooting (telnet for testing SMTP by hand, mailx for sending test messages). Postfix itself is installed by default on CentOS 6; if it is missing, add postfix to the same command.

yum -y install telnet mailx
yum -y install telnet mailx

we now need to verify the service will run after reboot, as well as starting/restarting it now.

chkconfig postfix on
service postfix restart
chkconfig postfix on, then service postfix restart: Shutting down and Starting postfix OK

Customize main.cf for your network

let’s begin customizing postfix for our network:

vi /etc/postfix/main.cf
vi /etc/postfix/main.cf

the first thing we want to do is set postfix to use only ipv4; if you turn off ipv6 at some point in the future, it would cause the service to fail.

change lines 119 and 120 to look as follows (line numbers are from the stock CentOS 6 main.cf; search for the parameter name if yours differ):

#inet_protocols = all
inet_protocols = ipv4
main.cf lines 118-120: #inet_protocols = all commented out and inet_protocols = ipv4

customize lines 116/117 to your environment. This is the interface postfix will be listening on; by default it only listens locally, so you need to open it up to the IP of the server.

#inet_interfaces = localhost
inet_interfaces = localhost, 192.168.1.50
main.cf lines 116-117: inet_interfaces = localhost, 192.168.1.50

this next step is critical, we need to tell postfix what networks to allow traffic from (mynetworks). Only list networks you trust; anything listed here can relay through the server, so never add 0.0.0.0/0 or you will run an open relay.

#mynetworks = hash:/etc/postfix/network_table
mynetworks = 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24
main.cf line 271: mynetworks = 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24

in this case we are going to accept mail from the following networks: 192.168.1.0/24 – 192.168.3.0/24

next you want to customize where the email is coming from by specifying the external hostname of your mail server.

myhostname = mailserver.yourdomain.local
main.cf line 77: myhostname = mailserver.yourdomain.local

now we need to set the ‘domain’ for outbound email addresses; you may need to set it .local or .com, depending on your environment.

mydomain = yourdomain.local
main.cf line 85: mydomain = yourdomain.local

restart postfix to ensure all your settings worked

service postfix restart
service postfix restart after editing main.cf, both steps OK

Setup TLS Secure SMTP

since we live in the age where we can no longer run insecure protocols, and everything needs to be encrypted, this is a necessary step.

first we need to create a directory to store our ssl certificates

mkdir /etc/postfix/ssl
mkdir /etc/postfix/ssl

generate a self-signed cert (you may want to use an official cert here)

openssl req -x509 -nodes -days 36500 -newkey rsa:4096 -keyout /etc/postfix/ssl/postfix.key -out /etc/postfix/ssl/postfix.crt
openssl req -x509 -nodes -days 36500 -newkey rsa:4096 writing /etc/postfix/ssl/postfix.key and postfix.crt

fill out the cert info as applies to you. The Common Name should be the host name clients use to reach the server:

OpenSSL certificate prompts answered: US, Colorado, Denver, Your_Company, IT, CN mailserver.yourdomain.local

The private key should only be readable by root:

chmod 600 /etc/postfix/ssl/postfix.key

now we need to tell the postfix instance about the ssl settings/certificate, etc.

vi /etc/postfix/main.cf
vi /etc/postfix/main.cf to add the TLS settings

add the following to the postfix config at the very bottom:

# -- TLS Settings -- #
# With this, the Postfix SMTP server announces STARTTLS support to remote SMTP
# clients, but does not require that clients use TLS encryption.
smtpd_use_tls = yes
smtpd_tls_security_level = may

# Configures the server certificate file and key file as well as the CA's
# intermediate certificate file.
smtpd_tls_cert_file = /etc/postfix/ssl/postfix.crt
smtpd_tls_key_file = /etc/postfix/ssl/postfix.key

# Enable logging of summary message for TLS handshake and to include
# information about the protocol and cipher used as well as the client and
# issuer CommonName
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

# Postfix SMTP server and the remote SMTP client negotiate a session, which
# takes some computer time and network bandwidth. SSL protocol versions other
# than SSLv2 support resumption of cached sessions.
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache

# Cached Postfix SMTP server session information expires after a certain
# amount of time. RFC2246 recommends a maximum of 24 hours.
smtpd_tls_session_cache_timeout = 10800s
Postfix TLS block in main.cf: smtpd_use_tls, smtpd_tls_security_level = may, cert and key files, loglevel and session cache

once this is completed, since there are a few config changes, we should immediately restart postfix to make sure the settings worked.

service postfix restart
service postfix restart after adding the TLS settings, both OK

Set how long mail stays in the queue

From here there is one final thing that needs to be considered: how long do you want mail to spool on the server? The default is 5 days; is that too much? Too little?

you can override these settings in the postfix config. A plain number is read as days:

#Increase Mail Spooling from 5(default) to 7 days
maximal_queue_lifetime=7
main.cf: maximal_queue_lifetime=7 to increase mail spooling from 5 (default) to 7 days

as always when there is any config change, you want to restart the service to be sure the settings worked.

service postfix restart
service postfix restart after setting maximal_queue_lifetime

Test the mailhub

ok, now it’s all setup and working, we just need to test it. Make sure TCP port 25 is open in the server’s firewall (iptables on CentOS 6) for the networks you listed in mynetworks.

From a remote host, telnet to the server on port 25, and test if it works:

telnet mailserver.yourdomain.local 25
telnet mailserver.yourdomain.local 25 from a remote host

you should see the following:

telnet connects: 220 mailserver.yourdomain.local ESMTP Postfix

you can perform an entire test as follows (end the message with a line containing only a period):

MAIL from:person@yourdomain.com
RCPT to:person@yourdomain.com
DATA
From:person@yourdomain.com
Subject: Mail Test

Hello, I'm writing to inform you that you are cool

.
SMTP test over telnet: MAIL from, RCPT to, DATA, Subject Mail Test, 250 2.0.0 Ok: queued as ED375DBD

you can check the status of your mail queue using the ‘mailq’ command.

mailq
mailq lists queue ID ED375DBD for person@yourdomain.com, 1 request

obviously the test email we sent is non-deliverable. We can check why in the maillog

tail /var/log/maillog
tail /var/log/maillog

here’s the status of the last email:

maillog: ED375DBD status=deferred, connect to mx00.1and1.com port 25 connection timed out
  • status=sent means it sent
  • status=rejected means that your server/ip is not allowed to send to that server.
  • status=deferred in this case timed out, because the firewall is blocking outbound email from that server.

for more info, try man postfix; it contains lots of good info on doing a mail flush, queue delete, etc. (for example postqueue -f to flush the queue and postsuper -d ALL to delete every queued message).

To setup CentOS clients to use the new mail server, see Configure Postfix RelayHost CentOS/RedHat.

On AlmaLinux, Rocky Linux and RHEL 8, 9 and 10

The same main.cf parameters still apply. The commands around them have changed:

  • Install with dnf install postfix telnet mailx on RHEL 8, or dnf install postfix telnet s-nail on RHEL 9 and later (s-nail provides the mailx command), and enable it with systemctl enable --now postfix; use systemctl restart postfix instead of service postfix restart.
  • Rather than editing by line number, set values with postconf -e, for example postconf -e "inet_interfaces = localhost, 192.168.1.50", and check your work with postconf -n and postfix check.
  • smtpd_use_tls = yes is the old (pre-2.3) way to turn on opportunistic TLS and has been superseded by smtpd_tls_security_level = may, which on its own does the same job, so you can leave smtpd_use_tls out. Run postconf -m to see which lookup table types your build supports and switch the session cache from btree: to lmdb: if btree is not listed.
  • Open the port with firewall-cmd --permanent --add-service=smtp and firewall-cmd --reload.
  • Logs go to the journal as well as /var/log/maillog when rsyslog is installed: journalctl -u postfix. To test STARTTLS from a client, use openssl s_client -starttls smtp -connect mailserver.yourdomain.local:25.

That’s it, now you have a basic idea how to setup a postfix mailhub/gateway.

Hosted Linux Servers at www.zwiegnet.com/go

Related guides: Configure Postfix and Dovecot on RHEL, AlmaLinux, Rocky and Oracle Linux | Postfix and Dovecot Cheat Sheet

Leave a Reply

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