Postfix

Postfix is a mail transfer agent (MTA), one of the components on a mail server. We prefer postfix over exim4 just for historical reasons. There have been long debates on what (if any) should be the default MTA for a Debian system (more).

Before installing

If not already set, set the hostname:

$ sudo hostnamectl set-hostname example.com
$ hostnamectl
   Static hostname: example.com
   ...
   Operating System: Debian GNU/Linux 10 (buster)
   ...

Check whether your PTR is correctly set:

$ nslookup example.com
Name: example.com
Address: 12.34.56.78

$ dig -x 12.34.56.78
;; ANSWER SECTION:
78.56.34.12.in-addr.arpa. 86400 IN PTR example.com.

Check your /etc/mailname file:

$ cat /etc/mailname
mail.example.com

Check your /etc/hosts file:

$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 example.com
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Install a certificate for the mail server:

$ sudo certbot certonly --standalone -d mail.example.com

Installation

Installing Postfix on Debian is easy and will automatically uninstall exim4:

$ sudo apt install postfix libsasl2-2 libsasl2-modules

The configuration is less easy. Installing postfix will start by asking you to select the configuration type. Choose “Internet site”.

It will then ask for your “mail name”, this is the fully qualified domain name of your server, without any special subdomain, i.e. just the name after the @ of the email addresses for which you want to manage mails.

Your answers are stored in a file /etc/postfix/main.cf, which you will probably continue to modify afterwards (see below).

There is another config file, /etc/postfix/master.cf. You should activate (uncomment) the smtps line in this file if you plan to use an ssh certificate.

The main.cf configuration file

main.cf
/etc/postfix/main.cf

This is the main configuration file for postfix. See the postfix documentation about the syntax and meaning of the parameters in this file. Summary of the most common ones:

  • relayhost : Empty when this server speaks directly to the smtp servers of the recipients. Otherwise the name of a relay host. See Using a relay host.

  • relay_domains :

  • mydomain : example.com (the “mail name” you specified during configuration)

  • myhostname : mail.$mydomain (the FQDN of the mail server, which in our case points to the same machine as the one where our web server is running)

  • myorigin

  • mydestination

Example:

myhostname = example.com
mail_name = mail.example.com

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

readme_directory = no
compatibility_level = 2

# TLS parameters
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem

smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, example.com, localhost.net, , localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4

home_mailbox = Maildir/

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

Controlling the postfix service:

$ sudo systemctl enable postfix
$ sudo systemctl stop postfix
$ sudo systemctl start postfix
$ sudo systemctl status postfix

Mail aliases

Check your email aliases in /etc/aliases:

$ cat /etc/aliases
postmaster:    root
root:   joe jim
info:   joe

After editing that file, don’t forget to say:

$ sudo newaliases

The /etc/aliases file also contains aliases generated by mailman:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"

Using a relay host

Set the name of the relay host in the relayhost parameter:

relayhost = relay.ovh.com

If the relay host requires a username and password:

$ sudo nano /etc/postfix/sasl_passwd
$ sudo postmap /etc/postfix/sasl_passwd

Here is our suggestion for your /etc/postfix/main.cf file:

myhostname = mail.example.com
myorigin = /etc/mailname
mydestination = $myhostname localhost.$mydomain localhost $mydomain
relayhost =  # where to send all outgoing mail
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mynetworks_style = host
relay_domains =  # fqdn for which you accept incoming mail
inet_interfaces = all

Here is what status should say:

$ sudo service postfix status
● postfix.service - Postfix Mail Transport Agent
   Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
   Active: active (exited) since Thu 2019-12-12 12:01:59 UTC; 7s ago
  Process: 2262 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 2262 (code=exited, status=0/SUCCESS)

Dec 12 12:01:59 my-host-name systemd[1]: Starting Postfix Mail Transport Agent...
Dec 12 12:01:59 my-host-name systemd[1]: Started Postfix Mail Transport Agent.

Multiple domain names on one server

  • The vhosts.txt file contains other domain names hosted on this server, e.g:

    saffre-rumma.net
    
  • The valias.txt file contains manual definitions of redirections from vhosts to local user names, e.g.:

    info@saffre-rumma.net luc
    webmaster@saffre-rumma.net luc
    

Diagnostic tips and tricks

How to see which version of postfix is running:

$ sudo postconf mail_version
mail_version = 3.4.10

To quickly see the value of a given parameter, type:

$ sudo postconf mydomain

To see a list of all parameters and their values:

$ sudo postconf | grep mydomain

Send a simple mail for testing the mail system:

$ mail -s "some test" joe@example.com mike@example.com

Quickly test whether emails are being sent:

$ echo "the body" | mail -s "the subject" mike@example.com

Display the mail log:

$ sudo less /var/log/mail.log

Inspect the mail queue

Display a list of queued mail waiting to be delivered (deferred and pending):

$ mailq

Display the content of queued mail:

$ sudo postcat -vq <QueueID>

Delete all queued mail:

$ sudo postsuper -d ALL

Delete deferred mail queue messages:

$ sudo postsuper -d ALL deferred

Common problems when running your own mail server

550 Email blocked means that the recipient’s mail server refuses to accept an incoming mail because the sender’s mail server is blacklisted.

To see whether your server is blacklisted, you can ask http://multirbl.valli.org/lookup/

For some nice examples of why blacklisting is needed, see bobcares.com.