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.