Install and configure Postfix

Note:
This guide does not cover setting up Postfix Virtual Domains. For information on Virtual Domains and other advanced configurations see References.

Install Postfix

To install Postfix run the following command:

sudo apt install postfix

It is OK to accept defaults initially by pressing return for each question. Some of the configuration options will be investigated in greater detail in the configuration stage.

Deprecation warning:
The mail-stack-delivery metapackage has been deprecated in Focal. The package still exists for compatibility reasons, but won’t setup a working email system.

Configure Postfix

There are four things you should decide before configuring:

  • The <Domain> for which you’ll accept email (we’ll use mail.example.com in our example)
  • The network and class range of your mail server (we’ll use 192.168.0.0/24)
  • The username (we’re using steve)
  • Type of mailbox format (mbox is the default, but we’ll use the alternative, Maildir)

To configure postfix, run the following command:

sudo dpkg-reconfigure postfix

The user interface will be displayed. On each screen, select the following values:

  • Internet Site
  • mail.example.com
  • steve
  • mail.example.com, localhost.localdomain, localhost
  • No
  • 127.0.0.0/8 \[::ffff:127.0.0.0\]/104 \[::1\]/128 192.168.0.0/24
  • 0
  • +
  • all

To set the mailbox format, you can either edit the configuration file directly, or use the postconf command. In either case, the configuration parameters will be stored in /etc/postfix/main.cf file. Later if you wish to re-configure a particular parameter, you can either run the command or change it manually in the file.

Configure mailbox format

To configure the mailbox format for Maildir:

sudo postconf -e 'home_mailbox = Maildir/'

This will place new mail in /home/<username>/Maildir so you will need to configure your Mail Delivery Agent (MDA) to use the same path.

SMTP authentication

SMTP-AUTH allows a client to identify itself through the Simple Authentication and Security Layer (SASL) authentication mechanism, using Transport Layer Security (TLS) to encrypt the authentication process. Once it has been authenticated, the SMTP server will allow the client to relay mail.

Configure SMTP authentication

To configure Postfix for SMTP-AUTH using SASL (Dovecot SASL), run these commands at a terminal prompt:

sudo postconf -e 'smtpd_sasl_type = dovecot'
sudo postconf -e 'smtpd_sasl_path = private/auth'
sudo postconf -e 'smtpd_sasl_local_domain ='
sudo postconf -e 'smtpd_sasl_security_options = noanonymous,noplaintext'
sudo postconf -e 'smtpd_sasl_tls_security_options = noanonymous'
sudo postconf -e 'broken_sasl_auth_clients = yes'
sudo postconf -e 'smtpd_sasl_auth_enable = yes'
sudo postconf -e 'smtpd_recipient_restrictions = \
permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'

Note:
The smtpd_sasl_path config parameter is a path relative to the Postfix queue directory.

There are several SASL mechanism properties worth evaluating to improve the security of your deployment. The options “noanonymous,noplaintext” prevent the use of mechanisms that permit anonymous authentication or that transmit credentials unencrypted.

Configure TLS

Next, generate or obtain a digital certificate for TLS. MUAs connecting to your mail server via TLS will need to recognise the certificate used for TLS. This can either be done using a certificate from Let’s Encrypt, from a commercial CA or with a self-signed certificate that users manually install/accept.

For MTA-to-MTA, TLS certificates are never validated without prior agreement from the affected organisations. For MTA-to-MTA TLS, there is no reason not to use a self-signed certificate unless local policy requires it. See our guide on security certificates for details about generating digital certificates and setting up your own Certificate Authority (CA).

Once you have a certificate, configure Postfix to provide TLS encryption for both incoming and outgoing mail:

sudo postconf -e 'smtp_tls_security_level = may'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
sudo postconf -e 'smtpd_tls_key_file = /etc/ssl/private/server.key'
sudo postconf -e 'smtpd_tls_cert_file = /etc/ssl/certs/server.crt'
sudo postconf -e 'smtpd_tls_loglevel = 1'
sudo postconf -e 'smtpd_tls_received_header = yes'
sudo postconf -e 'myhostname = mail.example.com'

