Recidives, wordpress and fail2ban

This is what happens when you configure fail2ban to ban recidives one week:

fail2ban-weekThe blue line is a wave of IP addresses probing my sites for a wordpress vulnerability and triggering wordpress-hard, the yellow line represents recidive addresses (hosts blocked more than 5 times over a week, blocked for a week).

See:

How to stop wordpress bruteforce logins with fail2ban

and

A bruteforce botnet targeting a wordpress site

A bruteforce botnet targeting a wordpress site

One of my wordpress sites has been hit by an organized brute-force login attack originating from a botnet. Since I use fail2ban for wordpress logs with 1 hour bantine, it was interesting observing the bots coming one at a time, triggering a ban almost immediately, and being followed by the next IP immediately, again and again. The attack lasted about one hour and featured about 120 distinct IPs. You can see the spike in the fail2ban graph:

fail2ban-monthThe usernames were the evergreen admin, domain and domaintld.

Update 20160927: more waves of bruteforce logins coming from dozens of different IPs. The real number of IPs is about 1/3 higher, due to the munin graph compression.

fail2ban-month

How to stop wordpress bruteforce logins with fail2ban

If you use wordpress and you enjoy reading the webserver logs like me, you see many failed login attempts produced by bots trying to guess common passwords for the accounts on your blog. This is bad because:

  • if one user has a weak or unsafe password, it will be compromised and your blog probably owned;
  • every user enumeration and password guess uses wp-login.php bypassing any caching that you may have, wasting resources that your server may well use to serve content;

I have tried a handful of plugins to limit login attempts, but they all work blocking brute force attempts at the php level.

If you have a dedicated server o a VPS you can use WP fail2ban plugin to write failed login attempts to /var/log/auth.log, then install and configure fail2ban to block offending IPs via iptables. The plugin documentation is straightforward and you should follow the recommended settings.

The key advantage of an iptables approach is that the overhead of blocking brute force bots is very low compared to PHP. The downside is that IP blocking it not very flexible if you really have lots of real users from real networks, so use it if you know what you are doing.

I have found the following settings specially effective:

  • raise the bantime from 300 seconds to something higher, like 3600 (1 hour). This has decreased the number of blocked IPs overall.
  • rename the admin account and set WP_FAIL2BAN_BLOCKED_USERS in wp-config.php accordingly. This triggers wordpress-hard and blocks bots instantly.
  • disable IPv6 on your domains. Unfortunately, fail2ban does not yet support IPv6 (version 0.10 will) and IPv6 bots do exist. Forcing them on IPv4 will let fail2ban block the attacks.

Don’t forget to configure fail2ban properly: to avoid banning your own server’s IP address, add the corresponding entry to the ignoreip line in your jail configuration. Otherwise you risk blocking wp-cron and having “missed schedule” errors in your blog.

Another migration from Movabletype to WordPress

I had to move a very old Movabletype site over to a WordPress install. This is the migration log, for future reference.

The original site was a MT 2.5 install from 2002/2003 that has been running until now, literally untouched since a major server move in 2006, with new posts being added daily and a grand total of 5000 post, mostly medium- and long-form essays and fiction writings.

The site suffered from severe underperformance issues even under moderate load, both caused by its outdated server and by MT’s code inability to cope with a modern web environment. Comments were disabled but trackbacks were not, resulting in huge amounts of pingback spam. No plugins and no customizations other than the site’s own graphic template.

First, I refreshed my memories from 2005 when I migrated a similar site. Then, I discovered this post by David B. Bitton that shows a new way of importing data while preserving old permalinks and SEO. I’ll follow David’s steps, here’s how:

Do a backup of database and files (cgi-bin and document root) and replicate the install on my laptop so that I can set config/memory limits as I please. Logging in the local MT site (let’s call it “local1”) change the “blog config” parameters to reflect the local settings, then rebuilt the site in order to visually check the installation and use it for reference (for the original style, color palette, exact content).

After that, clone “local1” into “local2” (mysqldump, new db, restore db, copy files, change mt.cfg settings from local1 to local2). “local1” will be the reference old installation, “local2” will be the actual upgrade installation.

The goal here is to upgrade to a Movabletype version where I can do an XML “backup” of the blog, as opposed to a MT “export” in text format. The key difference is that the XML backup keeps the entry IDs of every post, that will be used later in the WordPress import. This feature was first introduced in MT 4.x MT (thanks Mihai Bocsaru in the MT forums for the information). I decided to upgrade straigth to 4.x without hopping through several intermediate upgrades 2.x 3.x 4.x and it worked, but if you have a more complex configuration, comments, plugins and customizations you may prefer the long upgrade path.

