OpenSMTPD Building a Mail Server [FAQ Index]


This example will show you how to turn your OpenBSD installation into a full-fledged mail server for medium-sized environments. However, keep in mind that everyone has different requirements and this example makes some very specific assumptions. It only shows a very small subset of what is possible with smtpd(8). The mail server will be doing the following things:

A standard OpenBSD installation as well as a recent installation of OpenSMTPD-extras including: table-passwd and tool-stats is assumed.

The following is not a copy and paste guide. You should know what you are doing and read the man pages.

smtpd Setup

The configuration below is for a medium-size mail server which handles multiple domains with multiple virtual users and is based on several assumptions. One is that a single system user named vmail is used for all virtual users. This user needs to be created:
# useradd -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail
# mkdir /var/vmail
# chown vmail:vmail /var/vmail
Afterwards, the /etc/passwd file will contain an entry like this:
vmail:*:1000:1000:Virtual Mail:/var/vmail:/sbin/nologin
The home directory /var/vmail is used to store virtual users maildir folders, and is entirely managed by the IMAP server (Dovecot). Mail is delivered to Dovecot via LMTP, using the rcpt-to keyword.

The configuration below assumes that virtual users submit mails via the submission port. Virtual users sending mail are authenticated via the /etc/mail/passwd file, which is shared with Dovecot for the IMAP authentication.

The full content of the /etc/mail/smtpd.conf file is shown below:

# pki setup
pki certificate "/etc/ssl/"
pki key "/etc/ssl/private/"

# tables setup
table aliases file:/etc/mail/aliases
table domains file:/etc/mail/domains
table passwd passwd:/etc/mail/passwd
table virtuals file:/etc/mail/virtuals

# listen ports setup
listen on lo0
listen on egress port 25 tls pki
listen on egress port 587 tls-require pki auth <passwd>

# special case for gmail to avoid ipv6 here
#limit mta for domain inet4

# allow local messages
accept from local for local alias <aliases> deliver to lmtp "/var/dovecot/lmtp" rcpt-to
# allow virtual domains
accept from any for domain <domains> virtual <virtuals> deliver to lmtp "/var/dovecot/lmtp" rcpt-to
# allow outgoing mails
accept from local for any relay
Several table(5) directives are specified in the configuration shown above. The aliases table is set up from the /etc/mail/aliases file and contains aliases for local system users. Below the system user john has an alias to the virtual user
vmail:    /dev/null
root:     john
The domains table is set up from the /etc/mail/domains and contains a list of accepted virtual domains:
In addition, table-passwd is used to set up shared authentication for the virtual users between smtpd(8) and Dovecot. The /etc/mail/passwd file contains (at least) the virtual user names and the encrypted passwords:$2b$...encrypted...password...::::::$2b$...encrypted...password...::::::userdb_quota_rule=*:storage=1G
Finally, the actual virtual users setup is in the /etc/mail/virtuals file as shown below:          vmail          vmail
Note that all virtual users which are supposed to receive mail into a maildir folder are mapped to the single system user vmail.

IMAP Server

In this example, Dovecot is used as an IMAP server.
# export PKG_PATH=http://your.local.mirror/pub/OpenBSD/%c/packages/%a
# pkg_add dovecot
# rcctl enable dovecot
Virtual users access and read their mails via IMAP. Dovecot listens on a LMTP socket in /var/dovecot/lmtp for mail delivery from smtpd(8). Passwords are shared with smtpd(8) in the /etc/mail/passwd file and mails are delivered to /var/vmail subfolders. Thus the Dovecot configuration should contain something like the lines below:
passdb {
    args = scheme=blf-crypt /etc/mail/passwd
    driver = passwd-file

userdb {
    args = uid=vmail gid=vmail home=/var/vmail/%d/%n
    driver = static

Bonus: Log Statistics

A simple weekly crontab(5) entry can be set up to parse the mail logs and send statistics, using mail(1) and tool-stats:
/usr/bin/zcat /var/log/maillog.*.gz \
    | /usr/local/bin/tool-stats \
    | /usr/bin/mail -s " smtpd log report" root