Now that we have our basic mail infrastructure working, we will add support for rspamd and enable DKIM signing of our messages.
In this series we will set up a fully-featured mail server in a FreeBSD jail using OpenSMTPd, Dovecot and rspamd. In contrast to many other guides, this one is split into multiple posts that can either be read and followed individually, or as a whole. After each post, you end up with a fully working system (that might lack some features ;)).
Install rspamd and redis
rspamd uses redis for storing information, so we need to install both and enable the services. OpenSMTPd also has a filter module for rspamd, which makes the integration a breeze:
pkg install redis rspamd opensmtpd-filter-rspamd
sysrc redis_enable=YES
sysrc rspamd_enable=YES
service redis start
service rspamd start
Create DKIM keys
For now we will leave the sane defaults for filtering provided by rspamd and go straight to DKIM signing. First, we’ll create the necessary keys:
cd /etc/mail
mkdir dkim
openssl genrsa -out /etc/mail/dkim/example.com.key 1024
openssl rsa -in /etc/mail/dkim/example.com.key -pubout -out /etc/mail/dkim/example.com.pub
Create DKIM DNS record
/etc/mail/dkim/example.com.pub
now stores the public key, which you need to add to your domain’s DNS records. So get the contents of that file between the -----BEGIN PUBLIC KEY-----
and -----END PUBLIC KEY-----
markers and create a record like follows:
mail._domainkey TXT "v=DKIM1;k=rsa;p=your-key-goes-here"
The key stored in the file has line breaks in it, but you can just remove them and append them to make one big string which goes into your DNS record.
Configure rspamd for DKIM signing
Next we need to tell rspamd to sign outgoing mail with the key that we just created. Create the file /usr/local/etc/rspamd/local.d/dkim_signing.conf
(you might need to create the local.d
folder first) and add the following:
domain {
example.com {
path = "/etc/mail/dkim/example.com.key";
selector = "mail";
}
}
The selector basically needs to match the left-hand part of the DNS record key you just created and the path - obviously - the path of the file. Assuming that we created the DKIM key from the jail’s root
user,
we need to change the ownership of the /etc/mail/dkim
folder to rspamd and then restart it:
chown -R rspamd:rspamd /etc/mail/dkim
service rspamd restart
Integrate rspamd with OpenSMTPd
For the integration between rspamd and OpenSMTPd to work, we will utilize opensmtpd-filter-rspamd
. So the only thing we need to do on OpenSMTPd side is to set up a filter and to use it for incoming and outgoing mail.
Open your /usr/local/etc/mail/smtpd.conf
file and add the filter (I put it below my pki setup):
filter rspamd proc-exec "/usr/local/libexec/opensmtpd/opensmtpd-filter-rspamd"
Now, we simply need to use it in all listen
directives, mine look like that (note the filter rspamd
at the end):
# Listen directives: Sockets and their configuration. lo1 is the cloned interface for our jail,
# if this would be standalone, you would need to use the public network interface
#
# We listen for incoming mail. We will make sure that you cannot send outgoing mail without
# authentication in a second
listen on lo1 tls pki mail.example.com auth-optional filter rspamd
# We listen on smtps (= port 465) for outgoing mail, only for authenticated users
listen on lo1 smtps pki mail.example.com auth <passwd> filter rspamd
# We listen on submission (= port 587)
listen on lo1 port submission tls-require pki mail.example.com auth <passwd> filter rspamd
Restart smtpd
and we are good to go:
service smtpd restart
Fix rspamd/redis communication in a jail
When you have a look at /var/log/rspamd/rspamd.log
and scroll back to the moment when rspamd booted, you probably get this error:
2022-06-02 05:14:13 #7518(normal) <tbf5py>; cfg; rspamd_redis_init: cannot init redis backend for BAYES_SPAM
This is because rspamd tries to connect to redis on 127.0.0.1
. As you probably recognized already, that does not work within jails
since it binds to the host system. To make it work, I rebound redis to my jail’s private IP (192.168.0.2
in my case) and let rspamd
connect to this address instead.
In /usr/local/etc/redis.conf
, make sure to have bind 192.168.0.2
instead of bind 127.0.0.1 -::1
and restart redis. Next, we
need to instruct rspamd to connect by that IP. Instead of changing it in /usr/local/etc/rspamd/modules/redis.conf
, we’ll keep it update-safe
and create our own file /usr/local/etc/rspamd/local.d/redis.conf
(you have to create local.d
first). This file only contains:
servers = "192.168.0.2";
After restarting rspamd, the communication should work and the log message should be gone.
Test DKIM integration
Try sending a mail from your mail server to any host and watch /var/log/maillog
and /var/log/rspamd/rspamd.log
to see if it signs the
email or if any errors occur. On the receiving end, check the mail headers for the DKIM signature.
I also verified my DKIM setup on those sites:
Conclusion
Setting up DKIM signing with rspamd is easy and straight forward. Additionally, you will get spam filtering without any extra configuration. Of course, over the time you may want to tweak the rspamd settings for better classification, but it should be okay with the defaults. The problem only is, that you cannot tell rspamd yet how to learn spam or ham (= good mail). We will take care for that in one of our upcoming posts.