How to Install and Configure Postfix Mail Server on RHEL 7

Postfix is a high-performance, security-focused Mail Transfer Agent (MTA) that is installed by default on many RHEL 7 systems. It handles the sending, receiving, and routing of email using the SMTP protocol. Whether you are setting up a server to send application alerts, relay mail through a smart host, or serve as a full inbound mail server for a domain, Postfix is the correct tool for the job on RHEL 7. This guide covers a complete Postfix installation and configuration, including the primary main.cf configuration file, hash table generation with postmap, service management with systemctl, firewall configuration, email testing with the mailx command, log analysis, and alias management.

Prerequisites

  • RHEL 7 system with root or sudo privileges.
  • A fully qualified domain name (FQDN) for the server, resolvable in forward and reverse DNS. This guide uses mail.example.com with IP 192.168.1.22.
  • Port 25 (SMTP) open and not blocked by an upstream firewall or ISP.
  • A valid MX DNS record pointing to your server’s hostname (for receiving mail).
  • No other MTA running on the system (check with systemctl status sendmail exim4).

Step 1: Install Postfix and mailx

Postfix may already be installed. Install or confirm it along with mailx, which provides the mail command for testing.

yum install -y postfix mailx

If sendmail is installed, switch the system MTA to Postfix using the alternatives system:

alternatives --set mta /usr/sbin/sendmail.postfix

Step 2: Configure /etc/postfix/main.cf

The main Postfix configuration file is /etc/postfix/main.cf. Open it and adjust the following parameters. The file already contains commented examples for most directives.

vim /etc/postfix/main.cf

Set the server’s identity parameters:

# The hostname of this mail system
myhostname = mail.example.com

# The internet domain name of this mail system
mydomain = example.com

# The domain that is appended to locally-posted mail
myorigin = $mydomain

Configure which network interfaces Postfix listens on. For a public mail server, set this to all:

# Listen on all interfaces
inet_interfaces = all

# Use IPv4 only (adjust to 'all' if IPv6 is needed)
inet_protocols = ipv4

Define which domains this server accepts mail for. Local delivery is performed for mail addressed to these domains:

mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

Set a trusted relay network (machines that may relay through this server without authentication):

mynetworks = 127.0.0.0/8, 192.168.1.0/24

If you are relaying outbound mail through an upstream smart host (such as your ISP’s SMTP server or a service like SendGrid), configure relayhost:

# Smart host relay (leave empty to send directly)
relayhost = [smtp.yourprovider.com]:587

If relayhost is empty, Postfix will attempt direct MX delivery to the recipient’s mail server. For a standalone lab or internal server, leave it empty.

Set the mailbox location for local delivery:

home_mailbox = Maildir/

Using Maildir/ format stores each message as a separate file, which integrates cleanly with Dovecot IMAP. The alternative is mbox format (leave this directive commented).

Step 3: Configure SMTP Banner and Size Limits

# SMTP greeting banner
smtpd_banner = $myhostname ESMTP

# Maximum message size: 50 MB
message_size_limit = 52428800

# Maximum mailbox size: 1 GB
mailbox_size_limit = 1073741824

The banner should not reveal the software version for security reasons — the default $mail_name $mail_version reveals Postfix and its version; using just $myhostname ESMTP is safer.

Step 4: Generate Hash Tables with postmap

Postfix uses Berkeley DB hash tables for lookup tables such as access restrictions and canonical mappings. After editing any table file, regenerate the .db index:

# Generate the access table (if used)
postmap /etc/postfix/access

# Generate the canonical table (if used)
postmap /etc/postfix/canonical

# Verify main.cf syntax
postfix check

The postfix check command validates the configuration and reports any errors or warnings without affecting the running service.

Step 5: Configure /etc/aliases and Rebuild the Alias Database

The aliases file maps local recipient names to real accounts or email addresses. This is essential for routing mail to root, postmaster, and other system accounts.

vim /etc/aliases
# Redirect root mail to a real user
root:           sysadmin

# Standard aliases
postmaster:     root
abuse:          root
webmaster:      root
mailer-daemon:  root

# Forward to an external address
sysadmin:       [email protected]

After editing the aliases file, rebuild the binary database:

newaliases

Postfix reads /etc/aliases.db at runtime; the newaliases command regenerates it from the text file. Forgetting this step means alias changes will have no effect.

Step 6: Start and Enable Postfix

systemctl start postfix
systemctl enable postfix
systemctl status postfix

Confirm the service shows active (running). Postfix starts multiple worker processes (master, qmgr, pickup, etc.) that should all appear in the status output.

Step 7: Open the Firewall for SMTP

firewall-cmd --permanent --add-service=smtp
firewall-cmd --reload
firewall-cmd --list-services

If you plan to support SMTP submission (port 587) for authenticated clients, add that port as well:

firewall-cmd --permanent --add-port=587/tcp
firewall-cmd --reload

Step 8: Test with the mail Command

Send a test email to a local user or an external address using mailx:

# Send a test message
echo "This is a test email from Postfix on RHEL 7" | mail -s "Postfix Test" root

# Send to an external address
echo "Testing Postfix" | mail -s "Test" [email protected]

Check the local mailbox to confirm delivery:

# If using Maildir format
ls ~/Maildir/new/

# If using mbox format
mail

Step 9: Monitor the Mail Log

All Postfix activity is logged to /var/log/maillog. This is the first place to look when troubleshooting delivery failures.

# Watch the log in real time
tail -f /var/log/maillog

# Search for a specific message ID
grep "message-id" /var/log/maillog

# Find delivery status for a specific recipient
grep "to=<[email protected]>" /var/log/maillog

A successful local delivery produces log lines including status=sent (delivered to maildir). A relay to an external server shows status=sent (250 OK) from the upstream SMTP server. Deferred messages show status=deferred with the reason, giving you clear guidance on what needs to be fixed.

Step 10: Check the Mail Queue

# View queued messages
mailq

# Attempt immediate delivery of all queued mail
postqueue -f

# Delete all queued messages (use with caution)
postsuper -d ALL

A properly configured Postfix mail server on RHEL 7 provides a reliable, standards-compliant foundation for both internal notification mail and internet-facing email delivery. The combination of main.cf for policy, /etc/aliases for local routing, postmap-generated hash tables for lookups, and real-time log monitoring in /var/log/maillog gives administrators complete visibility and control. For a production deployment, complement this base configuration with TLS encryption using a certificate from Let’s Encrypt, SMTP authentication via SASL, and integration with a Dovecot IMAP server to give users access to their mailboxes.