DNS DDOS: fail2ban mit Bind

In letzter Zeit werden einige DNS Server mittels Anfragen wie die folgenden geflutet.

query: ripe.net IN ANY +ED
query: isc.org IN ANY +ED

Mittels fail2ban („apt-get install fail2ban“) kann man diese Querys recht einfach auf die schwarze Liste setzen und mit iptables blocken. Dazu muss der Named erst mal alle Querys loggen:

# /etc/bind/named.conf.local

logging {
    channel query.log {
        file "/var/log/named/query.log" versions 0 size 1m;
        severity debug 3;
        print-time yes;
    };
    category queries { query.log; };
};

Das „versions 0 size 1m“ gibt an, das Named eine Datei von 1MB Größe immer wieder überschreiben soll. Das File hätte ohne diese Anweisung schnell einige GB erreicht…

Für fail2ban habe ich hier ein quick-and-dirty script angepasst, welches auf die beiden oben genannten Domains testet (Download: named-ddos.conf). Das Rezept ist auch gut anpassbar für eigene Zwecke. Das Script „named-ddos.conf“ gehört nach „/etc/fail2ban/filters.d/“.

In der /etc/fail2ban/jail.conf muss das Rezept jetzt noch aktiviert werden:

[named-ddos-tcp]
enabled  = true
port     = domain,953
protocol = tcp
filter   = named-ddos
logpath  = /var/log/named/query.log
maxretry = 8

[named-ddos-udp]
enabled  = true
port     = domain,953
protocol = udp
filter   = named-ddos
logpath  = /var/log/named/query.log
maxretry = 8

Nach einem restart von fail2ban sollte /var/log/fail2ban.log anzeigen, dass IPs gebannt werden:

2012-08-02 22:56:44,886 fail2ban.actions: WARNING [named-ddos-udp] Ban 63.166.xxx.xxx
2012-08-02 22:56:44,903 fail2ban.actions: WARNING [named-ddos-udp] Ban 216.9.xxx.xxx

Wenn alles funktioniert würde ich den loglevel in der /etc/fail2ban/fail2ban.conf auf „1“ setzen damit das logfile nicht überläuft.

Nutzung auf eigene Gefahr 😉 Man sollte sich dessen bewusst sein, dass u.U. auch „legale“ User ausgesperrt werden könnten und bei Bedarf die Schwellwerte anpassen.

DNS forwarder

Da unsere DNS-Server für fremde Zonen logischerweise direkt die Root-Nameserver befragen hatten wir natürlich auch mit dem DENIC-Problem zu kämpfen. Die google-Nameserver verwende ich normalerweise aus verschiedenen Gründen nicht, aber zur Zeit sind sie willkommen… Schnell in die named.conf auf den Nameservern eingetragen kann wenigstens wieder gesurft werden. Wenn das Problem vorüber ist wird der forwarder wieder raus genommen.

# named.conf
options {
...
        forwarders {
                8.8.8.8;
                };
        forward first;
}

Anscheinend verwendet Google andere TTLs oder einen sonstigen Mechanismus um die Zonen länger gültig zu halten.

DNS: Wildcard Records

Eine Sache die mir beim DNS gar nicht so bewusst war: Wildcard Records. Bei Webanwendungen arbeite ich gerne mit einem Default-Hosting und lasse die Anwendung bestimmen was bei welchem Hostnamen passiert (über den HTTP1.1 Header). In letzter Konsequenz fehlte mir eigentlich nur noch, dass ich die Hostnamen nicht mehr in die DNS-Zone eintragen muss.

Logische Folgerung (Auszug auf dem Bind-Zonenfile):

*.sub.bergercity.de.     IN A    88.151.66.11

Plesk: DNS-Zonen auf neue Serial umstellen

Plesk kann seit Version 8.6 auch mit RIPE-Konformen Zonen-Serials umgehen. Um in einem Rutsch sämtliche Domains auch einem Server auf das neue Format umzustellen reichen folgende Befehle (vorher Backup anlegen!):

Neue Serial setzen (natürlich auf aktuelles Datum anpassen):

mysql -Ns -u admin -p`cat /etc/psa/.psa.shadow` -D psa \
-e "UPDATE dns_zone SET serial_format = 'YYYYMMDDNN', serial = '2009022000' "

Alle Zonen im Bind updaten:

mysql -Ns -u admin -p`cat /etc/psa/.psa.shadow` -D psa \
-e 'SELECT name FROM dns_zone' \
| awk '{print " /usr/local/psa/admin/sbin/dnsmng update " $1}' | sh

Den zweiten Befehl habe ich hier abgeleitet. Da einige Programme keine Argumente über die Standardeingabe (stdin) annehmen (oder mangels Dokumentation nicht klar ist, ob sie das tun) finde ich es eigentlich ganz elegant, das Kommando mittels awk zusammenzubauen und dann zeilenweise auszuführen.