This is the fifth part of series of post on setting up a mail server for your personal use.

This time we will cover how to install Postfix. Postfix is the actual mail server doing the delivery of the emails. In our specific cases, we need it for the following activities:

  • Deliver to our Dovecot IMAP server the mail that an external program (fetchmail) will fetch from an external account
  • Send email from our local accounts by using an external (e.g. Google) account
  • Internal delivery of email, which includes notifications generated by the system

Installation

We’ll make a base installation of postfix. The installer can run interactively to choose from a number of scenarios, but we can skip that with the -y flag

$ sudo apt-get install -y postfix

Configuration

There two main configuration files, main.cf and master.cf, the first contains the global options, while the latter configure the single services inside postfix. For now we’ll be fine with only changing main.cf

Host and domain configuration

The first important part is setup hostname/domain related configuration. I will use the convention set in the previous posts, with the hostname set to ubuntu and the domain name set to localdomain. The default values should in general suffice, and look more or less like the following

myhostname = ubuntu.localdomain
mydomain = localdomain
myorigin = $myhostname
mydestination = $myhostname, localhost.$mydomain, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128

If the are not present at all in the configuration file, it is fine to leave them missing. The above lines are important because they specify which is the hostname of the machine, its domain and for whom we are handling the mail, and mark the difference between the local mail (meant to stay on the machine) and external mail (meant to be delivered somewhere else). Failure to set this up will mean at the very least inability to send any kind of email.

Note that most probably this is not the public name from which the machine may be reachable from internet, but the hostname and local domain name setup during installation.

Since we want to use our external account to deliver our mail, we have to tell Postfix to do so

relayhost = [smtp.gmail.com]:587
smtp_tls_security_level = encrypt
smtp_use_tls = yes

In this example we are telling Postfix that external mail will be delivered through Google’s SMTP server (smtp.gmail.com) on port 587. We the other two lines we require encrypted communication.

If your server use the older SSL protocol instead of TLS (tipically on port 465), you should enable the following options

smtp_tls_wrappermode = yes

It is probably the case that in order to send a mail we’ll need provide to the external service a username and a password, so we should enable also the following

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl/passwd
smtp_generic_maps = hash:/etc/postfix/generic

With this, Postfix will search in the given file the credentials to use. Note that this means that all the mail will be relayed through the same account. If you want to use different accounts for different users the options to use are different (smtp_sender_dependent_authentication and sender_dependent_relayhost_maps) but I will not cover them for now.

Certificates

In order to offer a encrypted communication, we need to tell Postfix where to get the needed certificates. This can be done so

smtpd_tls_cert_file=etc/letsencrypt/live/mymailserver.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mymailserver.example.com/privkey.pem
smtpd_use_tls=yes

The example above assumes that you have configured the certificates as explained in a previous entry using Let’s Encrypt. If it not the case and you obtained the certificates in a different way, you may have to change the paths.

External relay configuration

In main.cf we chose to use an external relay to deliver our mail, but we haven’t specified yet the credentials to use. For this, we will need to edit two different files. /etc/postfix/generic and /etc/postfix/sasl/passwd (it’s the two files that we specified above). The first contains a map between local users and external user. In our case, it’s a map between the local user and the account on the relay server that will be use to send the mail.

For example, if our system has a user name myuser, the content could be as follows

myuser@localdomain    myname@gmail.com

Again I assume that the local domain is localdomain and that we are delivering our emails through Google’s server. The second file contain the actual credentials to use. The content should be a line like the following.

[smtp.gmail.com]:587    myname@gmail.com:mypassword

The first part of the line should be the SMTP server to use, and must match what we choose in main.cf as relay_host. The second part is a pair username:password to authenticate. The user should be the same used in the generic file

Once the changes are done, we need to create the actual lookup table used by Postfix from the textual one. We can do it this way

$ cd /etc/postfix
$ sudo postmap generic
$ cd sasl
$ sudo postmap passwd

Two new files /etc/postfix/generic.db and /etc/postfix/sasl/passwd.db should appear.

Final touch

By default Postfix has a low limit on the maximum size of the messages that it will accept. If we plan to send or receive emails with big attachments we should to increase it. In particular we want to increase it to a value bigger than what our external mail accepts, otherwise we may not be able to receive some valid emails.

message_size_limit = 100000000

This will limit the size to about 100MB.

(Re)start the service

We can finally restart the service:

$ sudo systemctl restart postfix

Test it

You should be able to send messages now. My suggested method to test it is to install the old fashioned bsd-mailx package and send an email from the command line:

$ mail myname@gmail.com

Don’t forget that with this tool you need to press ctrl-D to finish writing the body of the email ;-).