Rspamd Architecture#
How rspamd provides spam filtering, DKIM signing, and content analysis in the Mailu mail flow.
Role in Mail Flow#
Rspamd integrates with Postfix via the milter protocol. Every incoming and outgoing message passes through rspamd for analysis before delivery.
sequenceDiagram
participant S as Sending MTA
participant P as Postfix
participant R as rspamd
participant U as Unbound DNS
participant D as Dovecot
S->>P: SMTP delivery (port 25)
P->>R: milter check (port 11332)
R->>U: RBL/SPF/DKIM DNS queries
U-->>R: DNS responses
R-->>P: accept / reject / greylist
P->>D: LMTP delivery (port 2525)
Spam Detection Layers#
Rspamd uses multiple detection methods in parallel:
1. DNS-Based Blocklists (RBLs)#
RBL providers maintain lists of known spam-sending IP addresses and domains. Rspamd queries these via DNS. A positive response (e.g. 127.0.0.2 from Spamhaus) adds score to the message.
Configured RBLs:
Spamhaus ZEN (SBL + XBL + PBL)
Spamhaus DBL (domain-based)
Barracuda RBL
Spamcop
2. Bayesian Classification#
Statistical analysis of message content. Rspamd learns from previous spam and ham (legitimate mail) to classify new messages.
Auto-learning: Messages above spam threshold are automatically learned as spam, below ham threshold as ham
Storage: Bayes database persisted in
/var/lib/rspamdPVC
3. Fuzzy Hashing#
Compares message content hashes against databases of known spam:
Local fuzzy storage: Learns from locally identified spam (port 11333)
Remote fuzzy servers: rspamd.com maintains a global fuzzy database with known spam hashes
4. Protocol Checks#
SPF: Sender Policy Framework verification
DKIM: DomainKeys Identified Mail signature verification
DMARC: Domain-based Message Authentication policy enforcement
ARC: Authenticated Received Chain for forwarded messages
5. Scoring System#
Each check adds or subtracts from a message score. Actions are taken based on thresholds:
Threshold |
Score |
Action |
|---|---|---|
Greylist |
>= 3 |
Temporary rejection (legitimate servers retry) |
Add Header |
>= 5 |
Mark as spam via X-Spam header |
Reject |
>= 12 |
Permanent rejection |
Unbound DNS Sidecar#
RBL providers like Spamhaus block queries from public DNS resolvers (Cloudflare, Google) because they anonymize the query source and prevent rate limiting.
The solution is a dedicated recursive DNS resolver (Unbound) running as a sidecar container in the rspamd pod:
graph TB
subgraph "rspamd Pod"
R[rspamd container<br/>port 11332-11334]
U[Unbound container<br/>port 53]
R -->|DNS queries<br/>127.0.0.1:53| U
end
U -->|recursive queries| RBL[RBL Providers<br/>Spamhaus, Barracuda, etc.]
U -->|forward .cluster.local| KD[kube-dns<br/>10.43.0.10]
Key Unbound configuration:
Recursive resolution: Queries go directly to authoritative DNS servers, not public resolvers
Kubernetes integration:
.cluster.localqueries forwarded to kube-dns for service discoveryRBL compatibility:
private-domainsettings allow 127.0.0.x responses from RBL zonesRebind exemption for cluster.local: the base image’s
private-address 10.0.0.0/8rebind protection would strip Service ClusterIPs from answers;private-domain: "cluster.local."exempts them so rspamd can reach the admin DKIM vaultQNAME minimization disabled: Required by Spamhaus for correct query handling
Storage Architecture#
Rspamd persists learned data in a 5Gi PVC:
Bayes database: Statistical model trained on spam/ham samples
Fuzzy hashes: Local fuzzy hash database
Statistics: Historical processing data
This data survives pod restarts and is critical for maintaining spam detection accuracy over time.
Web Interface#
Rspamd provides an HTTP API and web UI on port 11334 for:
Viewing message processing history
Checking symbol scores and triggered rules
Monitoring throughput statistics
Manual spam/ham learning
Access is protected by Traefik ForwardAuth middleware (Mailu admin authentication).
See Also#
Configure Spam Filtering - Setup guide for spam filter improvements
Component Specifications - Rspamd ports and resources