Install and Integrate Rspamd on Ubuntu 26.04

This is the third part of our Setting up and configuring a mail server . In this tutorial, we will install and configure Rspamd, connect it to Postfix, and create DKIM and DMARC DNS records.
You may ask why we choose to go with Rspamd and not with Spamassassin. Rspamd is more actively maintained and written in C, so it is much faster than Spamassassin which is written in Perl. Another reason is that Rspamd ships a DKIM signing module, so we will not have to use another piece of software to sign our outgoing emails.
If you are not familiar with Rspamd, you can check the official documentation here .
Prerequisites
Before continuing with this tutorial, make sure you are logged in as a user with sudo privileges and that you have completed the first and second parts of the series, where we set up PostfixAdmin, Postfix, and Dovecot.
Install Redis
Redis is used as the storage and caching backend for Rspamd. Install it with:
sudo apt update
sudo apt install -y redis-server
sudo systemctl enable --now redis-serversystemd-resolved already binds port 53) is out of scope for this tutorial.Install Rspamd
Ubuntu 26.04 universe ships a recent stable Rspamd, so we can install it directly from the default repositories:
sudo apt install -y rspamdConfirm the installed version and that the service started:
rspamd --version
systemctl status rspamd --no-pagerresolute suite. Use the modern keyring layout under /etc/apt/keyrings/ rather than the deprecated apt-key.Configure Rspamd
Instead of modifying the stock configuration files, we will create new files under /etc/rspamd/local.d/ which override the default settings.
By default Rspamd’s normal worker (the worker that scans email messages) listens on all interfaces on port 11333. Restrict it to localhost:
bind_socket = "127.0.0.1:11333";The proxy worker listens on port 11332 and supports the milter protocol. Postfix talks to Rspamd through this worker, so we enable milter mode and configure it to scan messages locally:
bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;
upstream "local" {
default = yes;
self_scan = yes;
}Generate an encrypted password for the controller worker, which provides access to the Rspamd web interface:
rspamadm pw --encrypt -p rspamd_controller_passwordThe output should look something like this:
$2$khz7u8nxgggsfay3qta7ousbnmi1skew$zdat4nsm7nd3ctmiigx9kjyo837hcjodn1bob5jaxt7xpkieoctbrspamd_controller_password with a long random password before running the command.Copy the password from your terminal and paste it into the controller configuration file:
password = "$2$khz7u8nxgggsfay3qta7ousbnmi1skew$zdat4nsm7nd3ctmiigx9kjyo837hcjodn1bob5jaxt7xpkieoctb";
bind_socket = "127.0.0.1:11334";Point Rspamd at the local Redis instance:
servers = "127.0.0.1";Set Redis as the backend for the Bayesian classifier:
servers = "127.0.0.1";
backend = "redis";Open the milter_headers.conf file and set the headers Rspamd writes to scanned messages:
use = ["x-spamd-bar", "x-spam-level", "authentication-results"];You can find more information about the milter headers in the Rspamd documentation .
Run a configuration check and restart the Rspamd service for the changes to take effect:
sudo rspamadm configtest
sudo systemctl restart rspamdConfigure Postfix
Configure Postfix to use the Rspamd milter on the proxy worker socket:
sudo postconf -e "smtpd_milters = inet:127.0.0.1:11332"
sudo postconf -e "non_smtpd_milters = inet:127.0.0.1:11332"
sudo postconf -e "milter_protocol = 6"
sudo postconf -e "milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}"
sudo postconf -e "milter_default_action = accept"Restart the Postfix service for the changes to take effect:
sudo systemctl restart postfixSend a test message and confirm Rspamd scanned it:
swaks --to user@linuxize.com --from admin@linuxize.com --server 127.0.0.1
sudo grep -i rspamd /var/log/mail.log | tail -n 10Configure Nginx
In the first part
of this series, we created an Nginx server block for the PostfixAdmin instance. Add a new location block to that server so we can reverse proxy
the Rspamd controller through HTTPS:
...
location /rspamd/ {
proxy_pass http://127.0.0.1:11334/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
...Reload the Nginx service for the changes to take effect:
sudo systemctl reload nginxOpen https://mail.linuxize.com/rspamd/ in your browser, enter the password you generated with rspamadm pw, and you will be presented with the Rspamd web interface.

Create DKIM keys
DomainKeys Identified Mail (DKIM) is an email authentication method which adds a cryptographic signature to outbound message headers. It allows the receiver to verify that an email claiming to originate from a specific domain was indeed authorized by the owner of that domain. The main purpose of this is to prevent forged email messages.
We can have different DKIM keys for each domain we host. The Rspamd DKIM signing module supports a per-domain layout out of the box, so we will use a key path that includes both the domain and the selector. That way you can add more domains later by generating a new key with the same selector.
Create a directory to store the DKIM keys and generate a new keypair using rspamadm:
sudo mkdir -p /var/lib/rspamd/dkim
sudo rspamadm dkim_keygen -b 2048 -s mail -d linuxize.com -k /var/lib/rspamd/dkim/linuxize.com.mail.key > /tmp/linuxize.com.mail.txtIn the example above we are using mail as the DKIM selector. The private key is written to /var/lib/rspamd/dkim/linuxize.com.mail.key, and the public TXT record we will publish in DNS is captured in /tmp/linuxize.com.mail.txt.
Set the correct ownership and permissions so only the Rspamd user can read the private key:
sudo chown -R _rspamd:_rspamd /var/lib/rspamd/dkim
sudo chmod 750 /var/lib/rspamd/dkim
sudo chmod 440 /var/lib/rspamd/dkim/linuxize.com.mail.keyNow tell Rspamd where to look for the DKIM key. The path uses the $domain and $selector variables so the same configuration file works for every domain you add later:
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail";
allow_username_mismatch = true;Run a configuration check and restart Rspamd:
sudo rspamadm configtest
sudo systemctl restart rspamdDNS settings
The DKIM public TXT record was written to /tmp/linuxize.com.mail.txt when we generated the key. The content should look similar to this:
mail._domainkey IN TXT ( "v=DKIM1; k=rsa;"
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqdBRCqYzshc4LmmkxUkCH/rcIpSe..."
"...ZTRe1FlONOzO7ZkQFb7O6ogFepWLsM9tYJ38TFPteqyO3XBjxHzp1AT0UvsPcauDoeHUXgqbxU7udG1t05f6ab5h/Kih+jisgHHF4ZFK3qRtawhWlA9DtS35DlwIDAQAB" ) ;If you are running your own Bind DNS server, copy and paste the record directly into your domain zone file. If you are using a DNS web interface, create a new TXT record with mail._domainkey as the name. For the value, remove the quotes and concatenate the lines together so the record contains a single string starting with v=DKIM1; and ending with the public key.
We will also publish a Domain-based Message Authentication, Reporting, and Conformance (DMARC) record. DMARC tells the receiving server how to treat email that fails SPF or DKIM checks, and it protects your domain against direct spoofing while improving its reputation.
If you followed the series from the beginning, you should already have an SPF record for your domain. To set up a DMARC record, the sending domain needs both an SPF and a DKIM record published. The DMARC policy itself is published as a TXT record:
_dmarc IN TXT "v=DMARC1; p=none; adkim=r; aspf=r;"Let us break down the record:
v=DMARC1is the DMARC version identifier.p=nonetells the receiver to take no action on messages that fail DMARC. You can change this toquarantineorrejectonce you are confident the configuration is correct.adkim=randaspf=rset the DKIM and SPF alignment mode to relaxed. Usesfor strict alignment.
As with the DKIM record, paste the line into your zone file or create a TXT record with _dmarc as the name and v=DMARC1; p=none; adkim=r; aspf=r; as the value.
It may take a while for the DNS changes to propagate. You can check whether the records have propagated using the dig command :
dig mail._domainkey.linuxize.com TXT +short
dig _dmarc.linuxize.com TXT +short"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqdBRCqYzshc4LmmkxUkCH/rcIpSe..."
"v=DMARC1; p=none; adkim=r; aspf=r;"You can also inspect your domain DMARC policy with the DMARC inspector .
Verify DKIM signing
Before you trust outbound mail to be signed, send an authenticated message through port 587 and confirm a DKIM-Signature header appears on the delivered copy:
swaks --to user@linuxize.com --from user@linuxize.com --server mail.linuxize.com --port 587 --auth LOGIN --auth-user user@linuxize.com --auth-password 'MAILBOX_PASSWORD' --tlsFind the most recent message in the user Maildir and inspect its headers:
LATEST=$(sudo find /var/mail/vmail -type f \( -path '*/new/*' -o -path '*/cur/*' \) -printf '%T@ %p\n' | sort -nr | head -1 | awk '{print $2}')
sudo grep -E '^(DKIM-Signature|Authentication-Results|ARC-)' "$LATEST"You should see a DKIM-Signature: v=1; a=rsa-sha256; ... d=linuxize.com; s=mail; ... line. If the header is missing, check the path in dkim_signing.conf against the file name on disk and confirm the key is readable by _rspamd.
Troubleshooting
Rspamd web login fails
Confirm that the hash in /etc/rspamd/local.d/worker-controller.inc came from the same plain text password you are entering in the browser. Then restart Rspamd and reload Nginx:
sudo rspamadm configtest
sudo systemctl restart rspamd
sudo systemctl reload nginxPostfix messages are not scanned
Check that Postfix points to the proxy worker on port 11332, then send a local test message and inspect the mail log:
postconf smtpd_milters non_smtpd_milters
swaks --to user@linuxize.com --from admin@linuxize.com --server 127.0.0.1
sudo grep -i rspamd /var/log/mail.log | tail -n 20DKIM-Signature is missing
Verify that the private key name matches the $domain.$selector.key pattern from dkim_signing.conf, and that the _rspamd user can read it:
sudo ls -l /var/lib/rspamd/dkim/
sudo -u _rspamd test -r /var/lib/rspamd/dkim/linuxize.com.mail.keyConclusion
You have installed Rspamd, integrated it with Postfix as a milter, configured per-domain DKIM signing, and published the DKIM and DMARC TXT records. In the next part of this series, we will continue with Roundcube installation and configuration .
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page