Download MT 4.37 (the earliest 4.x available) from http://www.movabletype.org/downloads/archives/. Read the documentation on upgrades from the tarball’s docs/mtupgrade.html. The two key issues are that mt-db-pass.cgi is deprecated and mt.cfg has moved to mt-config.cgi.

Go to “local2” cgi-bin directory, copy mt.cfg to mt-config.cgi, and add a DBPassword “yourdbpassword” statement. Then set execution permissions to mt-config.cgi. Copy the MT 4.37 files over the old installation. Go to localhost/cgi-bin/mt.cgi (or where you installed local2): an upgrade page will walk you through the upgrade process, with a nice progress bar and a helpful upgrade log. I had to check apache2 error.log several times because of missing static files (javascript and such) that I forgot to move to the proper place.

When the upgrade is completed login in the new “local2” site and check that everything is fine. It is not, actually, because somewhere between MT 2.5 and 4.3 the character encoding has switched from Latin1 to UTF-8 and all accented letters are garbled. Ignore this issue for the time being (it’s not well documented, MT is old software with a long complicated proprietary/open history).

Go to Tools>Backup in your MT dashboard. Do an uncompressed undivided backup. The output is an XML file of all your blog contents. The original MT2.5 database was 100 MB, the XML is just a little above that. Open the XML file with a text editor: in my case half of the contents were pingback/trackback spam which I deleted, final size was 50MB.

(The pingback spam could have beed deleted from the original database via SQL in the first place, but I was not familiar with MT2.5 database. Deleting spam from the db before upgrading is going to make the following process faster.)

Then convert the character encoding of the XML backup file with iconv:
iconv -f ISO-8859-1 -t UTF-8 file > newfile
It still contained illegal characters to be replaced with their UTF-8 equivalents or their XML escape entities, especially apostrophes in the entry titles. I used Firefox to check and validate the XML file every time. (A possible explanation for this character havoc is the accumulation of thousand of posts by dozens of authors over a decade: different word processors, operating systems, writing habits: nice mess!)

From now follow David B. Bitton’s post. I made a local WordPress installation, add the Movable Type Backup Importer plugin and add just after line 407 of class-mt-backup-import.php:
$post->import_id = $id;

Import the XML file and wait, it takes some time for 5000 posts.

Then set the permalink structure, I use the year/month/day/post-title style and slightly different rewrite rules. The key is to redirect existing incoming links to the old permalink structure to WordPress default short (numeric) URLs and redirect the feed subscribers. Here’s the .htaccess (snippet):


RewriteEngine On
RewriteRule ^archives/[0-9]{4}/[0-9]{2}/0*(\d+).html$ /?p=$1 [R=301,NC,L]
RewriteRule ^archives/[0-9]{4}/[0-9]{2}/0*(\d+)print.html$ /?p=$1 [R=301,NC,L]
RewriteRule ^archives/([0-9]{4})_([0-9]{2}).html$ /$1/$2 [R=301,NC,L]
RewriteRule ^archives/cat_([a-z_]*).html$ /categorie/$1 [R=301,NC,L]
RewriteRule ^archives.html$ / [R=301,NC,L]
RewriteRule ^index.rdf$ /feed [R=301,NC,L]
RewriteRule ^index.rss$ /feed [R=301,NC,L]
RewriteRule ^index.xml$ /feed [R=301,NC,L]
RewriteRule ^atom.xml$ /feed [R=301,NC,L]

# BEGIN WordPress

Edit: there are a couple more rules I added depending on the original permalink structure in the old site. I found out checking the apache logs for 404 not found errors.

Now I have a working localhost site with all the original old site content. Check that nothing is missing, verify the users/passwords. Check the old MT media directory (usually /archives) and delete all .xml files (mostly trackback spam), html files (single posts, category archives, date archives) and date directories.

Eventually, move it to a production server (I prefer editing a database dump for this purpose) and enjoy. Keep an eye on the web server logs for 404s, adjust the htaccess rules as needed.

Una intervista su Nazione Indiana

Antonio Prudenzano di Affaritaliani.it intervista Gianni Biondillo a proposito di Nazione Indiana:

