LFCE 63 ๐ง Mail Server โ Postfix Basics
Postfix is the default Mail Transfer Agent (MTA) on most Linux distributions. Its job is to move mail between servers using SMTP, accepting messages from local users or remote clients and delivering them to the correct destinationโeither a local mailbox or another mail server. The previous chapters covered web servers and load balancers; this chapter covers the mail server that handles the SMTP protocol, the configuration file that controls it, and the diagnostic tools that show whether mail is flowing or stuck.
Postfix was designed by Wietse Venema as a secure replacement for Sendmail. It uses a modular architecture: a master daemon launches small, unprivileged processes that each perform a specific task, limiting the damage a compromised process can cause . The configuration lives in /etc/postfix/, and the primary file is main.cf, which contains the global parameters . A working Postfix installation requires only a few parameters to be set correctly: the domain it serves, the hosts it accepts mail for, and the networks it relays for.
Key point: Postfix is an MTA, not a complete mail system. It handles SMTP transport and local delivery, but reading mail requires an MDA like Dovecot for IMAP/POP3. The mydestination parameter defines the domains Postfix accepts mail for locally. The mynetworks parameter defines the clients allowed to relay through it. Without these two settings, Postfix either rejects mail for its own domain or becomes an open relay.
Why Postfix requires careful configuration
The open-relay problem.
An MTA that relays mail for any client is an open relay, and spammers will find it within hours. The mynetworks parameter controls which clients are authorized to relay. By default, Postfix authorizes the IP subnets the machine is attached to . If the server has a public interface and mynetworks includes it, the server becomes an open relay. The parameter must be set to the local network only, or to 127.0.0.0/8 for a server that only accepts mail from local processes.
The local-delivery problem.
Postfix accepts mail for the domains listed in mydestination. If the server’s hostname is mail.example.com and mydestination contains only $myhostname, then mail addressed to user@example.com is rejected because example.com is not in the list. A domain-wide mail server must list $mydomain in mydestination . The distinction between $myhostname (the server’s name) and $mydomain (the parent domain) is the most common source of “Relay access denied” or “User unknown” errors.
The alias problem.
The postmaster address must exist and must point to a human. The alias_maps parameter points to the alias file, typically /etc/aliases or /etc/postfix/aliases. After editing the file, the postalias command must be run to rebuild the lookup table . Without it, the new aliases are not active, and mail to the alias address bounces.
a. The main.cf parameters
The main.cf file contains the global configuration. The parameters that must be set for a basic server are myhostname, mydomain, myorigin, mydestination, mynetworks, and inet_interfaces.
# /etc/postfix/main.cf
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
mynetworks = 127.0.0.0/8, 192.168.1.0/24
inet_interfaces = all
The myhostname is the server’s fully qualified name. The mydomain is the parent domain. The myorigin is the domain that appears in mail sent from this machine; setting it to $mydomain makes outgoing mail appear to come from example.com rather than mail.example.com . The mydestination lists the domains that Postfix delivers locally. The mynetworks lists the clients allowed to relay. The inet_interfaces controls which interfaces the SMTP server listens on.
After editing main.cf, the service must be reloaded.
sudo postfix reload
# Or: sudo systemctl reload postfix
The postfix reload command re-reads the configuration without dropping the connections that are in progress . A full restart is not necessary for parameter changes.
b. Aliases and local delivery
The alias file maps one address to another or to a list of recipients. The postmaster alias is required, and the root alias is commonly set to forward to a real user.
# /etc/aliases (or /etc/postfix/aliases)
postmaster: root
root: admin@example.com
sysadmin: alice, bob
The postmaster: root line forwards mail for postmaster to the root account. The root: admin@example.com line forwards root’s mail to an external address. The sysadmin: alice, bob line delivers to both local users . After editing, the postalias command rebuilds the table.
sudo postalias /etc/aliases
# Or: sudo newaliases
The postalias command is the Postfix-specific tool. The newaliases command is the Sendmail-compatible alias . Both produce the same result: a database file that Postfix reads when delivering mail.
c. The mail queue and diagnostics
Postfix places every message in a queue before delivery. The queue has five states: incoming, active, deferred, hold, and corrupt . The mailq command shows the messages in the queue, and the postqueue command provides the same information with more options.
# Show the queue
mailq
# Or: postqueue -p
# Force a retry of all deferred messages
sudo postqueue -f
# Delete a specific message
sudo postsuper -d <QUEUE_ID>
# Put a message on hold
sudo postsuper -h <QUEUE_ID>
# Release a held message
sudo postsuper -H <QUEUE_ID>
The mailq output shows the queue ID, the size, the arrival time, the sender, and the recipient. A message that is deferred shows the reason in parentheses, such as “Connection timed out” or “Host not found” . The postqueue -f command flushes the deferred queue and retries every message immediately.
The log file is the primary diagnostic tool. On Debian and Ubuntu, the mail log is /var/log/mail.log; on RHEL and its derivatives, it is /var/log/maillog . The log shows the SMTP conversation, the delivery status, and the reason for any failure.
# Follow the mail log
sudo tail -f /var/log/mail.log # Debian
sudo tail -f /var/log/maillog # RHEL
# Find the log entries for a specific queue ID
grep <QUEUE_ID> /var/log/mail.log
The log entries include status=sent, status=deferred, or status=bounced, along with the recipient and the relay. A deferred message that repeatedly shows “Connection refused” indicates that the destination server is unreachable or the port is blocked.
Complete Example Session
# ============================================
# PART 1: INSTALL POSTFIX
# ============================================
# Debian / Ubuntu: the installer prompts for the mail configuration type
sudo apt install postfix
# Select "Internet Site" and enter the system mail name (e.g., example.com)
# RHEL / Rocky
sudo dnf install postfix
# ============================================
# PART 2: CONFIGURE main.cf
# ============================================
sudo tee -a /etc/postfix/main.cf > /dev/null <<'EOF'
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
mynetworks = 127.0.0.0/8, 192.168.1.0/24
inet_interfaces = all
EOF
# ============================================
# PART 3: CONFIGURE ALIASES
# ============================================
sudo tee -a /etc/aliases > /dev/null <<'EOF'
postmaster: root
root: admin@example.com
EOF
sudo postalias /etc/aliases
# ============================================
# PART 4: RELOAD AND CHECK THE SERVICE
# ============================================
sudo postfix reload
sudo systemctl status postfix
# Output: active (running)
# ============================================
# PART 5: CHECK THE LISTENING PORT
# ============================================
sudo ss -tlnp | grep :25
# Output: LISTEN 0 100 *:25 *:* users:(("master",pid=...))
# ============================================
# PART 6: SEND A TEST MESSAGE
# ============================================
echo "Test message body" | mail -s "Test subject" root
# ============================================
# PART 7: CHECK THE QUEUE
# ============================================
mailq
# The message should be delivered or queued
# ============================================
# PART 8: CHECK THE LOG
# ============================================
sudo tail -5 /var/log/mail.log # Debian
# Output shows the connection, the delivery, and status=sent
# ============================================
# PART 9: TEST SMTP MANUALLY
# ============================================
telnet localhost 25
# EHLO localhost
# MAIL FROM:<test@example.com>
# RCPT TO:<root@localhost>
# DATA
# Subject: Manual test
#
# Test body
# .
# QUIT
# ============================================
# PART 10: CHECK THE MAILBOX
# ============================================
sudo cat /var/mail/root
# The test messages are in the root mailbox
The ten parts demonstrate the Postfix basics: installation, main.cf configuration, alias setup, reload, port verification, test message, queue inspection, log inspection, manual SMTP conversation, and mailbox check. The critical verification is Part 8: the log shows the delivery status, and a status=sent confirms that Postfix accepted and delivered the message.
Quick Reference
main.cf Parameters
| Parameter | Purpose | Example |
|---|---|---|
myhostname | Server FQDN | mail.example.com |
mydomain | Parent domain | example.com |
myorigin | Domain in outbound mail | $mydomain |
mydestination | Domains delivered locally | $myhostname, $mydomain |
mynetworks | Clients allowed to relay | 127.0.0.0/8, 192.168.1.0/24 |
inet_interfaces | Listening interfaces | all or loopback-only |
Queue Commands
| Command | Purpose |
|---|---|
mailq | Show the queue |
postqueue -p | Show the queue (Postfix syntax) |
postqueue -f | Flush deferred messages |
postsuper -d <ID> | Delete a message |
postsuper -h <ID> | Hold a message |
postsuper -H <ID> | Release a held message |
Log Locations
| Distribution | Log File |
|---|---|
| Debian / Ubuntu | /var/log/mail.log |
| RHEL / Rocky | /var/log/maillog |
| systemd | journalctl -u postfix |
Alias Commands
| Command | Purpose |
|---|---|
postalias /etc/aliases | Rebuild alias database |
newaliases | Sendmail-compatible equivalent |
Best Practices
โ Do This:
# Set mydestination to include the domain
mydestination = $myhostname, localhost.$mydomain, $mydomain # โ
# Restrict mynetworks to the local subnet
mynetworks = 127.0.0.0/8, 192.168.1.0/24 # โ
# Set the postmaster alias
postmaster: root # โ
# Rebuild the alias table after editing
postalias /etc/aliases # โ
# Check the log after sending a test message
tail -f /var/log/mail.log # โ
# Use postfix reload after changing main.cf
postfix reload # โ
โ Don’t Do This:
# Set mynetworks to any
mynetworks = 0.0.0.0/0 # Open relay # โ
# Omit the postmaster alias
# Mail to postmaster bounces # โ
# Forget to rebuild the alias table
# New aliases are not active # โ
# Edit main.cf and restart without reloading
# The changes are not applied # โ
# Ignore the queue
# Deferred messages pile up and disk fills # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Relay access denied | mynetworks does not include the client | Add the subnet |
| User unknown | mydestination missing the domain | Add $mydomain |
| Open relay | mynetworks includes public interfaces | Restrict to local subnets |
| Alias not working | postalias not run | Rebuild the table |
| Mail stuck in queue | Destination unreachable or DNS issue | Check mailq and the log |
| Service not listening | inet_interfaces set to loopback-only | Set to all |
Real-World Examples
1. Basic main.cf
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, $mydomain
mynetworks = 127.0.0.0/8, 192.168.1.0/24
2. Postmaster alias
postmaster: root
3. Rebuild aliases
sudo postalias /etc/aliases
4. Reload Postfix
sudo postfix reload
5. Check queue
mailq
6. Flush deferred queue
sudo postqueue -f
7. Delete a message
sudo postsuper -d <QUEUE_ID>
8. Check the mail log
sudo tail -f /var/log/mail.log
9. Test SMTP
telnet localhost 25
10. Send a test message
echo "Test" | mail -s "Test" root
Visual
Postfix Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ POSTFIX IS AN MTA, NOT A COMPLETE MAIL SYSTEM โ
โ โ
โ MUA (Thunderbird) โ
โ โ SMTP โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Postfix (MTA) โ โ
โ โ โโโ accepts mail via SMTP โ โ
โ โ โโโ queues it โ โ
โ โ โโโ delivers locally to /var/mail/$USER โ โ
โ โ โโโ relays to remote servers via SMTP โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ MDA (Dovecot) โ โ
โ โ โโโ reads /var/mail/$USER or ~/Maildir โ โ
โ โ โโโ serves IMAP/POP3 to the client โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Postfix moves mail; Dovecot lets users read it. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
main.cf Parameters
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE FOUR CRITICAL PARAMETERS โ
โ โ
โ myhostname = mail.example.com โ
โ โ The server's own name โ
โ โ
โ mydomain = example.com โ
โ โ The parent domain โ
โ โ
โ mydestination = $myhostname, $mydomain โ
โ โ Domains Postfix delivers locally โ
โ โ
โ mynetworks = 127.0.0.0/8, 192.168.1.0/24 โ
โ โ Clients allowed to relay โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Mail Queue States
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ POSTFIX HAS FIVE QUEUE STATES โ
โ โ
โ incoming โ arriving messages โ
โ active โ being delivered โ
โ deferred โ temporary failure; will retry โ
โ hold โ administratively paused โ
โ corrupt โ unreadable โ
โ โ
โ mailq shows the deferred and active queues. โ
โ postqueue -f retries all deferred messages. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Role | Mail Transfer Agent (MTA) |
| Configuration | /etc/postfix/main.cf |
| Primary daemon | master |
| SMTP port | 25 |
| Local delivery | /var/mail/$USER or ~/Maildir |
| Domain served | mydestination |
| Relay clients | mynetworks |
| Required alias | postmaster |
| Queue view | mailq or postqueue -p |
| Log (Debian) | /var/log/mail.log |
| Log (RHEL) | /var/log/maillog |
| Reload | postfix reload |
Key takeaways:
- Postfix is an MTA, not a mail client. It moves mail between servers via SMTP and delivers it locally. Reading mail requires an MDA like Dovecot for IMAP/POP3.
mydestinationdefines the local domains. Mail addressed to a domain in this list is delivered to a local mailbox. Mail to any other domain is relayed or rejected. A domain-wide server must list$mydomain.mynetworksdefines the relay clients. Clients in this list can send mail through the server to any destination. An incorrect setting makes the server an open relay. The default authorizes the local subnets .- The postmaster alias is required. It must point to a human who can receive delivery failure reports. The
postaliascommand rebuilds the alias table after editing . - The queue is the diagnostic center.
mailqshows the messages, and the log shows the reason for deferral or bounce. A stuck queue is usually a DNS or connectivity problem . postfix reloadapplies configuration changes. A full restart is not necessary formain.cfchanges. The reload re-reads the file without dropping active connections .
Remember: Postfix is the SMTP engine. It accepts mail, queues it, and delivers it either locally or to a remote server. The main.cf file controls the domain it serves, the clients it relays for, and the interfaces it listens on. The mydestination and mynetworks parameters are the two that determine whether the server works correctly or becomes an open relay. The queue and the log are the tools that show what happened to a message. Configure the parameters, reload the service, send a test message, and check the log.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!