Spamfiltering met rspamd

Introductie

Spam is vervelend. Het is onnodige ruis en komt met aanvullende risico’s voor de ontvanger. Denk aan het per ongeluk aanklikken van ongewenste links of bevestigen dat de spam succesvol is aangekomen. Gelukkig zijn er meerdere open source oplossingen om inkomende en uitgaande e-mails te controleren. Een moderne en krachtige oplossing is Rspamd. Veelal als rspamd wordt ingezet, zet de systeembeheerders het aan zonder het te configureren, onder het mom dat het standaard al best goed werkt. Dat is spijtig, want er zoveel meer uit de software te halen.

Heb je al gewerkt met Rspamd? Scroll dan niet meteen door het document, maar lees (nogmaals) de basisconfiguratie. Deze bevat o.a. tips voor een goede structuur en opzet.

Waarom dit artikel?

  • Basisstappen voor installatie
  • Achtergrond over spamdetectie
  • Begrip rondom de minimale configuratie
  • Aanpassen van instellingen op jouw omgeving
  • Minder spam!

Over Rspamd en spamfiltering

Lange tijd was het vooral SpamAssassin dat werd ingezet om spamfiltering te doen. Hoewel deze oplossing ook prima kan werken, kan het relatief veel vragen van het systeem, zeker als er veel e-mail binnen komt. De eerste versie van rspamd is uitgekomen in 2008 en had het doel om een efficiëntere oplossing te bieden. Zo is SpamAssassin geschreven in Perl en gebruikt rspamd de programmeertaal c. Vanaf het eerste moment lag de focus op snelheid en efficiëntie.

Efficiëntie is natuurlijk fijn, maar we willen ook dat onze spamfiltering effectief is. Dat wil zeggen dat ongewenste e-mail als zodanig herkend en gemarkeerd moet worden. Gelijktijdig mar juist legitieme e-mail niet als spam worden gemarkeerd. Spammers doen er alles aan, vaak met zo min mogelijk middelen, om te worden gezien als een legitieme e-mail. Als zij zien dat hun grootschalige spamacties niet meer het gewenste effect hebben, dan wordt er een nieuw plan bedacht. Soms van subtiele wijzigingen in teksten, tot aan het wisselen van systemen en domeinen. Spammers zijn als speedboten en kunnen zich snel bewegen in het water. Wij, of onze mailservers, staan juist stil. Bijsturen kan, maar vergt langdurig goed beheer en het maken van goede afwegingen. We willen immers niet dat legitieme e-mail in de spambox terecht komt.

In de wereld van techniek komen veel termen voor, dus waar relevant worden die meteen toegelicht. We hebben het al gehad over spam, oftewel ongewenste e-mail. Bij spamfiltering noemen we legitieme e-mail ham. Dat is alvast handig om te weten, aangezien we later SPAM en HAM gaan gebruiken om ons systeem slimmer te maken en te trainen met data.

Rspamd en Redis installeren

Voor het gebruik van rspamd dient deze eerst geïnstalleerd te worden. Op de meeste Linux-distributies en BSD’s heet het pakket rspamd. Aanvullend is Redis nodig, of het alternatief Valkey. Voor eenduidigheid in dit artikel zal worden gesproken worden over Redis. Waar nodig vul dit vrijblijvend in als Valkey en bijbehorende commando’s.

De rol van Redis is de opslag van data (zogeheten key-value store), zoals het opslaan van geleerde berichten inclusief spam. Enkele functionaliteiten die alleen mogelijk zijn als Redis is geïnstalleerd zijn:

  • Bayesiaanse classificatie zoals hoe vaak een woord voor is gekomen in legitieme e-mail en spam
  • DMARC-rapportages (aggregate reports)
  • Greylisting om bij te houden welke conversaties al eerder zijn geweest met de server
  • Neuraal netwerk voor opslag gewicht dat een model heeft en status van training
  • Opslaan van antwoorden (replies)

