Seit ein paar Tagen stelle ich einen immer stärker werdenden Zugriff von LIBWWW Clients auf meine Webseite fest. Hier wird ziemlich genau mein Szenario beschrieben. Gibt man LIBWWW bei Google ein wird man sehr schnell fündig: Das sind offensichtlich Attacks, die versuchen Sicherheitslücken zu finden.
Sofern man seinen Joomal Server sicher aufgesetzt hat kann man die Attacken ignorieren. Hier ist ein guter Link, wie man seinen Server sichert.
Abgesehen von dem erhöhten Traffic und aufblähen der Logs mag ich es auch nicht, wenn jemand bei mir zu Hause ständig an der Türklinke rüttelt, obwohl die Haustür verschlossen ist. Deshalb habe ich die Tür wie folgt für libwww geschlossen:
- Edit von .htaccess
- Einfügen von
BrowserMatchNoCase "^libwww-perl" botnetz
order allow,deny
allow from all
deny from env=botnetz
Die Clientidentifikation kann natürlich ohne Probleme geändert und damit der Block umgangen werden. Aber ich denke 99% der Angriffsversuche werden damit geblocked. Und der Rest sollte aufpassen, dass er sich beim Rütteln nicht die Hand bricht ...
Update 12/24/2010:
Bei irgendeiner Umstellung sind meine o.g. Statements unbemerkt aus der .htaccess leider verschwunden. Leider erzeugen sie jetzt aus irgendwelchen mir unerfindlichen Gründen Apache Fehler. Auf dieser Seite habe ich eine Alternative gefunden und eingebaut.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* – [F,L]
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* – [F,L]
Damit werden alle Requests auf 401 (Access denied) umgebogen. Ausserdem habe ich die Joomla Admin Seite wieder mit einem Apache Passwort zusätzlich zum normalen Joomla Admin Passwort geschützt, denn dieser Schutz war dummerweise auch verloren gegangen und dadurch wurde natürlich kräftig versucht, das Passwort zu knacken. Da zeigt sich wieder, dass ein gutes und sicheres Password wichtig ist.
Nachdem es mir zu lästig wurde immer mal im Joomla nachzusehen ob noch alles OK ist mit den libwww Besuchen habe ich folgendes Python Script geschrieben. Es listet die letzten libwww Versuche und schreibt eine Warnung wenn ein Limit überschritten wird. Nun noch cron und sendmail konfiguriert und man bekommt bei libwww Requests auf seiner Joomla Webseite immer immer Warn eMails. Bei Einsatz der o.g. .htaccess Rules sollte da aber nichts mehr auftauchen.
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Query and check if libwww accesses were detected on a joomla based website.
# Requirement: joomlaStats installed
#
# 12/27/2010 framp at linux-tips-and-tricks dot de
#
import MySQLdb
import sys
LIMIT=0
alert=False
maximum=0
try:
conn = MySQLdb.connect (host = "host",user = "user",passwd = "password",db = "database")
cursor = conn.cursor ()
cursor.execute ("""SELECT year, month,day, count(*) as Count
FROM jos_jstats_ipaddresses AS a
LEFT JOIN jos_jstats_visits AS c ON a.id = c.ip_id
where a.useragent like '%libwww%'
group by year,month,day
order by year desc,month desc, day desc
limit 0,30""")
row = cursor.fetchall()
conn.close ()
for r in row:
(year,month,day,count) = r
print "%2d.%2d.%4d - %d" % (day,month,year,count)
if count > LIMIT:
alert=True
if count > maximum:
maximum=count
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit (1)
if alert:
exceed=maximum-LIMIT
print "!!! libwww threshold of %d exceeded by %d!!!" % (LIMIT,exceed)
# -*- coding: utf-8 -*-
#
# Query and check if libwww accesses were detected on a joomla based website.
# Requirement: joomlaStats installed
#
# 12/27/2010 framp at linux-tips-and-tricks dot de
#
import MySQLdb
import sys
LIMIT=0
alert=False
maximum=0
try:
conn = MySQLdb.connect (host = "host",user = "user",passwd = "password",db = "database")
cursor = conn.cursor ()
cursor.execute ("""SELECT year, month,day, count(*) as Count
FROM jos_jstats_ipaddresses AS a
LEFT JOIN jos_jstats_visits AS c ON a.id = c.ip_id
where a.useragent like '%libwww%'
group by year,month,day
order by year desc,month desc, day desc
limit 0,30""")
row = cursor.fetchall()
conn.close ()
for r in row:
(year,month,day,count) = r
print "%2d.%2d.%4d - %d" % (day,month,year,count)
if count > LIMIT:
alert=True
if count > maximum:
maximum=count
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit (1)
if alert:
exceed=maximum-LIMIT
print "!!! libwww threshold of %d exceeded by %d!!!" % (LIMIT,exceed)
