Rspamd Advanced Spam Filtering Configuration
Rspamd is a high-performance spam filtering system that combines Bayesian classification, neural networks, DKIM/DMARC verification, and greylisting to protect mail servers from spam. This guide covers advanced Rspamd configuration on Linux including Bayes training, custom rules, Redis integration, and fine-tuning classification.
Prerequisites
- Ubuntu 20.04+/Debian 11+ or CentOS 8+/Rocky Linux 8+
- A running Postfix (or other MTA) already configured
- Redis (required for Bayes and neural network modules)
- Root or sudo access
Rspamd Architecture Overview
Rspamd processes messages through a pipeline of modules:
- Pre-filters: Greylisting, reputation checks, DNSBL
- Filters: Bayes, regex rules, neural network, DKIM/DMARC
- Post-filters: Actions based on score (reject, quarantine, rewrite subject)
Each module adds or subtracts from the message score. Score thresholds determine the action taken.
Installing Rspamd
# Add the Rspamd repository
curl https://rspamd.com/apt-stable/gpg.key | \
gpg --dearmor | sudo tee /usr/share/keyrings/rspamd.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/rspamd.gpg] https://rspamd.com/apt-stable/ \
$(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/rspamd.list
sudo apt update && sudo apt install -y rspamd
# Install Redis
sudo apt install -y redis-server
sudo systemctl enable --now redis-server
# Start Rspamd
sudo systemctl enable --now rspamd
For CentOS/Rocky:
curl -s https://rspamd.com/rpm-stable/centos-8/rspamd.repo | \
sudo tee /etc/yum.repos.d/rspamd.repo
sudo dnf install -y rspamd
Integrate with Postfix:
# Add to /etc/postfix/main.cf
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_default_action = accept'
sudo postconf -e 'milter_protocol = 6'
sudo systemctl reload postfix
Redis Integration
Redis stores Bayes tokens, neural network data, and rate limits:
# Create Rspamd's Redis config
sudo tee /etc/rspamd/local.d/redis.conf << 'EOF'
servers = "127.0.0.1";
password = ""; # Set if Redis requires a password
db = "0";
timeout = 1.5;
EOF
Configure Redis for Rspamd's use patterns:
# /etc/redis/redis.conf - optimize for Rspamd
sudo tee -a /etc/redis/redis.conf << 'EOF'
# Use LRU eviction for Rspamd's working set
maxmemory 256mb
maxmemory-policy allkeys-lru
# Persistence (optional, disable for speed)
# save ""
EOF
sudo systemctl restart redis-server
Bayesian Classifier Setup
The Bayes module learns from spam/ham classifications:
# /etc/rspamd/local.d/classifier-bayes.conf
sudo tee /etc/rspamd/local.d/classifier-bayes.conf << 'EOF'
# Use Redis for storage
backend = "redis";
# Minimum learns before Bayes makes decisions
min_learns = 200;
# Token expiry (90 days)
expire = 7776000;
# Enable per-user learning
per_user = false;
# Learning threshold
spam_threshold = 0.9;
ham_threshold = 0.1;
# Auto-learning (optional - Rspamd can learn from high-confidence results)
autolearn = true;
autolearn_threshold = {
spam = 12.0;
ham = -0.5;
};
EOF
sudo systemctl restart rspamd
Manually train Bayes from a maildir or mbox:
# Train with spam
rspamc learn_spam /path/to/spam/maildir/
# Train with ham (legitimate mail)
rspamc learn_ham /path/to/ham/maildir/
# Train from an mbox file
rspamc learn_spam /path/to/spam.mbox
# Check Bayes statistics
rspamc stat | grep -i bayes
DKIM Verification Configuration
sudo tee /etc/rspamd/local.d/dkim.conf << 'EOF'
# Verify DKIM signatures on incoming mail
check_local = false; # Skip verification for local submissions
check_authenticated = false;
sign_local = false;
sign_authenticated = true;
# DKIM signing configuration (for outgoing mail)
# path = "/var/lib/rspamd/dkim/$domain.$selector.key";
# selector_map = "/etc/rspamd/local.d/dkim_selectors.map";
EOF
Configure DKIM signing for your domain:
# Generate a DKIM key
rspamadm dkim_keygen \
--selector mail \
--domain yourdomain.com \
--bits 2048 \
--privkey /var/lib/rspamd/dkim/yourdomain.com.mail.key
# View the public key for DNS
cat /var/lib/rspamd/dkim/yourdomain.com.mail.pub
sudo tee /etc/rspamd/local.d/dkim_signing.conf << 'EOF'
enabled = true;
use_domain = "header";
sign_local = true;
# Path to private key
# Variables: $domain = sender domain, $selector = DKIM selector
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail";
EOF
sudo systemctl restart rspamd
DMARC and ARC Configuration
sudo tee /etc/rspamd/local.d/dmarc.conf << 'EOF'
enabled = true;
# Actions for DMARC failures
actions = {
quarantine = "add_header"; # or "reject"
reject = "reject";
};
# Send DMARC reports (optional)
reporting {
enabled = true;
email = "[email protected]";
domain = "yourdomain.com";
org_name = "Your Organization";
from_name = "DMARC Reporter";
}
EOF
Enable ARC (Authenticated Received Chain) for forwarded mail:
sudo tee /etc/rspamd/local.d/arc.conf << 'EOF'
enabled = true;
sign_local = true;
use_domain = "header";
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail";
EOF
Greylisting
Greylisting temporarily rejects unknown senders, stopping most spam bots:
sudo tee /etc/rspamd/local.d/greylisting.conf << 'EOF'
enabled = true;
# Time to wait before retry is accepted (30 minutes)
expire = 86400; # 24 hours before greylist expires
timeout = 1800; # 30 minutes initial delay
# Whitelist known good senders
# whitelist_domains_url = "/etc/rspamd/local.d/greylist_whitelist_domains.map";
# Don't greylist authenticated senders
# skip_local = true;
EOF
View greylisting stats:
rspamc stat | grep -i grey
redis-cli keys "rg_*" | wc -l # Count greylisted entries
Neural Network Module
The neural network module learns patterns from classified messages:
sudo tee /etc/rspamd/local.d/neural.conf << 'EOF'
enabled = true;
# Store in Redis
backend = "redis";
# Minimum messages before the network activates
min_learns = 1000;
# Training settings
train {
max_trains = 100;
max_usages = 20;
spam_score = 8.0; # Score threshold to mark as spam for training
ham_score = -2.0;
}
EOF
sudo systemctl restart rspamd
Custom Rules
Add custom Lua rules in /etc/rspamd/local.d/:
sudo tee /etc/rspamd/local.d/custom_rules.lua << 'EOF'
-- Block specific phrases in subjects
local custom_spam_subjects = rspamd_config:register_symbol({
name = 'CUSTOM_SPAM_SUBJECT',
score = 5.0,
group = 'custom',
description = 'Contains known spam phrases in subject',
callback = function(task)
local subject = task:get_header('Subject')
if not subject then return false end
local spam_phrases = {
'make money fast',
'you have won',
'claim your prize',
}
for _, phrase in ipairs(spam_phrases) do
if subject:lower():find(phrase, 1, true) then
return true, 1.0, {phrase}
end
end
return false
end
})
-- Whitelist a trusted domain
rspamd_config:add_condition('DKIM_REJECT', function(task)
local from = task:get_from('mime')
if from and from[1] and from[1].domain == 'trusted-partner.com' then
return false -- Skip DKIM_REJECT for this domain
end
return true
end)
EOF
sudo systemctl restart rspamd
Custom regex rules:
sudo tee /etc/rspamd/local.d/custom_regexp.map << 'EOF'
# Custom body regex rules
/viagra|cialis|levitra/i CUSTOM_PHARMA_SPAM 4.0
/\[urgent\]|\[important\]/i CUSTOM_FAKE_URGENT 1.5
EOF
Rspamd Web Interface
Enable the web UI with a password:
# Generate a password hash
rspamadm pw
# Store the hash in the controller config
sudo tee /etc/rspamd/local.d/worker-controller.inc << 'EOF'
password = "$2$...hashed_password..."; # Replace with output of rspamadm pw
enable_password = "$2$...hashed_admin_password...";
bind_socket = "127.0.0.1:11334";
EOF
sudo systemctl restart rspamd
Access via Nginx reverse proxy:
location /rspamd/ {
proxy_pass http://127.0.0.1:11334/;
proxy_set_header Host $host;
}
Navigate to https://mail.yourdomain.com/rspamd/ and log in with the password set above.
Troubleshooting
Rspamd not receiving messages from Postfix:
# Check milter is listening
ss -tlnp | grep 11332
# Test connection
echo "test" | nc 127.0.0.1 11332
# Check Rspamd logs
journalctl -u rspamd -f
Bayes not classifying:
# Check training counts
rspamc stat | grep -A5 -i bayes
# Need at least 200 spam and 200 ham messages
# Force a test classification
rspamc check /path/to/test.eml
Too many false positives:
# Lower spam threshold temporarily
# In /etc/rspamd/local.d/actions.conf:
# reject = 15; # Increase from default 15
# add_header = 8;
# Check which symbols are triggering
rspamc check /path/to/false-positive.eml | grep -v "^$"
Conclusion
Rspamd's modular design lets you tune spam detection precisely without choosing between false positives and missed spam. The combination of Bayes classification, neural network learning, DKIM/DMARC verification, and greylisting provides defense in depth against all spam types. Regular Bayes training with your actual mail corpus is the single most impactful thing you can do to improve accuracy.