Kortom, Redis is wel een belangrijk onderdeel in de installatie. Begin daarom met het installeren van Rspam en Redis.

Linux-voorbeelden:

  • Debian: apt install rspamd redis-server
  • Alma Linux: dnf install rspamd redis

Zowel op Linux als de BSD’s dienen rspamd en Redis gestart te worden.

  • systemctl enable –now rspamd.service
  • systemctl enable –now redis-server.service
  • rcctl enable rspam redis
  • rcctl start rspam redis

Basisconfiguratie

Paden

De configuratie van rspamd is te vinden in /etc/rspam, verdeeld over meerdere configuratiebestanden. Er zijn een aantal generieke bestanden, aangevuld met een modulaire structuur. Het is zelden een goed idee om deze bestaande bestanden te wijzigen, aangezien de package manager deze wijzigingen ongedaan kan maken. Door de modulaire opzet bouwt rspamd steeds de configuratie aan de hand van de basisstructuur aangevuld met lokale wijzigingen. Zo maakt rspamd gebruik van o.a. overrides (/etc/rspam/override.d), waarmee het een basisconfiguratiebestand in zijn geheel kan vervangen. Ook is er /etc/rspam/local.d, waarmee we aanpassingen kunnen doen gericht op de bestaande modules.

Voor de meeste systemen is het gebruik van overrides niet aan te raden. Het is verstandiger om de basisconfiguratie per module aan te vullen met lokale wijzigingen. In de meeste gevallen betekent dat dus een bestand plaatsen in /etc/rspam/local.d met de naam van de relevante module.

Een rspamd-configuratie bestaat dus uit de volgende zaken:

  • Basisconfiguratiebestanden (rspamd.conf, settings.conf, groups.conf)
  • Overrides uit de directory /etc/rspamd/override.d
  • Lokale aanpassingen voor modules in directory /etc/rspamd/local.d

Hoe de configuratie wordt samengesteld

Rspamd gebruikt de basisconfiguratiebestanden als fundament. Vervolgens zullen de overrides de bestaande onderdelen van de configuratie overschrijven, om uiteindelijk aangevuld te worden met de lokale aanpassingen.

Het is ook goed om te realiseren dat bepaalde instellingen meermaals voor kunnen komen. Ze overschrijven dan niet de waarde, maar vullen hem aan. Een enkelvoudige waarde wordt dan een reeks (array) van waardes.

Configuratie bekijken, testen en uitbreiden

Voordat de configuratie van Rspamd wordt gewijzigd, is het verstandig om een keer goed door structuur heen te lopen. Zo leer je de modules kennen.

Instellen Redis

Afhankelijk van de standaardconfiguratie van Rspamd, kan het nodig zijn om Redis eerst te activeren. Dat kunnen we controleren:

mail# rspamadm configdump redis 
*** Section redis ***
servers = "127.0.0.1";

*** End of section redis ***

In de Redis-configuratie zelf dienen we enkele instellingen aan te passen, die ons later gaat helpen om het geheugenbeheer onder controle te houden. Open /etc/redis/redis.conf en voeg de volgende instellingen toe:

maxmemory 384mb
maxmemory-policy volatile-ttl

De eerste instelling beperkt het geheugen. Voor een kleine tot gemiddelde installatie is 256-512 megabyte vaak voldoende. In dit geval is daarom 384 megabyte gekozen, er tussenin het ongeveer 1/3e van het geheugen van 1 gigabyte. Zo blijft er voldoende over voor de andere diensten op het systeem. Heb je meer geheugen of komt er veel e-mail, dan zou je dit kunnen verhogen.

Met maxmemory-policy geven we aan wat er moet gebeuren als het geheugen vol zit. De waarde volatile-ttl vertelt Redis dat items met een TTL (time-to-live) opgeruimd mogen worden. Hierbij zullen de items die binnenkort gaan verlopen, als eerste het veld ruimen.

Herstart nu Redis, zodat de nieuwe instellingen actief worden.

Controles

  • rspamadm configdump
  • rspamadm configtest