If you are using your own Certificate Authority to sign the certificate, enter:

sudo postconf -e 'smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem'

Again, for more details about certificates see our security certificates guide.

Outcome of initial configuration

After running all the above commands, Postfix will be configured for SMTP-AUTH with a self-signed certificate for TLS encryption.

Now, the file /etc/postfix/main.cf should look like this:

# See /usr/share/postfix/main.cf.dist for a commented, more complete
# version
    
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
    
# appending .domain is the MUA's job.
append_dot_mydomain = no
    
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
    
myhostname = server1.example.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = server1.example.com, localhost.example.com, localhost
relayhost =
mynetworks = 127.0.0.0/8
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
smtpd_sasl_local_domain =
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,permit_mynetworks,reject _unauth_destination
smtpd_tls_auth_only = no
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_key_file = /etc/ssl/private/smtpd.key
smtpd_tls_cert_file = /etc/ssl/certs/smtpd.crt
smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

The Postfix initial configuration is now complete. Run the following command to restart the Postfix daemon:

sudo systemctl restart postfix.service

SASL

Postfix supports SMTP-AUTH as defined in RFC2554. It is based on SASL. However it is still necessary to set up SASL authentication before you can use SMTP-AUTH.

When using IPv6, the mynetworks parameter may need to be modified to allow IPv6 addresses, for example:

mynetworks = 127.0.0.0/8, [::1]/128

Configure SASL

Postfix supports two SASL implementations: Cyrus SASL and Dovecot SASL.

To enable Dovecot SASL the dovecot-core package will need to be installed:

sudo apt install dovecot-core

Next, edit /etc/dovecot/conf.d/10-master.conf and change the following:

service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Its default
  # permissions make it readable only by root, but you may need to relax these
  # permissions. Users that have access to this socket are able to get a list
  # of all usernames and get results of everyone's userdb lookups.
  unix_listener auth-userdb {
    #mode = 0600
    #user = 
    #group = 
  }
    
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
 }

To permit use of SMTP-AUTH by Outlook clients, change the following line in the authentication mechanisms section of /etc/dovecot/conf.d/10-auth.conf from:

auth_mechanisms = plain

to this:

auth_mechanisms = plain login

Once you have configured Dovecot, restart it with:

sudo systemctl restart dovecot.service

Test your setup

SMTP-AUTH configuration is complete – now it is time to test the setup. To see if SMTP-AUTH and TLS work properly, run the following command:

telnet mail.example.com 25

After you have established the connection to the Postfix mail server, type:

ehlo mail.example.com

If you see the following in the output, then everything is working perfectly. Type quit to exit.

250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250 8BITMIME

Troubleshooting

When problems arise, there are a few common ways to diagnose the cause.

Escaping chroot

The Ubuntu Postfix package will, by default, install into a chroot environment for security reasons. This can add greater complexity when troubleshooting problems.

To turn off the chroot usage, locate the following line in the /etc/postfix/master.cf configuration file:

smtp      inet  n       -       -       -       -       smtpd

Modify it as follows:

smtp      inet  n       -       n       -       -       smtpd

You will then need to restart Postfix to use the new configuration. From a terminal prompt enter:

sudo service postfix restart

SMTPS

If you need secure SMTP, edit /etc/postfix/master.cf and uncomment the following line:

smtps     inet  n       -       -       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Log viewing

Postfix sends all log messages to /var/log/mail.log. However, error and warning messages can sometimes get lost in the normal log output so they are also logged to /var/log/mail.err and /var/log/mail.warn respectively.

To see messages entered into the logs in real time you can use the tail -f command:

tail -f /var/log/mail.err

Increase logging detail

The amount of detail recorded in the logs can be increased via the configuration options. For example, to increase TLS activity logging set the smtpd_tls_loglevel option to a value from 1 to 4.

