OpenBSD - Mail Server
23/06/24 09:12
The utopian view we had of the Internet in the '90s - as a free, open, and democratic playground where information could be freely published by anyone - faces many challenges today. For the dream to stay alive, it must remain possible and practical for an individual to host their own web and mail servers.
Since web serving is trivial on OpenBSD using the built in httpd, there's little point documenting my configuration here. Although I will acknowledge that the rise of Let's Encrypt and similar services has made web self-hosting much more accessible.
When choosing to host your own mail you must face one stark reality - you might lose mail. In fact this is the reason I abandoned self-hosting in the past - it's all fun and games until you're waiting to hear back about a job application! With that in mind I decided to start with a domain which I semi-abandoned years ago: swproductions.co.uk.
In the past I have used sendmail or Postfix, but the dream is always to use the base tools provided by OpenBSD since they are secure, simple, and well integrated. With that in mind, I use OpenSMTPD.
For me the basic configuration is very straightforward since I won't have any virtual users - I just need to deliver mail to a single local account:
# configure TLS
pki "mail" key "/etc/ssl/private/home.kovkins.uk.key"
pki "mail" cert "/etc/ssl/home.kovkins.uk.fullchain.pem"
table aliases file:/etc/mail/aliases
# this is the default anyway
listen on socket
# listen on all interfaces port 25 with tls
listen on em0 tls pki "mail"
listen on lo tls pki "mail"
action "local_mail" maildir "%{user.directory}/.mail" alias
match from any for domain "swproductions.co.uk" action "local_mail"
# Needed to allow local routing of eg. root@home.kovkins.uk
match from local for local action "local_mail"
The configuration sets up pki settings, declares an alias table, and sets which interfaces to listen on. Then there are actions and matches. Actions declare what to do with a mail, and matches select which mails should be handled with which actions.
The complication came when I wanted to add two virtual users on another domain for whom mail would be forwarded to a Gmail address:
# Rotate every ~6 months
srs key "fx6o4WsA1AFoD2X2yzURsnNYRx1EvAjal6yFxT8C"
# When rotating, replace backup with the old key above.
srs key backup "sLXTf6CAEe7LwilX6D4C8Q6Mu7o4Hl8Jmtfz42x5"
table addresses { user1@jenkins.je, user2@jenkins.je }
table forwards { user1=address1@gmail.com, user2=address2@gmail.com }
action "relay" relay srs
action "aliasedrelay" forward-only virtual
# apply forwarding
match from any for rcpt-to action "aliasedrelay"
match from local for any action "relay"
Of course, now it seems remarkably straightforward, but a missing "from any" sent me down a rabbit hole which led me to briefly believe what I wanted to achieve wasn't possible.
Since web serving is trivial on OpenBSD using the built in httpd, there's little point documenting my configuration here. Although I will acknowledge that the rise of Let's Encrypt and similar services has made web self-hosting much more accessible.
When choosing to host your own mail you must face one stark reality - you might lose mail. In fact this is the reason I abandoned self-hosting in the past - it's all fun and games until you're waiting to hear back about a job application! With that in mind I decided to start with a domain which I semi-abandoned years ago: swproductions.co.uk.
In the past I have used sendmail or Postfix, but the dream is always to use the base tools provided by OpenBSD since they are secure, simple, and well integrated. With that in mind, I use OpenSMTPD.
For me the basic configuration is very straightforward since I won't have any virtual users - I just need to deliver mail to a single local account:
# configure TLS
pki "mail" key "/etc/ssl/private/home.kovkins.uk.key"
pki "mail" cert "/etc/ssl/home.kovkins.uk.fullchain.pem"
table aliases file:/etc/mail/aliases
# this is the default anyway
listen on socket
# listen on all interfaces port 25 with tls
listen on em0 tls pki "mail"
listen on lo tls pki "mail"
action "local_mail" maildir "%{user.directory}/.mail" alias
match from any for domain "swproductions.co.uk" action "local_mail"
# Needed to allow local routing of eg. root@home.kovkins.uk
match from local for local action "local_mail"
The configuration sets up pki settings, declares an alias table, and sets which interfaces to listen on. Then there are actions and matches. Actions declare what to do with a mail, and matches select which mails should be handled with which actions.
The complication came when I wanted to add two virtual users on another domain for whom mail would be forwarded to a Gmail address:
# Rotate every ~6 months
srs key "fx6o4WsA1AFoD2X2yzURsnNYRx1EvAjal6yFxT8C"
# When rotating, replace backup with the old key above.
srs key backup "sLXTf6CAEe7LwilX6D4C8Q6Mu7o4Hl8Jmtfz42x5"
table addresses { user1@jenkins.je, user2@jenkins.je }
table forwards { user1=address1@gmail.com, user2=address2@gmail.com }
action "relay" relay srs
action "aliasedrelay" forward-only virtual
# apply forwarding
match from any for rcpt-to
match from local for any action "relay"
Of course, now it seems remarkably straightforward, but a missing "from any" sent me down a rabbit hole which led me to briefly believe what I wanted to achieve wasn't possible.