Statistieken

Met behulp van rspamc kunnen we commando’s geven aan Rspamd. Zo kunnen we de statistieken uitlezen:

mail# rspamc stat 
Results for command: stat (0.00106 seconds)
Messages scanned: 225
Messages with action reject: 1, 0.44%
Messages with action soft reject: 0, 0.00%
Messages with action rewrite subject: 0, 0.00%
Messages with action add header: 10, 4.44%
Messages with action greylist: 1, 0.44%
Messages with action no action: 213, 94.67%
Messages treated as spam: 11, 4.89%
Messages treated as ham: 214, 95.11%
Messages learned: 0
Connections count: 20
Control connections count: 7
Average scan time: 0.608 sec
Pools allocated: 76
Pools freed: 49
Bytes allocated: 17615056
Memory chunks allocated: 52
Shared chunks allocated: 2
Chunks freed: 0
Oversized chunks: 2
Statfile: BAYES_SPAM type: redis; length: 0; free blocks: 0; total blocks: 0; free: 0.00%; learned: 0; users: 0; languages: 0
Statfile: BAYES_HAM type: redis; length: 0; free blocks: 0; total blocks: 0; free: 0.00%; learned: 0; users: 0; languages: 0
Total learns: 0

Configuratie

Actions

Rspamd heeft meerdere standaardacties. Deze acties worden bepaald aan de hand van een berekende score. Zowel reject als add_header betekent dat de ingekomen e-mail met grote zekerheid spam is. Bij een reject zal de e-mail worden geweigerd, bij add_header gaat de e-mail wel door, maar met extra informatie. In het laatste geval is deze informatie opgeslagen in de headers van de e-mail zelf, inclusief details.

mail# rspamadm configdump actions
*** Section actions ***
reject = 15;
add_header = 6;
greylist = 4;

*** End of section actions ***

De waarde voor greylist bepaalt dat we de e-mail tijdelijk nog niet accepteren. Hiermee geven we een signaal af en bekijken we de e-mail later alsnog aangeboden krijgen. Dit geeft ook eventuele andere bronnen de tijd om spammers te detecteren.

Advies: verlaag of verhoog niet zomaar de waardes. Het systeem heeft de tijd nodig om te leren en het is altijd beter dat er wat spam doorheen glipt, dan dat we legitieme e-mail onterecht bestempelen als spam. Voorzichtigheid en goede monitoring is essentieel voor het bijsturen van het (gedeeltelijk) zelflerende systeem.

De installatie kan al worden getest nu met behulp van rspamc en een testbericht:

mail# echo -e "Subject: Testbericht vi@gra !! \nFrom:mezelf@example.org\n\nThis is a clean test email." | rspamc   
Results for file: stdin (0.00164 seconds)
[Metric: default]
Action: add header
Spam: true
Score: 12.00 / 15.00
Symbol: ARC_NA (0.00)
Symbol: DMARC_POLICY_REJECT (2.00)[example.org : No valid SPF, No valid DKIM, reject]
Symbol: FROM_NO_DN (0.00)
Symbol: HEADER_FROM_EMPTY_DELIMITER (1.00)
Symbol: HFILTER_HOSTNAME_UNKNOWN (2.50)
Symbol: MIME_GOOD (-0.10)[text/plain]
Symbol: MIME_TRACE (0.00)[0:+]
Symbol: MISSING_DATE (1.00)
Symbol: MISSING_MID (2.50)
Symbol: MISSING_TO (2.00)
Symbol: MISSING_XM_UA (0.00)
Symbol: ONCE_RECEIVED (0.10)
Symbol: RCVD_COUNT_ZERO (0.00)[0]
Symbol: R_DKIM_NA (0.00)
Symbol: R_MISSING_CHARSET (0.50)
Symbol: SINGLE_SHORT_PART (0.00)
Symbol: SUBJECT_ENDS_EXCLAIM (0.00)
Symbol: SUBJECT_ENDS_SPACES (0.50)
Message-ID: undef

