Mastodon Mastodon Mastodon Systeemkabouter blog – Enabling proper mail for runbsd.eu (OpenBSD + Postfix + Dovecot + OpenDKIM)

Enabling proper mail for runbsd.eu (OpenBSD + Postfix + Dovecot + OpenDKIM)

Posted on zo 16 november 2025 in runbsd

On the list of things that should work on OpenBSD in my runbsd.eu project, e-mail is somewhere on the top. This is where the project helps to do stuff on OpenBSD. Because for normal use, I outsourced most of the e-mail server tasks to Soverin. And that works fine.

But the idea for the RunBSD hobby project is to run as much as possible on BSD. Using some unknown mailplatform would not be a good fit.

So I'm going to host the mail on my OpenBSD.Amsterdam virtual machine. The VM is now renamed to petpuffy.runbsd.eu, to fit in to the new project nicely. This virtual server, for most part, only serves this static website up till now. So handling a couple of e-mails should pose no issue at all.

Toolchain

This setup will consist of OpenBSD running Postfix, Dovecot and opendkim.

I already received feedback on the choice for postfix. Maybe in the future I will try the OpenBSD native mailer OpenSMTPD instead :-)

Cleaning up my own mess

As I started working on the VM, there already was an installation of postfix. Apparently past self had started installing postfix on the machine, got distracted and left it at that. So I found out the host has been trying to deliver over 700 system messages, but all was pretty much broken.

Before starting to fix stuff, I made sure the complete set of mails in the postfix queue got permanently deleted.

Getting postfix back to work

With the queue cleaned up, I started looking at errors in the logging and applying fixes for these errors. Soon enough the postfix install was somewhat in a usable state. Mails got go in and out and were being delivered.

Configuring Dovecot

The dovecot package was also already installed, but in a misconfigured state. So that took some trial and error to get on its feet again. But it worked out

Internet.nl testing

This is where de loop starting of testing the mailserver config with Internet.nl, applying fixes and re-running the tests. There were al sorts of things missing and/or misconfigured. This Internet.nl tool is so darn useful!

The end result:

Internet.nl 100% score :-)

(link to report)

Postfix /etc/postfix/main.cf

The settings and relevant context came trom a whole list of sites, I will list most of them at the bottom.

main.cf with commented lines removed:

smtpd_banner =  ESMTP 
biff = no
append_dot_mydomain = no
compatibility_level = 3.8

queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
data_directory = /var/postfix

home_mailbox = Maildir/

sendmail_path = /usr/local/sbin/sendmail
newaliases_path = /usr/local/sbin/newaliases
mailq_path = /usr/local/sbin/mailq

html_directory = /usr/local/share/doc/postfix/html
manpage_directory = /usr/local/man
sample_directory = /etc/postfix
readme_directory = /usr/local/share/doc/postfix/readme
shlib_directory = no
meta_directory = /etc/postfix

smtpd_tls_cert_file=/etc/ssl/runbsd_eu-tls.crt
smtpd_tls_key_file=/etc/ssl/private/runbsd_eu-tls.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:/smtpd_scache
smtp_tls_session_cache_database = btree:/smtp_scache

smtpd_tls_protocols = TLSv1.3, !TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = TLSv1.3, !TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_ciphers =  high
smtpd_tls_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, eNULL, MD5,EXPORT,DES,RC4,CAMELLIA256-SHA,ECDHE-ECDSA-DES-CBC3-SHA,ECDHE-RSA-DES-CBC3-SHA,DHE-RSA-DES-CBC3-SHA,AES256-GCM-SHA384,AES128-GCM-SHA256,AES256-SHA256,AES256-SHA,AES128-SHA256,AES128-SHA,DES-CBC3-SHA,ADH-AES256-GCM-SHA384
smtp_tls_exclude_ciphers = aNULL, eNULL, MD5,EXPORT,DES,RC4,CAMELLIA256-SHA,ECDHE-ECDSA-DES-CBC3-SHA,ECDHE-RSA-DES-CBC3-SHA,DHE-RSA-DES-CBC3-SHA,AES256-GCM-SHA384,AES128-GCM-SHA256,AES256-SHA256,AES256-SHA,AES128-SHA256,AES128-SHA,DES-CBC3-SHA,ADH-AES256-GCM-SHA384
smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL, MD5,EXPORT,DES,RC4,CAMELLIA256-SHA,ECDHE-ECDSA-DES-CBC3-SHA,ECDHE-RSA-DES-CBC3-SHA,DHE-RSA-DES-CBC3-SHA,AES256-GCM-SHA384,AES128-GCM-SHA256,AES256-SHA256,AES256-SHA,AES128-SHA256,AES128-SHA,DES-CBC3-SHA,ADH-AES256-GCM-SHA384
smtpd_tls_mandatory_protocols = TLSv1.3, !TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_protocols = TLSv1.3, !TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high