sudo postconf -e 'smtpd_tls_loglevel = 4'

Reload the service after any configuration change, to activate the new config:

sudo systemctl reload postfix.service

Logging mail delivery

If you are having trouble sending or receiving mail from a specific domain you can add the domain to the debug_peer_list parameter.

sudo postconf -e 'debug_peer_list = problem.domain'
sudo systemctl reload postfix.service

Increase daemon verbosity

You can increase the verbosity of any Postfix daemon process by editing the /etc/postfix/master.cf and adding a -v after the entry. For example, edit the smtp entry:

smtp      unix  -       -       -       -       -       smtp -v

Then, reload the service as usual:

sudo systemctl reload postfix.service

Log SASL debug info

To increase the amount of information logged when troubleshooting SASL issues you can set the following options in /etc/dovecot/conf.d/10-logging.conf

auth_debug=yes
auth_debug_passwords=yes

As with Postfix, if you change a Dovecot configuration the process will need to be reloaded:

sudo systemctl reload dovecot.service

Note:
Some of the options above can drastically increase the amount of information sent to the log files. Remember to return the log level back to normal after you have corrected the problem – then reload the appropriate daemon for the new configuration to take effect.

References

Administering a Postfix server can be a very complicated task. At some point you may need to turn to the Ubuntu community for more experienced help.

2 Likes

While postfix is the standard default for Ubuntu, there are numerous other options. I’ve found msmtp to be easy to set up and lightweight (if a bit slow, but that may just be me…)

Exim4 and Sendmail (now known as Proofpoint) are worth consideration, and also documented in this guide.

I dropped the section on mail-stack-delivery (deprecated and not working in Focal) and added a deprecation warning about it.

There’s also Let’s Encrypt, which I don’t think can be described as “commercial CA”.

Thanks, good point about Let’s Encrypt, I’ve added a mention to the article.

1 Like

@paride @bryce

Thanks. Nice Article.

We wanted a smtp (Gmail) only mail server for fail2ban, graylog etc services used for alerts. We wanted the hostname in email title. However changing anything on

mydestination = server1.example.com, localhost.example.com, localhost

doesn’t put hostname in email title. So we left mydestination field altogether with a simple main.cf

alias_maps = hash:/etc/aliases

relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_pwd
smtp_sasl_security_options = noanonymous
smtp_tls_CApath = /etc/ssl/certs
smtpd_tls_CApath = /etc/ssl/certs
smtp_use_tls = yes

It works. However it generates lots of entries on /var/log/mail.log

C345B88528D: to=<root@server-02.localdomain>, orig_to=<root>, relay=local, delay=0.25, delays=0.05/0.01/0/0.19, dsn=2.0.0, status=sent (delivered to mailbox)

Is there anyway we can stop these messages?

As far as I understand these are relaying mail on localhost. We do have server fqdn like server-02.example.com though we do not use it anywhere.

I found 2 issues when setting this up on a brand new Ubuntu Server 20.04 LTS:

sudo postconf -e ‘smtpd_sasl_security_options = noanonymous,noplaintext’

should be:

sudo postconf -e 'smtpd_sasl_security_options = noanonymous'

Also, when editing /etc/dovecot/conf.d/10-master.conf, you missed the closing ‘}’ on the

service auth {

section.

Once I changed those, I was able to successfully telnet from another server.

Thanks for the article :slight_smile:

2 Likes

@digital-pig thanks for taking the time to post about the changes you had to make! I’ve corrected the missing }.

As far as removing “noplaintext”, these configurations should allow plaintext mechanisms, but only over a TLS-encrypted connection. Did you also setup TLS or run into some other type of error?

1 Like

Actually I did not set up TLS. I was having some other issues getting graylog to send emails, so that may well be the cause of it. :smiley:

