Postfix send-only email server

Note: I no longer run my own mail server because delivery is difficult.

Web applications sometimes need to send password resets and system alerts. Third party email services abound but in my experience the free plan they bait you with gets canceled after a few months, so finding and keeping a free plan becomes more work than just running the email server yourself. Fortunately setting up a send-only email server you control is easy, and you only have to do it once.

Because the mail server won’t receive incoming email we don’t need a spam filter or virus scanner. A hardware crash won’t delete the mail archive because nothing’s archived on it. Much of the complexity of a full-blown email solution is avoided: no database to store user email, no mailboxes, no web mail interface, just a bare bones server sending emails for local processes.

Mail Transport Agents

The first thing to decide is which Mail Transport Agent (MTA) to use. An MTA is like a post office: someone drops off mail at the post office which sends it to the destination post office (another MTA), where it’s put into the subscriber’s mail box. The subscriber downloads the message from his mail box—called a Mail Delivery Agent (MDA)—using an email client.

Postfix and Exim are two popular open-source MTAs and both are free to use. I chose Postfix because it has a minimalist design that captures the Unix philosophy to make each program do one thing well, along with clear, simple configuration files.1

Setup

I cobbled together these instructions from several online tutorials, the Postfix website, and the official Debian Postfix page (which was the biggest help of all). If you run into any problems, check your distribution’s website for instructions on configuring Postfix.

1. Set the hostname

The examples below assume your server’s IPv4 address is 203.0.113.10 and IPv6 address is 2600:3c01::a123:b456:c789:d012.

We need to pick a convenient name to call the server, called a hostname. In this example we’ll name it Hal.

hostnamectl set-hostname hal

Next set the Fully Qualified Domain Name (FQDN), which is the hostname plus the domain name. Assuming Hal is found at example.com, the FQDN is hal.example.com. Add the FQDN to the hosts file /etc/hosts:

127.0.0.1 localhost.localdomain localhost
203.0.113.10 hal.example.com hal

If an application uses IPv6, add your server’s IPv6 address to /etc/hosts as well:

2600:3c01::a123:b456:c789:d012 hal.example.com hal

2. Create DNS records

Your domain registrar has online tools for creating and modifying your site’s DNS records. Create an A record for the domain as follows:

Type:   A
Host:   hal
Value:  203.0.113.10

If an application uses IPv6, create an AAAA record as well.

Type:   AAAA
Host:   hal
Value:  2600:3c01::a123:b456:c789:d012

3. Install Postfix

apt install postfix mailutils

When the setup wizard asks “General type of mail configuration”, select “Internet Site”.

4. Configure Postfix

Change the following lines in /etc/postfix/main.cf.

inet_interfaces = loopback-only
mydestination = $myhostname localhost.$mydomain

And restart:

systemctl restart postfix

5. Test your setup

echo "This is a test." | mail -s Testing someone@somedomain.com

6. Forward root emails to your personal email address

Edit /etc/aliases:

mailer-daemon: postmaster
postmaster:    root
root:          <your-email-address>

To make the changes take effect, run:

newaliases

7. Install a report generator (optional)

Pflogsumm tells you who is using the server, where, and when. Highly recommended.

a. Install:

apt install pflogsumm

b. Generate report:

pflogsumm /var/log/mail.log

Afterward

You should now have a working mail server that sends emails for local processes only; if you want to allow external clients to use it as well, follow the instructions in Part Two.


  1. Postfix shows the beauty of a well-written Unix module: you have some sensible default settings stored in a plain text configuration file. Customize the setup by changing a few lines and you’re done. And you can store the text file in a revision control system so the settings are never lost.