Learn OpenBSD - OpenSMTPD & Mail Services
Episode 17 of 23

Learn OpenBSD - OpenSMTPD & Mail Services

Building an email service with OpenSMTPD, OpenBSD's native mail server: arranging /etc/mail/smtpd.conf, choosing between maildir and mbox, configuring relay and virtual users, securing with STARTTLS, and considering DKIM and SPF for deliverability.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 16 you built a web frontend with relayd. Now we run a service older than the web itself: email. And on OpenBSD, email means OpenSMTPD — a lightweight, secure, and very easy-to-configure native mail server.

Email is a complex and often misunderstood protocol: sending (SMTP), receiving (SMTP + POP/IMAP), authentication, and anti-spam. OpenSMTPD handles the SMTP side elegantly, while applying the OpenBSD principles you already know: secure by default, minimal configuration, and pledge/unveil.

Enabling OpenSMTPD

Enabling smtpd
rcctl enable smtpd
rcctl start smtpd
rcctl status smtpd

The configuration is at /etc/mail/smtpd.conf. After changing it, validate and reload:

Validating the smtpd configuration
smtpd -n
rcctl reload smtpd

Anatomy of smtpd.conf

The smtpd.conf structure consists of listen (receiving mail) and action/match (determining the treatment):

/etc/mail/smtpd.conf - basic
listen on egress
action "local" mbox alias <aliases>
match from any for domain example.com action "local"
  • listen on egress receives mail on all interfaces.
  • action "local" mbox stores mail as mbox in the local user's mailbox.
  • match ... for domain example.com directs mail for that domain to the local action.

Maildir vs mbox

OpenSMTPD supports two storage formats:

FormatDescriptionBest for
mboxOne file per user (/var/mail/user)Simple, the default
maildircur/, new/, tmp/ directories per userMore reliable for many-client access

For maildir, the action is written:

/etc/mail/smtpd.conf - maildir
action "local" maildir "/home/%{user}/Maildir" alias <aliases>

The maildir advantage: no file locking, more resistant to crashes. Many administrators choose maildir for servers with many users.

Relay: Sending Mail Outbound

To send email (not just receive), define a relay action:

/etc/mail/smtpd.conf - relay
action "outbound" relay
match from any mail-from any for any action "outbound"

The match ... relay line forwards mail to the internet. For authentication to an external relay (for example an SMTP provider), use:

/etc/mail/smtpd.conf - relay with auth
action "relay" relay host smtp://mail.example.com:587 auth <secrets>

The authentication details are stored in a separate file (/etc/mail/secrets) read by OpenSMTPD — never put passwords in smtpd.conf.

Virtual Users

To serve many domains/users without system accounts, use virtual users. The database can be a text file or a database:

/etc/mail/smtpd.conf - virtual users
table aliases db:/etc/mail/aliases.db
table virtuals db:/etc/mail/virtuals.db
 
action "vmail" maildir "/var/vmail/%{dest.domain}/%{dest.user}" virtual <virtuals>
match from any for any action "vmail"

virtuals.db contains the mapping of addresses to virtual users. All virtual mail is stored in /var/vmail, separate from system accounts — the standard way to host mail.

Warning

Database files for tables (for example aliases.db and virtuals.db) must be generated from the source text file with makemap. If you edit the text file directly without makemap, the changes won't be seen by smtpd.

Securing with STARTTLS

Encrypted mail requires STARTTLS. Using the certificates from episode 10:

/etc/mail/smtpd.conf - STARTTLS
listen on egress tls pki example.com

This configuration encrypts SMTP traffic. Certificates are managed with acme-client as usual, with rcctl reload smtpd after renewal.

DKIM and SPF: Deliverability

Email that doesn't use DKIM/SPF will land in spam. Two mechanisms you need to understand:

  • SPF: a DNS record stating which servers are allowed to send mail on behalf of your domain. Added as a TXT record in DNS.
  • DKIM: a cryptographic signature on mail. OpenBSD provides dkimproxy as a package to sign outbound mail.

Install and enable dkimproxy:

Setting up DKIM
pkg_add dkimproxy
rcctl enable dkimproxy_out
rcctl start dkimproxy_out

Then point smtpd through the proxy:

/etc/mail/smtpd.conf - DKIM
action "outbound" relay host smtp://127.0.0.1:10027

DKIM works as an SMTP filter: outbound mail passes through dkimproxy, which signs it, then it's forwarded. SPF is just a matter of adding a TXT record to your DNS zone.

Monitoring OpenSMTPD

Mail is a system that must be constantly watched:

Monitoring smtpd
rcctl status smtpd
tail -f /var/log/maillog
smtpctl show queue
smtpctl show sessions

/var/log/maillog records every mail transaction. smtpctl show queue shows the waiting queue — if it's long, there's a delivery problem. smtpctl show sessions shows active connections.

Info

Before going live in production, test your mail from an external service and check maillog for relay or TLS errors. Emails that fail to send pile up in the queue — and a bloated queue is the first sign of a problem.

Closing

In episode 17 you built an email service with OpenSMTPD: enabling smtpd, arranging /etc/mail/smtpd.conf, choosing between maildir and mbox, configuring relay and virtual users, securing with STARTTLS, and handling DKIM, SPF, and monitoring.

Key takeaways:

  • listen and action/match are the heart of smtpd.conf.
  • Maildir is more reliable for multi-client; mbox is the simple default.
  • Virtual users separate mail from system accounts; databases are created with makemap.
  • DKIM (dkimproxy) and SPF (DNS TXT) are the keys to deliverability.

In the next episode, episode 18, we'll run virtualization with vmm and vmd — OpenBSD's built-in type 1 hypervisor, managing VMs with vmctl, building tap-based networking, and taking snapshots for testing environments.