Introduction
Postfix, Dovecot, Rspamd, DKIM & ARC — Done Right
Running your own mail server is still one of the most demanding infrastructure tasks. Modern mail delivery is no longer just SMTP — it is a trust pipeline involving SPF, DKIM, DMARC, ARC, reputation systems, content scanning, and strict authentication rules.
In this post we will walk through a clean, reproducible setup of:
- Postfix – SMTP (inbound & outbound)
- Dovecot – IMAP + SMTP authentication
- Rspamd – spam filtering, DKIM & ARC signing
- DKIM & ARC – cryptographic message authentication
All examples are based on Rocky Linux 10, with a focus on security, correctness, and debuggability.
⚠️ All passwords, secrets, and private data are replaced with placeholders such as
REPLACE_WITH_PASSWORDorexample.com.
1. System Preparation
1.1 Base OS Setup
dnf update -y
dnf install -y epel-release
Ensure the system hostname is fully qualified:
hostnamectl set-hostname mail.example.com
Verify:
hostname -f
This must resolve via DNS to your public IP.
1.2 Required DNS Records (Before You Start)
At minimum:
mail.example.com. A <SERVER_IP>
example.com. MX 10 mail.example.com.
Later we will add:
- SPF
- DKIM
- DMARC
- ARC (optional but recommended)
2. Installing Core Services
dnf install -y postfix dovecot dovecot-pigeonhole rspamd
systemctl enable postfix dovecot rspamd
Do not start them yet — configuration first.
3. Postfix Configuration
3.1 Main Configuration
/etc/postfix/main.cf (only relevant parts shown):
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mydestination = localhost
relay_domains =
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP
3.2 TLS Configuration
smtpd_tls_cert_file = /etc/ssl/certs/mail.pem
smtpd_tls_key_file = /etc/ssl/private/mail.key
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_auth_only = yes
⚠️ Common error: wrong permissions on TLS keys
Ensure:
chmod 600 /etc/ssl/private/mail.key
chown root:root /etc/ssl/private/mail.key
3.3 SASL Authentication via Dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
3.4 Rspamd Milter Integration
smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = $smtpd_milters
milter_protocol = 6
milter_default_action = accept
4. Dovecot Configuration
4.1 Mail Location
/etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
4.2 Authentication
/etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = yes
auth_mechanisms = plain login
4.3 Passdb / Userdb
For local users:
passdb {
driver = pam
}
userdb {
driver = passwd
}
4.4 Auth Socket for Postfix
/etc/dovecot/conf.d/10-master.conf
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
5. Rspamd Configuration
5.1 General Notes
Rspamd merges configuration from:
/usr/share/rspamd/(defaults)/etc/rspamd/override.d/(replace)/etc/rspamd/local.d/(extend/override)
Never re-declare module blocks in local.d.
6. DKIM Signing (Rspamd)
6.1 Generate DKIM Key
mkdir -p /var/lib/rspamd/dkim
rspamadm dkim_keygen \
-d example.com \
-s mail \
-k /var/lib/rspamd/dkim/example.com.mail.key
Permissions:
chown _rspamd:_rspamd /var/lib/rspamd/dkim/example.com.mail.key
chmod 400 /var/lib/rspamd/dkim/example.com.mail.key
6.2 DKIM Configuration
/etc/rspamd/local.d/dkim_signing.conf
enabled = true;
selector = "mail";
sign_authenticated = true;
sign_local = true;
domain {
example.com {
path = "/var/lib/rspamd/dkim/example.com.mail.key";
selector = "mail";
}
}
❌ Do NOT wrap this in
dkim_signing {}
This is the #1 DKIM configuration error.
6.3 DNS DKIM Record
mail._domainkey.example.com TXT (
"v=DKIM1; k=rsa; p=PUBLIC_KEY_HERE"
)
7. ARC Signing (Optional but Recommended)
7.1 Generate ARC Key
mkdir -p /var/lib/rspamd/arc
rspamadm dkim_keygen \
-d example.com \
-s arc \
-k /var/lib/rspamd/arc/example.com.arc.key
7.2 ARC Configuration
/etc/rspamd/local.d/arc.conf
enabled = true;
domain = "example.com";
selector = "arc";
path = "/var/lib/rspamd/arc/example.com.arc.key";
⚠️ Missing ARC keys cause log warnings but do not break mail flow.
8. SPF & DMARC
8.1 SPF
example.com TXT "v=spf1 mx -all"
8.2 DMARC
_dmarc.example.com TXT (
"v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1"
)
9. Common Pitfalls (Learned the Hard Way)
❌ Nested DKIM configuration
Cause:
dkim_signing {
dkim_signing {
}
}
Fix:
- Remove the outer block in
local.d
❌ ARC enabled but no key
Symptom:
cannot read key from /var/lib/rspamd/arc/...
Fix:
- Generate key or disable ARC explicitly
❌ TLS key unreadable by Postfix
Fix:
chmod 600
❌ Hostname not matching DNS
Fix:
- Forward & reverse DNS must match
10. Testing & Validation
rspamadm configtest
systemctl start postfix dovecot rspamd
Send a test mail and verify headers:
DKIM-Signature: v=1; ...
ARC-Seal: i=1; ...
Authentication-Results: ...
External checks:
- mail-tester.com
- Gmail “Show original”
Final Summary
Setting up a modern, trustworthy mail server on Rocky Linux 10 is absolutely possible — but only if you treat it as a security system, not a legacy service.
With:
- Postfix handling SMTP correctly
- Dovecot providing secure authentication
- Rspamd acting as the policy engine
- DKIM and ARC cryptographically sealing your reputation
…you end up with a mail server that delivers reliably, passes modern validation, and behaves predictably under load.
Most failures are not software bugs — they are configuration layering mistakes. Once you understand how Postfix, Dovecot, and Rspamd merge responsibility, the entire system becomes surprisingly elegant.
Happy self-hosting ✉️
Views: 4
