Table of Contents
Understanding Postfix Components and Files
Postfix is composed of several daemons and configuration files. For configuration work, you mostly interact with:
main.cf— global configuration (what network to listen on, domains, relaying rules, etc.)master.cf— service definitions (which daemons run, on what ports, and how)aliases(often/etc/aliases) — local alias mappingsvirtual(or other lookup maps) — virtual addresses and domainscanonical,sender_canonical,recipient_canonical— address rewriting (optional)
Service control is usually via:
systemctl start|stop|restart postfixpostfix reload(reload config without full restart)postfix check(syntax and consistency checks)
Paths are typically under /etc/postfix, but may vary slightly by distribution.
Basic Postfix Installation and Initial Setup
On common distributions:
- Debian/Ubuntu:
apt install postfix - RHEL/CentOS/Rocky/Fedora:
dnf install postfix
During installation, some distros run a configuration dialog (e.g. dpkg-reconfigure postfix on Debian/Ubuntu). This usually asks:
- General type: “Internet Site”, “Smarthost”, “Satellite system”, etc.
- System mail name: base domain used for outgoing mail when none is specified.
You can always adjust these later in main.cf.
Key initial steps after install:
- Ensure Postfix is the active MTA (if another MTA like Exim or Sendmail is installed).
- Start and enable the service:
systemctl enable --now postfix- Verify it’s listening:
ss -tlpn | grep :25
Core Settings in main.cf
main.cf defines how Postfix identifies itself and which mail it will accept or send.
Common baseline settings:
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
inet_interfaces = all
inet_protocols = ipv4
mynetworks = 127.0.0.0/8 [::1]/128
relayhost =
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTPExplanation of key parameters:
myhostname: Fully Qualified Domain Name (FQDN) of the mail server.mydomain: Default domain name. Oftenexample.com.myorigin: Domain used for locally posted mail without a domain part.mydestination: Domains that this server considers local (mail is delivered locally).inet_interfaces: Interfaces to listen on (all,loopback-only, etc.).inet_protocols: IPv4, IPv6, or both (all,ipv4,ipv6).mynetworks: IPs allowed to relay mail without authentication (LAN, localhost).relayhost: Upstream relay for outbound mail (used in relay/satellite setups).home_mailbox: Mailbox format and location (e.g.Maildir/vs mbox).smtpd_banner: Banner for the SMTP greeting.
After changes:
postfix check
postfix reloadLocal Delivery and Aliases
For system accounts and local delivery, aliases are important.
Aliases file
Typical path: /etc/aliases (referenced in main.cf as alias_maps).
Example:
postmaster: root
root: admin@example.com
support: support-team@example.comAfter editing:
newaliases
alias_maps is usually:
alias_maps = hash:/etc/aliasesLocal recipients and mydestination
If example.com is in mydestination, mail to user@example.com is treated as local and delivered to a local account user (or via alias/virtual mapping). If the domain should NOT be local, remove it from mydestination and handle it with virtual domains or relaying.
Basic SMTP Access Control
Postfix uses “restriction classes” to control who can send to whom and under what conditions, typically in smtpd_recipient_restrictions and related directives.
A minimal but sensible baseline:
smtpd_helo_required = yes
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destinationpermit_mynetworks: allow hosts defined inmynetworksto relay.permit_sasl_authenticated: allow authenticated SMTP clients (SASL).reject_unauth_destination: reject relaying for destinations not inmydestination, virtual domains, or relay domains.
For public-facing servers, you usually add anti-abuse checks (RBLs, invalid HELO, etc.), but the above expresses the core pattern: allow local/trusted/authenticated users, deny others from relaying.
Configuring Postfix for Common Roles
Postfix may fulfil several typical roles. Configuration differs per role.
Full Internet Mail Server (MX)
This server:
- Accepts mail from the Internet for your domains.
- Handles outbound mail for local users and possibly relays.
Key steps:
- Set proper identity:
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain- Listen on all interfaces:
inet_interfaces = all- Configure
mynetworkscarefully — most often only127.0.0.0/8and any internal admin networks. - Ensure correct DNS:
- MX record for
example.compointing tomail.example.com. - A (or AAAA) record for
mail.example.com.
Security, TLS, spam controls and authentication are typically mandatory on Internet-facing servers (covered further below).
Internal Relay or Smarthost
Here, Postfix only accepts mail from inside your network (or specific clients) and relays it to the wider Internet or a central provider.
Example:
myhostname = relay.internal.example.com
mydomain = internal.example.com
myorigin = example.com
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 127.0.0.0/8 10.0.0.0/8
relayhost = [smtp.isp.example]:587- The
relayhostis the upstream mail server; square brackets prevent MX lookups. - Use SASL to authenticate to the ISP relay if required (see the SASL section).
Satellite System / Outbound-Only
A small application host that just needs to send mail (alerts, logs) via a central mail relay.
Key idea: it doesn’t receive mail from the Internet; it uses another server to relay.
Example:
myhostname = app01.example.com
mydomain = example.com
myorigin = example.com
inet_interfaces = loopback-only
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost = [mail.example.com]:587
mynetworks = 127.0.0.0/8
Here, Postfix listens only on loopback, and all outbound mail goes via relayhost.
TLS Encryption for SMTP (STARTTLS)
TLS is needed both for:
- Securing incoming client/server connections.
- Authenticating clients (often combined with SASL).
Basic TLS server configuration
Generate or obtain a certificate and key for mail.example.com, then configure:
smtpd_tls_cert_file = /etc/ssl/certs/mail.example.com.crt
smtpd_tls_key_file = /etc/ssl/private/mail.example.com.key
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtp_tls_security_level = may
smtp_tls_loglevel = 1smtpd_directives apply to incoming mail.smtp_directives apply to outbound connections to other MTAs.
For stronger policies (e.g. mandatory for submission), you can use encrypt or verify security levels on specific ports (see master.cf customization).
User Authentication with SASL (Submission)
For users sending mail from clients (Thunderbird, Outlook, etc.), use the submission port (587) with STARTTLS and SASL authentication.
Enabling the submission service in master.cf
In /etc/postfix/master.cf, enable or add:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATINGKey points:
- Port 587 (
submission) is for authenticated clients. smtpd_tls_security_level=encryptenforces TLS.smtpd_sasl_auth_enable=yesturns on authentication.- Restriction: only authenticated users can send, others are rejected.
SASL backend selection (example with Dovecot)
If you’re using Dovecot for IMAP/POP, you commonly use Dovecot SASL:
In main.cf:
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
This assumes Dovecot is configured to expose an auth socket at /var/spool/postfix/private/auth (or similar). Other SASL backends (e.g. Cyrus SASL) require different options and configuration files.
Virtual Domains and Users
When you host mail for multiple domains or non-system users, use Postfix’s virtual facilities.
Virtual alias domains
Useful when all addresses are mapped to local or external addresses.
In main.cf:
virtual_alias_domains = example.net example.org
virtual_alias_maps = hash:/etc/postfix/virtual
/etc/postfix/virtual example:
postmaster@example.net alice@example.net
info@example.net alice@example.net
*@example.org bob@example.comAfter modifying:
postmap /etc/postfix/virtual
postfix reloadNow mail to those domains is rewritten according to the map and then processed as usual.
Virtual mailbox domains (mailboxes not tied to system users)
For separate, non-UNIX accounts:
In main.cf (simplified example):
virtual_mailbox_domains = example.net
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = lmtp:unix:private/dovecot-lmtp
/etc/postfix/vmailbox example:
alice@example.net example.net/alice/
bob@example.net example.net/bob/Then:
postmap /etc/postfix/vmailbox
postfix reload
Mail for these addresses is stored in directories like /var/mail/vhosts/example.net/alice/. Delivery is usually done by a dovecot LMTP service.
Outbound Relaying and Authentication to a Relayhost
If sending mail via an external relay (ISP or provider), you often need SMTP authentication.
In main.cf:
relayhost = [smtp.provider.example]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
/etc/postfix/sasl_passwd:
[smtp.provider.example]:587 username:passwordThen:
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
postfix reloadNow Postfix authenticates to the relayhost when sending outbound mail.
Address Rewriting and Canonical Mapping
Postfix can rewrite sender or recipient addresses to enforce specific formats.
Common for standardizing outbound sender addresses:
In main.cf:
sender_canonical_maps = hash:/etc/postfix/sender_canonical
/etc/postfix/sender_canonical:
root admin@example.com
@internal.local @example.comThen:
postmap /etc/postfix/sender_canonical
postfix reload
Now, root@internal.local becomes admin@example.com, and any @internal.local becomes @example.com.
Logging, Testing, and Verification
Useful commands and techniques to validate configuration:
- Syntax/config checks:
postfix check
postconf -n # show non-default settings- Controlled reload:
postfix reload- Test sending mail locally:
echo "test" | mail -s "Postfix test" you@example.com- SMTP dialog testing (unencrypted):
telnet localhost 25or
openssl s_client -connect mail.example.com:587 -starttls smtp- Check logs (paths vary by system):
/var/log/maillog/var/log/mail.logjournalctl -u postfix
Look for connection attempts, authentication successes/failures, relay denials, and TLS negotiation outcomes.
Hardening Basics Specific to Postfix Configuration
Postfix can be significantly hardened with relatively simple config options:
Examples:
smtpd_helo_required = yes
disable_vrfy_command = yes
smtpd_client_restrictions =
permit_mynetworks,
reject_rbl_client zen.spamhaus.org
smtpd_helo_restrictions =
permit_mynetworks,
reject_invalid_helo_hostname
smtpd_sender_restrictions =
reject_non_fqdn_sender,
reject_unknown_sender_domainEach restriction should be introduced with care and tested, as aggressive settings can cause false positives. Combine with other mail security mechanisms (SPF, DKIM, DMARC) configured outside Postfix core where appropriate.
Managing and Customizing master.cf
master.cf controls which Postfix services run, and how.
Common tasks:
- Enable or disable services (e.g.
submission,smtps). - Adjust process limits, chroot behavior.
- Route special mail streams differently.
Example: enabling smtps (implicit TLS on port 465):
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
After editing master.cf:
postfix reload
Always review postfix status or systemctl status postfix to confirm services started correctly.
Basic Troubleshooting Patterns
Common issues and where to look:
- Relaying denied:
- Check
relayhost,mynetworks,smtpd_recipient_restrictions. - Authentication failures:
- Review SASL logs (often in mail logs or separate auth logs).
- Confirm SASL backend path (
smtpd_sasl_path). - TLS problems:
- Verify certificate/key paths and permissions.
- Use
openssl s_clientto inspect handshake. - Mail loops:
- Check
mydestinationand DNS records (MX pointing to wrong host). - Virtual domain issues:
- Ensure
postmaphas been run on map files. - Confirm
virtual_*directives match the actual maps.
Systematically using postconf -n, postfix check, and carefully reading mail logs are central to debugging Postfix configurations.