The sample man.cf file shown doesn’t match what the file looks like after running the previous commands. In particular, the mailbox_command variable isn’t set. The commands provided don’t even install procmail, so the sample file shown would probably generate errors.

1 Like

I agree with @digital-pig but I’d instead remove the tweaking of both smtpd_sasl_security_options and smtpd_sasl_tls_security_options to keep them at their default. Ensuring TLS is required for SASL would then be done with:

sudo postconf -e 'smtpd_tls_auth_only = yes'

The noplaintext setting caused problem to some user: LP: #1940603

3 Likes

This document should be more clear about how to configure postfix to accept communication on other ports, such as the submission port (587).
Also, if a mail server is put on the open Internet (i.e. not behind a firewall/filter), it really needs to have some sort of mechanism to filter and reject bad messages, although configuring these tools (e.g. SpamAssassin) may deserve a separate article.

What about adding a whole new section:
Postfix and LDAP?

While current guide tells about Dovecot Sasl auth it’s not enabled in final conf:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

These lines are missing. I’m fighting with Postfix + Dovecot SASL for 4 days already and cannot configure it :face_with_symbols_over_mouth:. This guide is complete disappointment so far.

Hello,
Did you run the commands in the SMTP Authentication section? The two first ones

sudo postconf -e 'smtpd_sasl_type = dovecot'
sudo postconf -e 'smtpd_sasl_path = private/auth'

should add

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

to /etc/postfix/main.cf or whatever your main config file is.

Yeap, I have these lines in my config and my build is broken. Log says

postfix/smtpd[2050092]: fatal: no SASL authentication mechanisms

all the time.

Do you have the TLS certificates in place?

Also, would you mind sharing the Ubuntu and package versions you are using to follow this guide? This would help us reproduce your case to check if there are any issues with the guide and help figuring out what the current issue is.

As mentioned in comment 11: Install and configure Postfix - #11 by sdeziel1. smtpd_sasl_security_options and smtpd_sasl_tls_security_options should be left untouched as otherwise you run into issues. Only setting smtpd_tls_auth_only = yes is simpler and safer IMHO.

Issue description

When using telnet 127.0.0.1 25, postfix will apply smtpd_sasl_security_options = noanonymous,noplaintext meaning that it will filter out PLAIN and LOGIN as they are are plain text mechanisms. Since dovecot was told to only enable those 2 (see auth_mechanisms), you have no other SASL mechanism to use… hence the fatal: no SASL authentication mechanisms.

If however you connect with openssl s_client -connect 127.0.0.1:25 -starttls smtp you should see that PLAIN and LOGIN are both permitted because now you have an encrypted connection to the MTA so smtpd_sasl_tls_security_options = noanonymous applies. Since PLAIN and LOGIN are not annonymous, postfix doesn’t filter out any mechanism.

The noplaintext directive can be confusing because it sounds like something we want to prevent leaking credentials in plain text. However, PLAIN and LOGIN are meant to be used on top of TLS meaning there is no actual plain text on the wire.

Best current practices

I think the guide would need to be refreshed to follow best current practices. SASL auth should not be enabled on TCP/25, only on TCP/465 and TCP/587. It is best to leave port 25 for MTA to MTA (server to server) communication with opportunistic TLS and have users hit the smtps(TCP/465)/submission (TCP/587) ports where both TLS and authentication (SASL) are mandatory. Unfortunately, I don’t have time to do a rewrite :frowning_face:

2 Likes

I guess that was the case. Once I commented some of the smtpd_sasl options the error disappeared. If I understand correctly these few options are tightly connected to builtin Postfix SASL which disabled in my case in favour of Dovecot.

Postfix doesn’t implement SASL itself, it relies on Cyrus or Dovecot to do so. However, Postfix can filter out some mechanisms which is what smtpd_sasl_security_options and smtpd_sasl_tls_security_options are for.

smtpd_tls_auth_only = yes means that Postfix will propose SASL only when TLS is used by the client. In such case, plain text mechanisms are considered safe to use.

1 Like