Tja, so kanns gehen. Eben noch rege ich mich darüber auf, dass mein Hoster manitu von einer ddos heimgesucht wird, schon darf ich feststellen, dass einer meiner Nameserver an einer anderen Distributed Denial of Service Attacke munter mitgewirkt hat. grmpf.
Aufgefallen ist mir das ganze per munin:
Okay, zwei/drei Anfragen pro Sekunde sind nicht viel, nur sieht man leider dadurch im Graphen den Rest nicht mehr. Ausserdem könnte der Angreifer ja auf die Idee kommen, auch mal mehr Requests zu schicken. Aber was will der eigentlich von mir – und wie ist er auf meinen Server gekommen?! Und zwei Anfragen – wo soll hier der DOS sein? Und warum fragt der ständig nach den Nameservern der ‚.‘-Zone?
Was soll also der ‚Mist‘?
Des Rätsels Lösung: Natürlich bin ich nicht das Opfer, das war mir eigentlich klar, aber es ist fast noch schlimmer: Ich Mein Nameserver ist Mittäter und
die scheinbaren Angreifer sind die tatsächlichen Opfer.
Jemand im Internet schickt gerade an massiv vielen Nameserver diese Anfragen mit gefälschtem Absender. Das Ergebnis: Nameserver die nicht ganz korrekt konfiguriert sind antworten dann freigiebig mit der Liste aller Root-Nameserver.
Bei wirklich großen Nameservern fallen diese Anfragen vermutlich nicht mal auf, weil sie im Hintergrundrauschen untergehen, so dass nur wenige Admins den Missbrauch ihrer Systeme überhaupt bemerken werden.
(Die Liste der Root-Nameserver gibt es hier oder beim Nameserver Eures Vertrauens per $ dig . NS @nameserver. )
Warum ist das nun ein Problem? Ganz einfach: der Angreifer schickt ein paket mit 40 bytes los, das Opfer erhält aber eine Antwort, die um ein vielfaches größer ist. Die Nameserver fungieren also als Verstärker des Angriffs. Schade eigentlich.
Selbst ein korrekt konfigurierter Nameserver, der die Anfrage ablehnt, antwortet noch mit der Ablehung, trägt also immernoch ein bischen zum DOS bei.
Gegenmassnahmen?
Es sind mehrere denkbar:
Einerseits haben die Anfragen alle denselben Inhalt und sind daher alle 40 byte groß. In 40 byte kann man auch sonst kaum eine sinnvolle Anfrage unterbringen, also kann man alles was per udp auf port 53 ankommt und weniger als 45 byte Größe hat blocken. Damit antwortet man sogar nicht mal mehr mit der Ablehnung und die Anfragen sind aus den logs. Man sollte nur seinen Provider und primäre/sekundäre Nameserver der eigenen Domains whitelisten, für den Fall, dass der Angreifer mal diese als neues Ziel definiert.
Dann könnte man ein rate-limit per IP einführen, so dass bei mehr als 20 Anfragen in 20 Sekunden der port 53 für diesen Host für einige Zeit gesperrt wird. Auch hier: Whitelisten nicht vergessen.
Oder man kann regelmässig seine Logs durchgehen, wer denn nun schon wieder soviele Anfragen produziert, und dann diese IP’s für port 53 sperren.
Achja, und ganz wichtig: Das Secure BIND Template umsetzen und die default policy der BIND-Installation unter debian ändern, damit man auf die Anfragen nicht die Liste liefert² 😉
In dem Template werden übrigens Views für verschiedene Hostgruppen definiert. Sehr schick – und ich habe auch endlich welche in meinen Configs definiert. Wollte ich schon lange machen.
Damit kann man unterschiedlichen Hostgruppen per acl unterschiedlich antworten. Also z.B. allen hosts aus dem Firmennetz die privaten Adressen und Namen auflösen und mit demselben Nameserver von aussen diese Anfragen nicht erlauben oder eine komplett andere Antwort geben.
Damit könnte man auch mit einem einzigen Nameserver ein Wlan derart gestalten, dass alle noch nicht authentifizierten Benutzer auf die Anmeldeseite gelangen, wo sie einen vpn-Client herunterladen können und später – ohne Ändern der resolv.conf¹ – mit der IP die sie innerhalb des VPN’s haben korrekte Namensauflösung vom Nameserver erhalten. (Aber das ist ein anderes Thema…)
¹ Es ist sehr eklig, denn der DHCP-Client im Wlan andere Nameserver einträgt, als der VPN-Tunnel braucht, dann kloppen sich DHCP-Client und VPN-Client nämlich schön darum, wem die resolv.conf gehört. Läuft die DHCP-Lease ab, trägt der DHCP-Client ’seine‘ DNS-Server ein und man landet wieder nur auf der Startseite für das WLAN mit dem Hinweis, man solle sein VPN aktivieren. Arrrgh.
² Einer meiner anderen Nameserver, der auf ein minimales gentoo aufsetzt, hat interessanterweise diese Anfragen von Anfang an refused, obwohl die Konfiguration nicht wesentlich von der auf dem debian abwich. Grummel.
Nachtrag: Wirksame Gegenmassnahme
Tja, auf die Einfachsten Dinge kommt man zum Schluss: Offenbar sehen die Anfragen ja immer identisch aus, also kann man einfach die Anfrage als solche blocken:
iptables -I INPUT -i eth0 -p udp --destination-port 53 \
-m string --algo kmp --from 30 --hex-string "|010000010000000000000000020001|" -j DROP
und fertig ist die Laube…
Ab Position 30 fängt der eigentliche Query an.
0100 - standard Query mit Recursion (1)
0001 - Eine einzelne Frage ist enthalten
Gegen Ende dann:
0002 - NS wird angefragt
0001 - Class IN