Andrew Mercer
on this page

Installing Postfix

RHEL / CentOS / Fedora:

yum -y install postfix
systemctl enable postfix
systemctl start postfix

Debian / Ubuntu:

sudo apt-get -y install postfix mailutils

On Debian-family systems, the package's debconf installer prompts interactively for the general "system mail type" (No configuration / Internet Site / Internet with smarthost / Satellite system / Local only) and basic hostname. That prompt can be pre-seeded non-interactively — useful for scripted/unattended installs (e.g. building a null client, see the relaying doc):

debconf-set-selections <<< "postfix postfix/main_mailer_type select Satellite system"
debconf-set-selections <<< "postfix postfix/mailname string $HOSTNAME"
debconf-set-selections <<< "postfix postfix/relayhost string smtp.mailgun.org"
sudo apt-get -y install postfix mailutils

Switching the system MTA to Postfix

RHEL-family systems use the alternatives mechanism to decide which installed MTA provides sendmail-compatible behavior (/usr/sbin/sendmail) for local applications (cron, system tools, etc. that shell out to sendmail directly):

alternatives --config mta
There is 1 program that provides 'mta'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/sbin/sendmail.postfix

Enter to keep the current selection[+], or type selection number:

If Postfix is the only MTA installed, this is typically configured automatically — you'll just see it confirmed here, not something you usually need to change by hand.

Minimal main.cf for a standalone server

# /etc/postfix/main.cf
myhostname = host.domain.tld     # confirm with: hostname --long
myorigin = $myhostname
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks_style = subnet        # or explicitly: mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

A few of these deserve explanation:

  • recipient_delimiter = + enables "plus addressing" ([email protected] all deliver to user) — handy for filtering, and worth setting even if nothing uses it yet.
  • mailbox_size_limit = 0 disables Postfix's own per-mailbox size cap (leaving quota enforcement, if any, to the delivery agent/filesystem instead).
  • mynetworks_style = subnet is a shorthand that auto-derives mynetworks from the local interfaces' subnets — convenient, but be deliberate about it on a multi-homed host, since it effectively decides who's allowed to relay without authentication (see the security doc).

Testing mail flow

From the command line, using the local mail command:

yum -y install mailx     # provides /usr/bin/mail, RHEL-family
echo "Test" | mail -s "Test" [email protected]

Manually, over raw SMTP with telnet — the single most useful debugging technique in this entire guide, because it removes every layer (MUA, submission library, etc.) between you and exactly what Postfix sees:

telnet localhost 25
Connected to localhost.
220 host.domain.tld ESMTP Postfix

mail from: test@example.com
250 Ok

rcpt to: someone@example.com
250 Ok

data
354 End data with <CR><LF>.<CR><LF>
Subject: test message

This is a test message
.
250 2.0.0 Ok: queued as E06041CF26

quit

Note the envelope sender (mail from:) doesn't need to be a real/deliverable address for this local test — you're just confirming Postfix accepts and queues the message. Watch /var/log/maillog (RHEL-family) or /var/log/mail.log (Debian-family) in another terminal while you do this:

tail -F /var/log/maillog

SASL credentials for testing auth manually, if you need to hand-construct an AUTH PLAIN line for troubleshooting:

perl -MMIME::Base64 -e 'print encode_base64("\0username\0password")'

Adding a simple alias/redirect while you're getting the basics working

The most common very-first customization — forwarding one address to another — uses virtual_alias_maps:

# /etc/postfix/main.cf
virtual_alias_maps = hash:/etc/postfix/virtual
# /etc/postfix/virtual
root@host.domain.tld  you@domain.tld
postmap /etc/postfix/virtual
postfix reload

This exact pattern — a lookup table plus postmap plus reload — recurs everywhere in Postfix configuration; see the overview doc's "lookup tables" section and the virtual domains doc for the fuller version of this (multiple domains, mailing lists, etc.).