OpenSMTPD makes mail server configuration easy
Scrutinized
Setting up Sendmail or Postfix is no fun. The code for complex and historically evolved software such as Sendmail is virtually impossible to validate externally and comprehensively for accuracy and security. Even worse, the configuration file is a confusing juggernaut of many hundreds of lines, and each individual option can have various side effects on the behavior and the security of the mail server.
When looking around for a lean and secure alternative, administrators are quickly drawn to OpenSMTPD [1], the mail transfer agent (MTA) from the OpenBSD team. OpenBSD is known for its high security standards. The operating system has had only two remotely exploitable security vulnerabilities in the last two decades, mainly because of strict coding standards, code reviews, and data flow analyses to prevent errors – or at least detect them at an early stage.
OpenSMTPD's project goals [2] comply with the OpenBSD specifications: Security and reliability are at the top of the priority list. The community achieves this through defensive programming, privilege separation, and lean implementation (Figure 1).
Another factor is a configuration file that can be used to solve almost all mail server standard cases in fewer than 10 lines; even complex setups hardly need more effort.
Multiple Flavors
OpenSMTPD is at home not just on its native OpenBSD, but on Linux (with binary packages for Gentoo, Slackware, Debian, and Arch) and other BSDs, including Mac OS X. The package for Ubuntu served as the basis for the following discussion. To install the MTA, enter:
sudo apt-get install opensmtpd
OpenSMTPD also can be loaded onto the system in the classic way:
wget https://www.opensmtpd.org/archives/opensmtpd-portable-latest.tar.gz tar -xzf opensmtpd-portable-latest.tar.gz
After some missing packages are installed using apt-get
, enter
./configure make sudo make install
In a manual installation, the administrator needs to create the _smtpd
and _smtpq
users; otherwise, apt-script
does this with slightly different names (opensmtpd
, opensmtpq
), each with a private user group.
Configuration
The configuration file ends up in an unusual location for OpenBSD (/etc/
rather than /etc/mail/
) when installing via Apt. The default smtpd.conf
is pleasantly surprising: Four lines of instructions are enough for the local configuration to receive and forward email from your computers.
If you want to access the mail server from the outside, you have several possible approaches. The simplest: listen on all
accepts email liberally on all local IP addresses. However, anyone who, for example, wants to use their server while on the road via port 587, with SMTP authentication and TLS, and deal with all normal incoming email on port 25 should configure the server as in Listing 1.
Listing 1
Protected External Accessibility
01 pki post key '/etc/ssl/private/post.example.org' 02 pki mail key '/etc/ssl/private/mail.example.org' 03 table remote db:/etc/smtpd_remote.db 04 listen on 192.0.2.15 inet4 port 25 hostname post.example.org tls pki post 05 listen on 192.0.2.15 inet4 port 587 hostname mail.example.org tls-require pki mail auth <remote> tag remote 06 listen on 127.0.0.1 inet4 port 25 hostname local.example.org 07 limit mta inet4
Lines 1 and 2 set SSL keys for the server: one for authenticating remote users and the other for incoming email. Whether two keys are needed if a second server isn't planned is something you can consider, but the two instructions show how easy it is to include multiple keys. Lines 4 and 5 assign these keys to the respective connections (I use 192.0.2.15
) using the short names post
and mail
.
Line 4 offers TLS as an option, whereas line 5 sets it as mandatory (tls-require
). The individual ports use different hostnames. If you do not want this, you can leave out the hostname
directive. OpenSMTPD then takes on the hostname of the running system. Line 5 also requires that users authenticate. The smtpd_remote.db
file contains valid SMTP users generated from smptd_remote
with:
makemap smtpd_remote
Each line in this file contains the username and the associated encrypted password separated by a tab. Password encryption is handled by the following:
smtpctl encrypt
Email submitted in this way can be identified later and systematically treated using the remote
tag. Line 6 specifies that no TLS is required for mail coming from localhost.
OpenSMTPD supports IPv4 and IPv6; If you would rather restrict the server to IPv4, lines 4-6 do the trick per connection, whereas line 7 enforces IPv4 for the mta.
Passing on Email
Now that everything that needs to be configured has been configured, OpenSMTPD will accept email – and even do so in a construction that is complex by the program's own standards. OpenSMTPD now still has to learn how to process email. Again, you have several approaches available. The smtpd.conf
line
accept for local alias <aliases> deliver to mbox
delivers the email for genuine local users of the Linux system. The aliases.db
file has both an email address and the name of a local user or a recipient email address in the style of Sendmail aliases.
However, if you have several domains set up for individual email addresses, perhaps even with forwarding, you need to tweak some more controls:
accept from any for domain 'example.org' virtual <virtusers> deliver to mbox
Again, virtusers
is designed pretty much like aliases
. However, the resulting usernames do not really need to exist on the system; they can instead be resolved by further rules. Listing 2 shows an example: aliases
resolves the postmasters
if there is no other resolution. The last line shows how you can redirect any missing email addresses to an account. However, a catch-all account like this will attract spam, because spammers love guessing email addresses.
Listing 2
aliases
max.muster@example.org max max@example.org max.muster@example.org mm@example.org max@example.org moritz@example.org moritz@example.net catchall@example.org postmaster @example.org catchall@example.org
Two steps are required to integrate the two user lists: First, you need to convert them to the faster db
format as follows:
makemap -t aliases aliases makemap -t aliases virtusers
Second, you need to integrate the list into smtpd.conf
:
table aliases db:/etc/aliases.db table virtusers db:/etc/virtusers.db
If you have many domains with the same email addresses, you can also store the domain lists in a table and even use wildcards. Listing 3 (domains
) demonstrates this for example.org
, example.net
, example.com
, and all their subdomains. Because you want the same email accounts to exist in all of these domains, the users
file looks simpler:
max max moritz moritz@example.com
Listing 3
domains
example.org *.example.org example.net *.example.net example.com *.example.com
The first line ensures that OpenSMTPD forwards email addressed to max@*.example.*
to local user Max, whereas Moritz's email all goes to moritz@example.com
. The list can be transferred to users.db
and then included in smtpd.conf
using:
makemap -t aliases users table users db:/etc/users.db table domains '/etc/domains' accept from any for domain <domains> virtual <users> deliver to mbox
The last line takes care of the delivery, saving effort for companies that have registered many domains appropriate to their own brands (so that domain grabbers cannot preempt them) yet want email to be accessible under all of these domains. Flexible wildcards like this are not envisaged in Sendmail.
In OpenSMTPD, wildcards work everywhere, although example.* should be treated with caution from a security perspective, taking into account the now countless number of top-level domains.
Buy this article as PDF
(incl. VAT)