Page 1 of 2
Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Feb 18, 2009 8:31 pm
by el*Loco
Huhu Serendipity User,
da Akismet und auch
TypePad Antispam tlw. ein wenig viel wegfiltern - gerade Kommentare auf Deutsch - habe ich gestern ein wenig begonnen, mir über Alternativen Gedanken zu machen. Erst wollte ich Spamassassin zur Erkennung von Spam/Ham verwenden, bin dann aber bei
bogofilter gelandet, da Spamassassin sehr viele Tests für Mailheader hat und diese auch erwartet (Received-Zeilen etc.).
Da bogofilter ein Bayes-basierter Filter ist, muss er erst lernen, was gut und was schlechte Kommentare sind. Dazu habe ich zwei Dinge getan:
Alle guten Kommentare je in eine Datei pro Kommentar geschrieben:
Code: Select all
SELECT author,url,body FROM serendipity_comments WHERE status = 'approved';
Alle erkannten und abgelehnten Spamkommentare in je eine Datei pro Kommentar geschrieben:
Code: Select all
SELECT author,url,body FROM serendipity_spamblocklog WHERE type = 'REJECTED';
In meinem Fall ergab das dann zwei Verzeichnisse, einmal "blogspam" mit fat 370.000 abgelehnten Spams und ein "blogham" Verzeichnis mit 700 guten Kommentaren und Trackbacks. Jede der Dateien hatte untereinander author, url und body stehen. Jetzt zum lernen:
Code: Select all
loco@bigboy ~ $ bogofilter -v -H -n -B blogham/
# 6663 words, 696 messages
Code: Select all
loco@bigboy ~ $ bogofilter -v -H -s -B blogspam/
# 331002 words, 369836 messages
Wenn ich jetzt je einen neue Spamkommentar und einen erfundenen, aber validen sauberen Kommentar zur Prüfung durch den bogofilter jage, erkennt er das brav:
Code: Select all
loco@bigboy ~ $ bogofilter -v -H < test.blog
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.1.7
Code: Select all
loco@bigboy ~ $ bogofilter -v -H < test.blog
X-Bogosity: Spam, tests=bogofilter, spamicity=1.000000, version=1.1.7
Manuell tut das jetzt alles - aber wie verwende ich das in Serendipity? Ich bin SysAdmin, habe es überhaupt nicht mit der PHP Programmierung. Gäbe es denn Interessierte, die diesen Ansatz der Spamfilterung mittels Bayesfilter weiter verfolgen möchten und evtl. in ein Spamblock-Plugin giessen möchten?
Gruß aus dem närrischen Köln,
Peter
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Feb 18, 2009 10:50 pm
by garvinhicking
Hi!
Eigentlich ist das halbwegs einfach zu programmieren. Ich empfehle ausdrücklich, nicht das Haupt-Spamblock-Plugin als Grundlage zu nehmen (das ist überfüllt) sondern z.b. serendipity_event_spamblock_rbl (Spartacus).
Daraus abgeleitet mal folgendes Minigrundgerüst:
Code: Select all
<?php
class serendipity_event_spamblock_bogo extends serendipity_event {
function introspect(&$propbag) {
global $serendipity;
$this->title = 'Bogobogo';
$propbag->add('name', $this->title);
$propbag->add('version', '0.1');
$propbag->add('event_hooks', array('frontend_saveComment' => true));
$propbag->add('groups', array('ANTISPAM'));
}
function generate_content(&$title) {
$title = $this->title;
}
function bogo(&$comment) {
$f = '/tmp/bogo.log';
$fp = fopen($f, 'w');
flock($fp, LOCK_EX);
fwrite($fp, $comment['name'] . "\n" . $comment['url'] . "\n" . $comment['comment'] . "\n");
fclose($fp);
$return = `bogofilter -v -H < $f`;
if (preg_match('@X-Bogosity: Spam@imsU', $return)) {
return true;
}
return false;
}
function event_hook($event, &$bag, &$eventData, $addData = null) {
global $serendipity;
$hooks = &$bag->get('event_hooks');
if (isset($hooks[$event])) {
switch($event) {
case 'frontend_saveComment':
if (!is_array($eventData) || serendipity_db_bool($eventData['allow_comments'])) {
$serendipity['csuccess'] = 'true';
if ($this->bogo($addData)) {
$eventData = array('allow_comments' => false);
$serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_RBL . ' ('.implode(', ', $dnsbl->getTxt($remoteIP)).')';
return false;
}
}
return true;
break;
default:
return false;
break;
}
} else {
return false;
}
}
}
Das führt in der bogo Methode eigentlich alles aus und liefert "true" wenn's ein Spam ist. Entsprechend wird dann ein Kommentar hart geblockt. Wenn Du es lieber moderieren willst, muss man innerhalb der if ($this->bogo(...)) Bedingung stattdessen folgendes nehmen:
Code: Select all
$eventData['moderate_comments'] = true;
$serendipity['csuccess'] = 'moderate';
$serendipity['moderate_reason'] = 'Bogobogo!';
Ehrlich gesagt weiß ich nicht, ob Bayes hier gut greifen kann. Kommentare sind meist viel zu kurz um daraus verlässliche bayesische Filter erstellen zu können, fürchte ich....
Grüße,
Garvin
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Thu Feb 19, 2009 7:52 am
by Lux
el*Loco wrote:Manuell tut das jetzt alles - aber wie verwende ich das in Serendipity? Ich bin SysAdmin, habe es überhaupt nicht mit der PHP Programmierung. Gäbe es denn Interessierte, die diesen Ansatz der Spamfilterung mittels Bayesfilter weiter verfolgen möchten und evtl. in ein Spamblock-Plugin giessen möchten?
Ich finde die Idee immer noch grossartig und würde das auch gerne in einem Plugin sehen.
Gruss
Dirk
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Sat Feb 21, 2009 1:53 pm
by el*Loco
garvinhicking wrote:
Ehrlich gesagt weiß ich nicht, ob Bayes hier gut greifen kann. Kommentare sind meist viel zu kurz um daraus verlässliche bayesische Filter erstellen zu können, fürchte ich....
Mmh, viele Spam-Mails sind meist auch nicht so viel länger. Den Vorteil, den ich sehe, ist daß der Bayes Filter pro Blog trainiert werden kann. Bei Akismet und TypePad Antispam habe ich mittlerweile das Gefühl, daß deutschsprachige Kommentare und Trackbacks eher mal als Spam gewertet werden.
Gruß,
Peter
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Jun 24, 2009 1:48 pm
by onli
Ist es hier weitergegangen, vielleicht sogar ein Plugin entstanden? Als Alternative zu Akismet und Captcha wäre das schon toll.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Mon Jun 29, 2009 12:29 pm
by onli
Entschuldigt den Doppelpost.
Ich glaube, wollte man das als Plugin realisieren, könnte man statt bogofilter besser
b8 nutzen. B8 ist ein PHP-Bayes-Filter angepasst für Gästebucheinträge und Blogs - also genau das, was wir suchen. Ein Plugin könnte die vorhandenen Kommentare und den Spam in der install() zum Lernen nutzen und danach die neuen Kommentare bewerten, das genau so, wie es garvins code zeigt. Jemand Lust, das zu bauen?
Gruß
PS: Wie könnte man das Lernen anhand von nach der Installation eingetroffenen Kommentaren bewerkstelligen?
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Mon Jun 29, 2009 4:32 pm
by kleinerChemiker
Gibts da sonst noch interesse? Ein Bayse Filter mit PHP klingt interessant. Ich werds mir auf jeden Fall mal anschauen und wenn Interesse besteht vielelicht ein Plugin basteln.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Jul 01, 2009 6:14 pm
by onli
Ich habe mich mit kleinerChemiker abgesprochen und mich an b8 versucht. Dabei bin ich jetzt in drei Probleme gelaufen. Wahrscheinlich werde ich den b8-Weg sein lassen und stattdessen
http://aktuell.de.selfhtml.org/artikel/ ... e-software testen, aber den bisherigen Code hänge ich mal an. Die Probleme bisher:
1. Ein generelles: Ein bayes-Filter muss lernen, und wir können uns eigentlich nicht darauf verlassen, dass in der spamlog-Tabelle was drin steht. Auch manuelles kennzeichnen müsste möglich sein, ein "Spam"-Knopf beim Moderieren von Kommentaren wäre ideal. Nur: Wie den einfügen? Ein Event im core beim Formular-Erstellen feuern und das im Plugin greifen?
Die folgenden Probleme sind spezielle zum bisherigen Code:
2. Ist keine Datenbank vorhanden, wird createDB auf true gesetzt. Direkt danach scheitert aber die Initialisierung von b8, woraufhin nicht gelernt werden kann.
3. Beim zweiten Installieren ist die DB schon da und das Lernen klappt, aber im folgenden wirft b8 die Warnung, dass die Datenbank zu alt sei. Liegt wohl daran, dass die $version-Variable im b8-Code leer bleibt. Das muss irgendwas damit zu tun haben, wie mein Code die b8-Dateien anpackt, vor den Versuchen die Datenbankerstellung zu automatisieren trat dieser Fehler nicht auf. Ich tippe auf das Editieren der config_storage, diese Funktion (setCreate($value)) empfinde ich selbst als hässlich.
4. Versucht man sowas:
Code: Select all
$this->b8 = new b8;
if (! $this->b8->constructed) {
$this->b8 = new b8;
}
weil man vermutet, dass b8 beim ersten Mal immer fehlschlägt, gibt der Webserver die PHP-Datei als Textdatei zurück, also zum Downloaden. Ist das ein generelles PHP-Ding oder hat das mit b8 zu tun?
Gruß
PS: Ich bin nicht überzeugt davon, dass der selfhtml-Filter vergleichbar gute Ergebnisse bringt, es würde mich daher schon interessieren, die Probleme auszuräumen - ist ja gut möglich, dass sie durch von mir gemachten Fehlern entstanden.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Jul 01, 2009 6:18 pm
by onli
Doppelpost, weil edit scheitert:
Bisheriger Code.
(Bis auf die Warnmeldung, die Unmöglichkeit Spam nachträglich zu markieren und das zweimalige Installieren sollte es durchaus schon funktionieren, "Berkeley DB"-Unterstützung vorausgesetzt.)
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Jul 01, 2009 8:00 pm
by kleinerChemiker
Ich wüe nicht, weshalb die selfhtml Lösung schlechter sein sollte. Bayes-Filter basieren auf irgendsoeiner Wahrscheinlichkeitstheorie. Da die Berechnungen daher eigentlich ziemlich gleich sein sollten, sollte da kein allzu großer Unterschied sein.
Ich würde auch eher nur die wichtigen Funktionen übernehmen und das ganze enger auf s9y anpassen, z.B. die DB-Layer von s9y verwenden.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Wed Jul 01, 2009 8:56 pm
by onli
Hast du dir die readme genauer angeguckt? Ich fand an b8 verlockend, dass sich da jemand Gedanken gemacht hat. Beispiel:
The other thing is, that most Bayesian filters count one token one time, no matter how often it appears in the text (as Graham describes it in [1]). b8 does count how often it is there and learns or considers this. Additionally, the number of learned ham and spam texts are saved and used as the calculation base for the single possibilities. Why this? Because a text containing one link (no matter where it points to, just indicated by a "http://" or a "
www.") might not be spam, but a text with 20 links in it might be.
Ebenso ist
http://nasauber.de/opensource/b8/discussion/ eine scheinbar ordentliche Grundlage. Nichtsdestotrotz, der gemeinsame Versuch ist interessant.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Thu Jul 02, 2009 9:58 am
by kleinerChemiker
Wörter, die nur einmal vorkommen sind im Allgemeinen auch charakteristischer als Wörter wie "ist, und, wird, ..." die eben sehr oft vorkommen. Aber es spricht ja nichts dagegen, die Berechnungsgrundlagen von b8 für s9y anzupassen. Nur ie PHP Skripts von b8 halte ich persönlich für aufgebläht und die DB-Abfragen sind stark verbesserungswürdig.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Fri Jul 03, 2009 10:51 am
by onli
Ich denke, der Rahmen ohne Bayes-Funktionalität ist so brauchbar.
Gruß
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Fri Jul 03, 2009 5:16 pm
by kleinerChemiker
Es fehlt nur noch die Berechnung des Spamlevles. Das werd ich in den nächsten Tagen machen, wenn nix dazwischen kommt.
Re: Gedanken zu Spamerkennung mittels bogofilter
Posted: Sat Jul 11, 2009 6:20 pm
by kleinerChemiker
So, die Berechnung nun auch hinzugefügt. Eigentlich sollte es funzen, kann es aber derzeit leider nicht testen, da ich derzeit nur meinen alten Laptop zur verfügung habe.
Was mir noch aufgefallen ist, du bindest kein Langue-File ein und du solltest bei DB-Tabellen nicht "serendipity_" voraussetzen. Das Plugin wird allerdings erst mit s9y laufen, da ein Patch am Core notwendig ist, den ich Garvin noch schicken muß.