Al geruime tijd gebruik ik een Bayesian-filter om e-mail te beoordelen of het ham of spam is, maar wat is de stand nu na enkele maanden? Gelukkig loopt rrdtool mee te bepalen wat de vullingsgraad van de database is. Op de maandgrafiek lijkt niet echt mis en dat terwijl het langzaam lijkt af te nemen.
Als we naar de jaargrafiek kijken dan ziet het er iets heftiger uit, maar na de eerste dip in mei is de database aangepast om nog maar 500.000 tokens te bewaren maximaal. Dit omdat het verschil tussen de top en de bodem te groot was. Deze nieuwe top is dan ook zeker te zien bij de twee pieken erna, maar hierna lijkt de database zoveel spreiding in tokens van verschillende data te hebben dat er eens stabiele vullingsgraad komt.
Als we naar de huidige afname kijken dan zou die nooit onder de 375.000 moeten komen, want dat is de magische grens van 75 procent van 500.000 die in de database zou moeten blijven zitten bij een opschoning. Mocht dat wel gebeuren dan komen er niet snel genoeg verse tokens bij, maar dat zal duidelijk moeten worden in de komende maanden. Voorlopig lijkt de stroom van spam en ham berichten stabiel genoeg om dit voor elkaar te krijgen, maar het is even afwachten.
Nu SpamAssassin op automatische piloot staat en op versie 3.3 zit werd het tijd voor grafiekjes. Zeker om het gedrag te kunnen monitoren en een van de eerste onderdelen is was het Bayesian-filter. Met wat Perl-code en rrdtool kom je al redelijk vlot tot grafiekjes en hoef je alleen nog maar tijd te hebben.
Gelukkig hebben de grafiekjes voldoende tijd gehad, want recentelijk besloot de software dat de maximale vulgraad was bereikt en werd er opgeschoond, maar of dit nu geheel wenselijk was. Met bayes_expiry_max_db_size verhoogt naar 1.000.000 tokens zou de database even vooruit moeten en de performance bleek ook goed te zijn, maar waarom dan die grote afname in tokens? Zeker omdat het doel is om 75% van bayes_expiry_max_db_size te behouden of minimaal 100.000 tokens.