In dit geval hebben we een hoge score (12 van 15), voldoende om de grens van 6 te overschrijden, te laag om het te weigeren. Er zal daarom een header (Action: add header) worden toegevoegd aan de e-mail.

Symbols

Binnen Rspamd wordt gebruik gemaakt van symbolen, of symbols in het Engels. Dit is een resultaat met daaraan een score of gewicht gekoppeld (Weight). Bijvoorbeeld de aanwezigheid op een lijst met bekende spammers zal de score verhogen. Een succesvolle reeks aan controles op de aanwezigheid van SPF/DKIM/DMARC-informatie en bijbehorende IP-adres(sen) kan juist de score weer verlagen. In dat geval zal het gewicht dus een negatieve waarde hebben.

We kunnen de aanwezige symbolen opvragen met rspamc counters.

mail# rspamc counters
Results for command: counters (0.0102 seconds)
Symbols cache
 --------------------------------------------------------------------------------- 
| Pri  | Symbol                                | Weight  |   Frequency   |  Hits   |
 --------------------------------------------------------------------------------- 
|      |                                       |         |   hits/min    |         |
 --------------------------------------------------------------------------------- 
| 0    | ABUSE_FROM_INJECTOR                   |   2.0   | 0.000 (0.000) |    0    |
 --------------------------------------------------------------------------------- 
| 1    | ABUSE_SURBL                           |   5.0   | 0.000 (0.000) |    0    |
 --------------------------------------------------------------------------------- 
| 2    | ALIASES_CHECK                         |   0.0   | 0.000 (0.000) |    0    |
 --------------------------------------------------------------------------------- 
| 3    | ALIAS_RESOLVED                        |   0.0   | 0.000 (0.000) |    0    |
 --------------------------------------------------------------------------------- 

Instellingen per symbool

  • description: Een omschrijving van het symbool, wordt o.a. in de webinterface getoond en helpt met het beschrijven wat een symbool doet.
  • group: Symbolen worden gekoppeld aan 1 of meerdere groepen.
  • one-shot: Indien deze op ’true’ staat, zal hij slechts eenmalig meetellen. Bijvoorbeeld een e-mail heeft meerdere links of domeinnamen in het bericht, dan zullen meerdere ‘hits’ gezamenlijk slechts als ‘hit’ worden geteld. Dit helpt om te voorkomen dat een e-mail een enorm hoge score krijgt door slechts 1 of enkele tests. Het is vaak beter om vele factoren samen te laten bepalen of iets spamachtig is en deze instelling helpt met het waardeoordeel.

Voorbeeld: blokkeren aan de hand van de TLD

De TLD (top level domain) is het laatste stukje binnen een domeinnaam, zoals .com of .nl. Sommige TLD’s worden graag ingezet door spammers, aangezien ze hiervoor tijdelijke domeinnamen kunnen gebruiken die plausibel klinken, maar nog niet bezet zijn als een .com-domein.

mail# rspamadm configdump url_suspect
*** Section url_suspect ***
enabled = true;
max_urls = 10000;
process_flags [
    "has_user",
    "numeric",
    "obscured",
    "zw_spaces",
    "no_tld",
]
checks {
    user_password {
        enabled = true;
        length_thresholds {
            suspicious = 64;
            long = 128;
            very_long = 256;
        }
    }
    numeric_ip {
        enabled = true;
        allow_private_ranges = true;
    }
    tld {
        enabled = true;
        builtin_suspicious [
            ".tk",
            ".ml",
            ".ga",
            ".cf",
            ".gq",
        ]
    }
    unicode {
        enabled = true;
        check_validity = true;
        check_homographs = true;
        check_rtl_override = true;
        check_zero_width = true;
    }
    structure {
        enabled = true;
        check_multiple_at = true;
        max_at_signs = 2;
        check_backslash = true;
        check_excessive_dots = true;
        max_host_dots = 6;
        check_length = true;
        max_url_length = 2048;
    }
}

*** End of section url_suspect ***