tls_preempt_cipherlist = yes
smtpd_tls_eecdh_grade = ultra
smtpd_tls_dh1024_param_file = /etc/postfix/dh4096.pem

smtpd_tls_loglevel = 1
smtp_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:/var/postfix/smtpd_tls_session_cache
smtp_tls_session_cache_database = btree:/var/postfix/smtp_tls_session_cache

smtpd_client_connection_rate_limit = 50
smtpd_client_message_rate_limit = 100
anvil_rate_time_unit = 60s

smtp_tls_note_starttls_offer = yes

mail_owner = _postfix
setgid_group = _postdrop

canonical_maps = hash:/etc/postfix/canonical

smtpd_helo_required = yes
smtpd_helo_restrictions =
 permit_mynetworks,
 reject_invalid_helo_hostname,
 reject_non_fqdn_helo_hostname

smtpd_sender_restrictions =
 permit_mynetworks,
 reject_non_fqdn_sender,
 reject_unknown_sender_domain,
 reject_unauth_pipelining

smtpd_recipient_restrictions =
 permit_mynetworks,
 reject_unauth_destination,
 reject_non_fqdn_recipient,
 reject_unknown_recipient_domain

smtpd_relay_restrictions = permit_mynetworks defer_unauth_destination
myhostname = petpuffy.runbsd.eu
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
mydestination = runbsd.eu, localhost

unknown_local_recipient_reject_code = 550

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

smtp_tls_wrappermode = no
smtp_tls_security_level = encrypt

smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters 
milter_default_action = accept 

DNS changes

To fix certain Internet.nl tests, I set up CAA, DKIM, DANE and TLSA records

CAA / SPF records

TLSA record

Dovecot changes

Dovecot was configured to use the common TLS key/cert and configured to work as submission proxy. The users in this particular setup are actual local users, so no virtual accounts are used. Both postfix and Dovecot were configured to expect to find mail for a user in its own homedir ~/Maildir. Pretty oldskool but perfectly simple for this scenario.

In /etc/dovecot/dovecot.conf:

protocols = imap lmtp submission

(no need for pop3 support)

In /etc/dovecot/conf.d/20-submission.conf:

submission_relay_host = 127.0.0.1

In /etc/dovecot/conf.d/10-auth.conf:

auth_mechanisms = plain login

!include auth-system.conf.ext

In /etc/dovecot/conf.d/10-mail.conf:

mail_location = maildir:~/Maildir

In /etc/dovecot/conf.d/10-ssl.conf:

ssl = required

ssl_cert = </etc/ssl/runbsd_eu-tls.crt
ssl_key = </etc/ssl/private/runbsd_eu-tls.key

Creating Maildir

To create maildirs I tried maildirmake, but it was not installed. It appears to be part of the courier-imap package. So I installed this package without using/enabling the courier-imap services.

cd ~eelco
maildirmake Maildir 
chown -R eelco Maildir/

OpenDKIM configuration

Opendkim was installed using pkg_add opendkim

The opendkim.conf was changed as follows:

bash-5.3# grep -v ^# /etc/opendkim.conf | grep -v ^$ 
AuthservID      runbsd.eu
Domain          example.com
KeyTable        /etc/opendkim/KeyTable
Selector        my-selector-name
SigningTable /etc/opendkim/SigningTable
Socket          inet:8891@localhost
Syslog          Yes
Domain runbsd.eu 

Then I created the /etc/opendkim directory and created various files:

/etc/opendkim/KeyTable:

default._domainkey.runbsd.eu runbsd.eu:default:/etc/opendkim/runbsd.eu/default.private

/etc/opendkim/SigningTable:

*@runbsd.eu default._domainkey.runbsd.eu

Then a key was generated and the permissions were fixed:

opendkim-genkey -b 1024 -d runbsd.eu -D /etc/opendkim/runbsd.eu -s default -v
chown -R _opendkim:_opendkim /etc/opendkim/runbsd.eu/

lastly the service was enabled and started:

rcctl enable opendkim
rcctl start opendkim

Getting DANE / TLSA right

Ok this was somewhat of a hassle to get right. I had no real experience setting this up, so ik took some time to find proper tools and examples. These are listed below, but the Bovenender.de blogpost on the subject was the most useful starting point for me.

The TransIP webinterface is not the best tool for this job, but it works:

TransIP dns settings screenshot

Acknowledgements

This would have been a lot more work without the various bits and pieces I found on the Internet. First and foremost, I love the Internet.nl test tooling for both websites and mailservers. It provides great feedback. Internet.nl

Then in order of my open tabs: