Serendipity und IPv6

Saturday, October 6. 2012

Serendipity ist die Software, die dieses Blog liefert, und wegen eines IPv6-bezogenen bug dieser Software war dies blog mehr als einen Tag offline. 
Serendipity hat ein plugin Spamschutz mit einer Reihe von Möglichkeiten, Kommentarspam zu bekämpfen, und eine davon ist, erkannte Spammer per IP vom Zugang zum Blog auszuschliessen. Das hat sich hier gegen bestimmte Serienspammer erstaunlich gut bewährt. 

Bis der erste Spammer mit einer IPv6-Adresse gelogt wurde, danach war mein blog weg.

Das Problem ist: 

serendipity_event_spamblock.php patzt bei der Behandlung von IPv6-Adressen. IPv4 sind kürzer als IPv6 Adressen.
(IPv4: 4 Teile x 3 Stellen + 3 Trenner = 15 Zeichen  IPv6: 8 x 4 + 7 = 39). Darauf ist das plugin nicht eingerichtet.
Wenn man in der config des Plugin "SPAM IP Adressen via HTaccess blocken? " 'Ja' ankreuzt und eine IPv6-IP als Spam erkannt worden ist, dann schreibt das Plugin in die .htaccess etwas ähnliches wie:
 
#SPAMDENY
Deny From 205.189.73.46 205.189.73.64 208.89.211.173 217.157.179.122 24.62.10.133 
2607:5300:10:60 31.135.196.229 37.10.106.185 37.10.112.228 37.10.116.107 37.10.116.35 
#/SPAMDENY
 
Problematisch ist der Eintrag '2607:5300:10:60' Das ist keine gültige IP sondern nur die vordere Hälfte einer IPv6. Und so bekommt man nun bei jedem Versuch, das Blog zu laden, eine wunderschöne 500er-Fehlermeldung mit dem Hinweis auf 'invalid IP'
 
Das Hackstück aus der .htaccess zu löschen hilft auch nicht, denn mit dem naechsten Spammer wird der ganze deny from... - Block neu aus der Datenbank gelesen und eingeschrieben, incl. des fehlerhaften Eintrags. Die zuständige Tabelle heisst serendipity_spamblock_htaccess und ist wohl auch gleich die Schuldige an dem Bug. 
 
Diese Tabelle hat zwei Felder, timestamp vom Typ varchar(19) unsigned und ip vom Typ varchar(15). Eine Breite von 15 ist fuer legacy IPs grad recht, für IPv6 ist das ein Fehler. Benötigt wird eine Feldbreite von varchar(39). 
 
Massnahmen:
- Breite des Feldes ip auf 39 hochsetzen
- alle (in meinem Fall nur 1) defekte IPv6 löschen
o shell öffnen, 
o mysql -u (username) -p (und passwort)
o use (datenbankName)
o delete from `serendipity_spamblock_htaccess` where (`ip` like "%:%");
- auf den nächsten Spammer mit IPv6 warten...

Some minor edit to this blog, save, and instead of the usual messages I get an error message  incorrect key file for table ./database/serendipity_entries.MYI; try to repair it! Collateral damage: text has not been saved.

I tried Google to find some attempts to downplay the issue, possibly just a hd completly used. But this is not what has happened for me, tmpfs still has 505MB left and the Index file mentioned in the error report is just 320Kb. So I search on and find check table und repair table. The documentation recommends a prior backup. then:

mysql -u root -p
use database;

CHECK TABLE serendipity_entries;

 
(output denotes the table as corrupt)
 
REPAIR TABLE serendipity_entries;
 
+------------------------------+--------+----------+----------+
 
| Table                        | Op     | Msg_type | Msg_text |
 
+------------------------------+--------+----------+----------+
 
| web31db1.serendipity_entries | repair | status   | OK       |
+------------------------------+--------+----------+----------+
 
and that's it, savine works again.

Blinkaugen bei 1&1

Saturday, November 5. 2011

Im Kundenauftrag bei 1&1 unterwegs und aua! ist das ein Gewimmel von Zusatzangeboten, Irrwegen, und mehr! Der Webauftritt der Kundin sollte WebAnalytics und ein blog bekommen, beides leuchtet als Option im Controlcenter ihres Homepage-Paketes. Naja, geschenkte Gäule. Die Webanalytics sind ein glorifiziertes Awstats und sehen maximal 3 Monate zurueck. Und das Blog ist eine shared Wordpress Installation mit sehr reduzierter Konfigurationsbreite: man kann aus einer Latte Templates auswählen (aber nichts daran ändern) und man kann eine handvoll vorgegebener Plugins aktivieren (aber keine eigenen/anderen einsetzen). Dafür hat das Blog dann lauter Links zu 1&1 und das Ärgerlichste ist: es ist keine Option zum Export des Blogs vorgesehen. Wenn der Kunde irgendwann die Nase voll hat von 1&1 und weg will, kann er sich die Blog-Einträge mit Copy&Paste rüberziehen, einfach super.
Nun, also doch wie ursprünglich geplant Piwik für die WebAnalytics und Serendipity für's Blog. Auch das macht nicht so richtig spass bie 1&1 denn man bekommt keine error_log zu sehen. Und das heisst, wenn mal was nicht so flutscht wie es soll: Rummachen im Blindflug, uuähh!

Serendipity funzte schliesslich mit einer .htaccess wie dieser (ohne die beiden ersten Zeilen gab es bei event_plugins nur Fehlermeldungen!)

AddType x-mapp-php5 .php
AddHandler x-mapp-php5 .php

ErrorDocument 404 /index.php
DirectoryIndex /index.php

RewriteEngine On
RewriteBase /
RewriteRule ^serendipity_admin.php serendipity_admin.php [NC,L,QSA]
RewriteRule ^((archives/([0-9]+)-[0-9a-z\.\_!;,\+\-%]+\.html)/?) index.php?/$1 [NC,L,QSA]
RewriteRule ^(authors/([0-9]+)-[0-9a-z\.\_!;,\+\-%]+) index.php?/$1 [NC,L,QSA]
RewriteRule ^(feeds/categories/([0-9;]+)-[0-9a-z\.\_!;,\+\-%]+\.rss) index.php?/$1 [NC,L,QSA]
RewriteRule ^(feeds/authors/([0-9]+)-[0-9a-z\.\_!;,\+\-%]+\.rss) index.php?/$1 [NC,L,QSA]
RewriteRule ^(categories/([0-9;]+)-[0-9a-z\.\_!;,\+\-%]+) index.php?/$1 [NC,L,QSA]
RewriteRule ^archives([/A-Za-z0-9]+)\.html index.php?url=/archives/$1.html [NC,L,QSA]
RewriteRule ^([0-9]+)[_\-][0-9a-z_\-]*\.html index.php?url=$1-article.html [L,NC,QSA]
RewriteRule ^feeds/(.*) index.php?url=/feeds/$1 [L,QSA]
RewriteRule ^unsubscribe/(.*)/([0-9]+) index.php?url=/unsubscribe/$1/$2 [L,QSA]
RewriteRule ^approve/(.*)/(.*)/([0-9]+) index.php?url=approve/$1/$2/$3 [L,QSA]
RewriteRule ^delete/(.*)/(.*)/([0-9]+) index.php?url=delete/$1/$2/$3 [L,QSA]
RewriteRule ^(admin|entries)(/.+)? index.php?url=admin/ [L,QSA]
RewriteRule ^archive/? index.php?url=/archive [L,QSA]
RewriteRule ^(index|atom[0-9]*|rss|b2rss|b2rdf).(rss|rdf|rss2|xml) rss.php?file=$1&ext=$2
RewriteRule ^(plugin|plugin)/(.*) index.php?url=$1/$2 [L,QSA]
RewriteRule ^search/(.*) index.php?url=/search/$1 [L,QSA]
RewriteRule ^comments/(.*) index.php?url=/comments/$1 [L,QSA]
RewriteRule ^(serendipity\.css|serendipity_admin\.css)$ index.php?url=/$1 [L,QSA]
RewriteRule ^index\.(html?|php.+) index.php?url=index.html [L,QSA]
RewriteRule ^htmlarea/(.*) htmlarea/$1 [L,QSA]

RewriteRule (.*\.html?) index.php?url=/$1 [L,QSA]

<Files *.tpl.php>
    deny from all
</Files>

<Files *.tpl>
    deny from all
</Files>

<Files *.sql>
    deny from all
</Files>

<Files *.inc.php>
    deny from all
</Files>

<Files *.db>
    deny from all
</Files>
(Page 1 of 1, totaling 3 entries)