We kunnen de lijst met verdachte TLD’s uitbreiden, door aanvullende waardes op te geven in het bestand /etc/rspamd/local.d/url_suspect.conf.

checks {
    tld {
        builtin_suspicious [
            ".site",
            ".store",
            ".homes",
            ".delivery",
            ".tech",
            ".coupons",
            ".baby",
            ".cv",
            ".my",
        ]
    }
}

Phishing

rapsmadm configdump phishing

RBL

rspamadm configdump rbl

SPAMHAUS_ZEN_URIBL is uitgeschakeld (enabled staat op ‘false’).

...
    SPAMHAUS_ZEN_URIBL {
        enabled = false;
        rbl = "zen.spamhaus.org";
        checks [
            "emails",
        ]
        resolve_ip = true;
        returncodes {
            URIBL_SBL = "127.0.0.2";
            URIBL_SBL_CSS = "127.0.0.3";
            URIBL_XBL [
                "127.0.0.4",
                "127.0.0.5",
                "127.0.0.6",
                "127.0.0.7",
            ]
            URIBL_PBL [
                "127.0.0.10",
                "127.0.0.11",
            ]
            URIBL_DROP = "127.0.0.9";
        }
    }
...

Fuzzy matching

Om te controleren of fuzzy matching aan staat, bekijk de uitvoer van rspamc stat en dan specifiek de regels die beginnen met Fuzzy hashes.

Fuzzy hashes in storage "rspamd.com": 3300145381
Fuzzy hashes stored: 3300145381

Effectiviteit en monitoring

Status van rspam controleren

mail# rspamc stat
Results for command: stat (0.00629 seconds)
Messages scanned: 216
Messages with action reject: 0, 0.00%
Messages with action soft reject: 0, 0.00%
Messages with action rewrite subject: 0, 0.00%
Messages with action add header: 9, 4.17%
Messages with action greylist: 0, 0.00%
Messages with action no action: 207, 95.83%
Messages treated as spam: 9, 4.17%
Messages treated as ham: 207, 95.83%
Messages learned: 0
Connections count: 14
Control connections count: 0
Average scan time: 0.654 sec
Pools allocated: 59
Pools freed: 32
Bytes allocated: 17612720
Memory chunks allocated: 52
Shared chunks allocated: 2
Chunks freed: 0
Oversized chunks: 2
Statfile: BAYES_SPAM type: redis; length: 0; free blocks: 0; total blocks: 0; free: 0.00%; learned: 0; users: 0; languages: 0
Statfile: BAYES_HAM type: redis; length: 0; free blocks: 0; total blocks: 0; free: 0.00%; learned: 0; users: 0; languages: 0
Total learns: 0

Andere tips

  • Monitoren van het geheugengebruik van Redis

Foutmeldingen

Tijdens het opzetten van Rspamd kan het gebeuren dat bepaalde zaken niet ineens werken. Om probleemoplossing voor anderen gemakkelijker te maken, zijn een aantal foutmeldingen opgeslagen.

rspamd verbinding: connection refused

Jun  1 11:40:11 mail smtpd[18005]: rspamd: failed to receive a response from daemon. err: 'Post "http://localhost:11333/checkv2": dial tcp [::1]:11333: connect: connection refused'

rspamd timeout while connecting the server

2026-06-05 11:18:01 #56989(controller) <xum1zo>; lua; lua_bayes_redis.lua:167: cannot get bayes statistics for BAYES_HAM: timeout while connecting the server (1 sec)

Redis was niet actief. Gebruik rcctl enable redis && rcctl start redis om hem actief te maken en op te starten.

2026-06-27 23:56:06 #85922(normal) <004d42>; task; dkim_module_load_key_format: cannot load dkim key /etc/mail/dkim/private/dkim-example.org.key: cannot stat key file: '/etc/mail/dkim/private/dkim-example.org.key' Permission denied

Rechten te strak, controleer de bestandsrechten.

Bronnen

  • Het rspamd-boek op website
  • Documentatie