Een ander onderdeel van de expire is de leeftijd van de tokens en hoe vaak er een daadwerkelijke expire wordt uitgevoerd. Hieruit vallen twee dingen te herleiden. De daadwerkelijke opruimactie op de database wordt niet vaak genoeg getriggerd en hiervoor moet of de omvang van de database omlaag of moeten we sneller nieuwe tokens de database in. Een tweede wat te herleiden is dat er wel genoeg nieuwe tokens de database inkomen om oudere tokens op te ruimen.
Wat de oplossing gaat zijn ben ik nog niet geheel uit, maar wat wel interessant is om te zien of er een relatie is tussen de vulgraad van de database en de scores die worden uitgedeeld. Een ander feit is of de extra spam van week 10 invloed heeft gehad, maar dit zal moeten blijken met de volgende iteratie. Het is dus nog even wachten of dit eenmalig was of niet, want voorlopig blijkt het Bayesian-filter wel goed te werken.
Elk bestand en database moet op tape worden gezet is het motto bij veel sysadmins, maar is dat wel zo. En in veel gevallen hebben ze gelijk, maar helaas niet als het een database betreft die wordt gebruikt voor Bayesian-filtering. Maar waarom maak je backups? Om data die waarde heeft veilig te stellen is eigenlijk de stelregel.
Maar wat maakt Bayesian-filtering nu zo anders? Laten we eens kijken op een testnode.
$ sudo sa-learn --dump magic
0.000 0 3 0 non-token data: bayes db version
0.000 0 25556 0 non-token data: nspam
0.000 0 11331 0 non-token data: nham
0.000 0 204764 0 non-token data: ntokens
0.000 0 1262669327 0 non-token data: oldest atime
0.000 0 1263329413 0 non-token data: newest atime
0.000 0 0 0 non-token data: last journal sync atime
0.000 0 1263273928 0 non-token data: last expiry atime
0.000 0 345600 0 non-token data: last expire atime delta
0.000 0 21267 0 non-token data: last expire reduction count
Wat we zien is dat de database is gevuld met z’n dikke 25000 spamberichten en 11000 hamberichten, maar ook dat de database ruim 204000 kenmerken bevat om zijn berekeningen op laten plaats vinden. Twee leuke kenmerken van dit overzicht zijn dat er een data in de journal zit omdat dit direct in echte database zit ipv in de standaard BerkelyDB en de tweede is de hoeveelheid tokens. In een standaard database zitten maximaal 150000 tokens en welke bij een expire automatisch worden opgeschoond naar 75% van die 150000 tokens. Deze installatie heeft auto-expire uitstaan waardoor dit extern moet worden geregeld, maar ook dat de database meer dan een normaal aantal tokens mag bevatten.
Maar wat heeft dit met backups te maken? Waarom zou je data in veiligheid brengen als er elke uur een nieuwe tokens worden toegevoegd en elke dag een expire wordt gedaan? Een constante stroom aan nieuwe data zorgt ervoor dat de database altijd in flux is zoals het hoort en in het slechtste geval is je database een paar uur aan het bijleren. Om dit laatste te overkomen zou je spam- en hamberichten bijvoorbeeld in de Trash-folder van de IMAP-server kunnen laten staan die na een paar dagen deze automatisch verwijdert uit standaard policy. Het verplaatsen van alle berichten van de Trash-folder naar de INBOX en bij de volgende ronde komt alles weer vanzelf in de database. Deze methode werkt ook vrij goed als de layout van de database wordt aanpast bij een upgrade en de database moet opnieuw worden opgebouwd.
De vraag die sysadmins misschien wat meer moeten vragen of de data echt naar tape moet, want we leven steeds meer in een tijdperk dat backups onmogelijk(er) beginnen te worden. Er zullen dus andere oplossingen moeten worden gezocht om data veilig te houden voor gebruikers. De eerste stap is het niet op tape zetten van data die je kan reproduceren.
In mei 2009 besteede ik in postings PostgreSQL voor Bayesian-filtering in SpamAssassin en Een Bayesian-filter vullen met data de nodige aandacht aan Bayesian-filtering, maar hoe staat het er nu voor? En het eerste wat zal opvallen is de titel, want er staat “na ongeveer een jaar” en de postings waren in mei. Dit klopt, maar gelukkig was de opzet van Bayesian-filtering met een PostgreSQL-backend al eerder opgezet om zeker te zijn dat het zinvol was.
Een jaar later is goed te zeggen dat de keuze voor het starten van een Bayesian-filter een goede keuze was. Veel spamberichten welke normaal gesproken niet door SpamAssassin zouden worden herkent worden nu als spam gemarkeerd. Ook het snelle leren van nieuwe type spamberichten gaat redelijk vlot, hoewel je wel voldoende berichten moet voeden aan het systeem. Naarmate de tijd vorderde ging de interval dat sa-learn draaide van eenmaal per dag naar elke zes uur, naar elke vier uur en uiteindelijk naar elk uur om bij te blijven. Zeker nadat de spamdomeinen geen bescherming meer hadden van de Spamhaus regels in de mailserver.
De komende maanden zal er een herimplementatie moeten komen van het statistiekensysteem om zo duidelijk te krijgen wat de belangrijkste regels in SpamAssassin zijn en of het mogelijk is om zonder oa SURBL, URIBL en Spamhaus te kunnen, maar ook welke SARE-regels nog zinvol zijn. Een andere optie is om te kijken of een herintroductie van Spamikaze kan plaats vinden om bepaalde e-mails toch op basis van een eigen blacklist/whitelist af te handelen.
Het was te verwachten uiteraard, maar bij het bekijken waarom sommige spamberichten niet netjes naar de Junk-folder viel me iets grappigs op. Sommige partijen zijn begonnen om niet alleen hun responses te monitoren met Google Analytics, maar laten nu ook automagisch een Tweet aanmaken om zo hoger op sommige lijsten te scoren. Of het fair is laat ik even in het midden, maar het lijkt wel langzaam een trend te worden om Twitter-achtige dingen te gebruiken in marketing en de kans dat gebruikers dit naar elkaar doorsturen is vrij klein.
describe LOCAL_TWEET Mailing with Tweet-API
rawbody __A_LOCAL_TWEET /\bhttp:\/\/api\.tweetmeme\.com\/share\?url/i
rawbody __B_LOCAL_TWEET /\bunsubscribe\b/i
meta LOCAL_TWEET ( __A_LOCAL_TWEET && __B_LOCAL_TWEET )
score LOCAL_TWEET 0.001
Met de bovenstaande ruleset voor SpamAssassin is te controleren wat de impact gaat zijn. Een paar dagen loslaten op de honeypot die het bayesianfilter van kenmerken voorziet zou voldoende moeten zijn om te kijken wat de score daadwerkelijk moet gaan zijn en of het effectief is.
Recente reacties