Nel marzo 2003 è apparso su internet uno spazio destinato a rivoluzionare e sdoganare una volta per tutte i blog letterari in Italia: Nazione Indiana (d’ora in avanti NI, ndr). A fondarlo, un ampio e variegato gruppo di intellettuali (non solo scrittori e critici letterari, ma anche artisti). Tra gli obiettivi, quello di pubblicare testi letterari e critici e promuovere iniziative politiche e culturali, il tutto all’insegna dell’interdisciplinarità e del multiculturalismo. Va detto che NI (l’idea per il nome è di Antonio Moresco) è un blog aperto a tutti solo nello spazio (spesso infuocato…) riservato ai commenti, mentre possono pubblicare articoli (post) solo i membri del progetto. A maggio 2005 alcuni membri storici (tra questi, Moresco, Tiziano Scarpa e Dario Voltolini) hanno lasciato NI per fondare la rivista cartacea e online (ma senza la possibilità di commentare i singoli articoli) Il primo amore.  Attualmente, tra i membri più attivi di uno dei blog letterari italiani più famosi c’è lo scrittore-architetto Gianni Biondillo. Affaritaliani.it lo ha intervistato per fare il punto sul progetto NI e per provare a tracciare un bilancio del percorso fin qui compiuto.

Leggi l’intervista completa: Biondillo racconta Nazione Indiana: “A fine maggio siete tutti invitati alla nostra festa…”. L’intervista

Non mi piace wordpress 2.5

Sono appena passato da 2.3.3 a wordpress 2.5 qui su monsterlippa. Non sono granché soddisfatto:

  1. la gestione degli articoli non permette di selezionare i pezzi per autore né per stato; se ho un blog di gruppo gli autori fanno fatica a lavorare sui propri pezzi, sia di archivio che in via di pubblicazione;
  2. sempre nella gestione articoli, non compare l’ora di pubblicazione, utile per programmare vari post nell’arco della giornata;
  3. la pagina per scrivere un articolo è stretta, le opzioni (stato, data e ora, trackback, categorie etc) che erano sulla destra sono ora sparpagliate tra la colonna destra e il fondopagina;
  4. l’upload di immagini dal pc è bacato: mi ripete 3 volte ogni immagine, sfasandola e andando fuori dai margini della finestra javascript di upload;
  5. la gestione dei widget rende difficile capire come mettere un widget nella colonna 1 o 2;

Il punto 5 interessa solo me come amministratore, ma i punti 1 2 3 4 significano disagio per gli autori di un blog di gruppo, tante email di spiegazioni, richieste di aiuto.

Per il resto ci sono cose molto positive sul fronte delle funzionalità (migliore editor visuale, media gallery per chi fa foto) e della sicurezza (salted hashes delle password). Ma aspetterò a lungo prima di aggiornare altri siti, specialmente quelli con molto autori.

How to upgrade WP Super Cache

If you use the WP Super Cache plugin and want to upgrade, you must completely remove the old installation, otherwise you’ll get errors in your blog. At least, this is what happens with my installations. Follow this steps, loosely adapted from the plugin documentation:

  1. disable caching and disable the plugin;
  2. edit wp-config.php and delete the WP_CACHE define line;
  3. remove the files wp-content/wp-cache-config.php and wp-content/advanced-cache.php.
  4. remove the lines added by wp super cache in your .htaccess file;
  5. delete the wp-super-cache directory from /wp-content/plugins/, upload and unzip the new version
  6. go to the Plugins page and activate “WP Super Cache”;
  7. now go to Options->WP Super Cache and enable caching.;
  8. copy the mod_rewrite rules  into your .htaccess file.
  9. check that /wp-content/cache/.htaccess has the two lines about gz

That’s it!

Perché non ho ancora aggiornato WordPress

Aggiornamento: ormai ho WP 2.1 dappertutto, gli ultimi problemi sono stati risolti e valeva la pena aggiornare dato che a fine mese arriva WP 2.2

Il 22 gennaio è uscito WordPress 2.1, che introduce molte migliorie nelle prestazioni e nella praticità d’uso di questa piattaforma blog e CMS. Passare dalla versione 2.0.7 alla 2.1 è semplice e indolore, eppure non l’ho ancora fatto se non in certi miei ambienti sperimentali.

La spiegazione è semplice: passare a 2.1 significa modificare leggermente l’interfaccia di amministrazione per i miei utenti, e vuol dire un pochino di lavoro per me che devo controllare che tutto funzioni. Tanto vale approfittare dell’occasione per degli interventi più profondi sulla grafica del sito e sull’organizzazione dei contenuti, magari durante un passaggio da un fornitore di hosting all’altro.

Tutti motivi per rimandare e tenersi la 2.0.x , che del resto verrà mantenuta e aggiornata per la sicurezza fino al 2010 perché è entrata a far parte di Debian Etch. Oltretutto siamo già passati da 2.0.7 a 2.0.9 con degli aggiornamenti di sicurezza.

Per questoi miei progetti come Monsterlippa, Nazione Indiana o Markelo Uffenwanken sono tutti alla 2.0.9: ancora per poco, spero.