Notes: Setting up a modern Mail Server and Relay

This is an attempt to clean up these notes:

References go there. This post is a summary.

0. Before we start

These notes were collected while setting up a brand new mail server, on a fresh install of Ubuntu 16.04 Server.

I assume the user is root.

1. Pick a subdomain (and domain) for your mail server

Typically this is mail (i.e., but it can be anything. What’s important is that you’re consistent. is often referred to as the FQDN (Fully Qualified Domain Name).

You will be using all 3 variants (mail,, depending on what you’re doing.

2. Postfix (MTA)

Postfix is an Mail Transfer Agent (MTA) used to route and deliver e-mail.

Postfix uses SMTP (Simple Mail Transfer Protocol). It listens for mail, and either delivers it to a local user, or relays it to an external address. It does not provide a way for users to view their local mailbox. To be able to view a mailbox, you need to use a piece of software like Dovecot to run an IMAP or POP3 server.

With Postfix installed, we have everything we need to send and receive e-mails (other tools make it easier though).

2a. Before we start

We need to edit the host files. By default, the machine doesn’t know what domain to send e-mails from.

More than likely, the first line will be missing the domain part ( Adjust it accordingly.

This sets the e-mail address emails from users send from (i.e. [email protected]).

2b. Install Postfix and MailUtils

Done. You now have a mailbox in /var/mail/root

Here are some useful commands you may want to reference.

2c. Configuring Postfix

3. PTR (Pointer Records, i.e. Reverse DNS lookups)

PTR’s are used to convert an IP address in to a domain name.

PTR’s are set by your webhost (specifically, whomever owns/allocated your public IP address).

It should be set your mail server’s FQDN.

4. SPF (Sender Policy Framework)

SPF Records are used to say what IPs are allowed to send mail on behalf of a domain.

Add them as TXT records to your DNS (Cloudflare, etc).

You may also notice your DNS supports SPF records. These are optional, and set to the exact same values. SPF records were obsoleted, as AFAIK everybody used TXT records instead, and SPF was simply unable to get enough support.

The 2nd case ( makes reference to the FQDN. When configuring a separate domain to use your mail server, you only need a version of the 2nd line pointing to your mail server (unless you also want to get mail from Mail servers will recursively follow “include:’s” until they find an SPF record with an IP (though I’ve seen it suggested you should keep recursion depth low for maximum compatibility).

~all” means softfail on SPF failures (i.e. don’t fail). To fail on SPF failures, use “-all“.

To check that records are correctly set, dig them.

* * *

When setting up a mail relay server, the IP address of the sender will change to the relay itself. Thus, the SPF check will now fail. If using “~all” this fine, but may not be ideal long term.

To correct this, the relay needs to rewrite the sender. SRS should be used for this (discussed later). SRS rewrites the sender in such a way that the origin domain is included, as well as the new (your) domain. The new (your) domain becomes the part after the @ sign, and thus, when doing an SPF check, now passes since your IP address now matches the sender domain’s SPF record.

5. DMARC (Domain Message Authentication Reporting & Conformance)

DMARC records do a few things. Most importantly, they tell other mail servers where to send reports.

These reports can be very helpful for debugging (huzzah).

Reports are XML files sent daily by all the big e-mail providers.

If it’s working correctly, you ([email protected]) will get e-mails. 🙂

If you’re monitoring incoming mail (/var/mail/root), they tend to come delivered as BASE64 encoded ZIP files.

Reports look something like this.

The data in the later half of the report tends to be most useful. Telling you if DKIM and SPF tests pass.

DMARC is not only used for error reporting, but it tells the client what to do upon failure.

The “p=none” tells the client to take no special actions. Alternatively, “p=quarantine” or “p=reject” can be used to take action upon failure (send to spam, reject outright).

It’s good practice to begin with “p=none“. Once you have some reports under your belt, you can begin to quarantine or reject messages. This can be done gradually. More details can be found in the references below:

6. DKIM (DomainKeys Identified Mail)

DKIM is used to uniquely identify a domain using a public+private key pair as a signature. This is NOT encryption.

Together with SPF, mail is validated using the sender’s IP address (SPF), and by confirming their signature (DKIM). DMARC then says what to do about failures (though SPF does too), and who to report them to.

6a. Installing DKIM tools

6b. Generating the DKIM signature and permissions!

Debian/Ubuntu has a standard folder for this: /etc/dkimkeys/

What’s special about this folder is that it’s owned by opendkim:opendkim. Don’t forget to set permissions!

6c. DKIM DNS Settings

The “opendkim-genkey” command above generated a 2nd file, mail.txt.

We want what’s inside the quotes (both sets). Edit that together on one line, removing quotes, like so:

Now you can paste that in to your DNS control panel.

Create a TXT record named mail._domainkey, and paste the edited line above.

6d. Configuring OpenDKIM

Edit the config file.

The default file is fine, but could use a few tweaks.

Now comes the weird stuff.

* * *

On a stock Ubuntu install, Postfix is (mostly) run in a chroot jail. As far as Postfix is concerned, the “/” folder is “/var/spool/postfix/“. It cannot access anything outside this folder.

Therefor, the simplest way to use OpenDKIM with Postfix is with a TCP socket, but a Unix domain socket is much better.

Furthermore, the simplest way to use a Unix domain socket is as follows. Run the following commands:

Next edit the defaults file.

Add this to the end of the file:

Finally, restart the OpenDKIM service.

Again, that’s the easy way (it saves a lot of headaches). See the notes for the hard way (binding).

6e. Configuring Postfix for DKIM

Add these lines to the end of your “/etc/postfix/” file:

Again, since Postfix is inside the chroot jail, the paths above neglect the “/var/spool/postfix” folder.

Restart Postfix.

7. TLS (Transport Layer Security, i.e. Encryption)


8. SRS (Sender Rewriting Scheme)

SRS is used to fix the sender, so forwarded e-mails pass the SPF (i.e. sender’s IP address) test.

How this works can be a little confusing, but essentially this happens:

SPF checks look at what follows the @ sign in the sender address. It takes that domain, checks the matching TXT SPF record, and if the IP address of the sender and SPF record match, it succeeds. So SRS is rewriting the sender’s email to be from you (the forwarder’s) domain, thus letting the SPF check pass.

To setup, install PostSRSD:

Add these lines to the end of your “/etc/postfix/” file:

X. Aliases and Virtual Aliases


X. Adding Domains


X. Dovecot (IMAP and POP3)


X. Send-only Users


Things to Update

Most of the settings are fine and don’t need to be touched.

That said, some things should/need to be updated from time to time.

  • When your Domain or IP address changes, update the PTR and SPF records.
  • You shouldn’t need to, but if you need to refresh the sender identity (DKIM), be sure to update your _ file, and the mail._domainkey DNS record. Otherwise, depending on your DMARC/DKIM/SPF settings, mail delivery will begin to fail.
  • When your SSL certificate expires, you’ll need to go to your server and update your TLS. Otherwise, you lose encryption! In theory mail is still deliverable, but w/o encryption is bad.