Verteidigen Sie Ihren Webserver vor Angriffen mit verteilten Denial-of-Services (DDos)

In der Computersicherheit wird schnell deutlich, dass die Verhinderung von Computerangriffen viel schwieriger ist als der Angriff auf Computer. Ein gutes Beispiel für eine einfache Methode, um das Funktionieren einer Website zu verhindern, ist ein verteilter Denial-of-Service- oder DDoS-Angriff, bei dem eine Anzahl von Computern, die im Internet gefährdet sind, Web- (oder andere Protokoll-) Anforderungen auf einem schlechten Server stellt. Wenn die angeforderte Webseite eine Menge serverseitiger Verarbeitung erfordert, hindert die aus den kombinierten Anforderungen resultierende Last den Webserver daran, auf legitime Anforderungen zu reagieren, wodurch der Dienst abgelehnt wird. Da Tech-Recipes.com kürzlich einem solchen Angriff ausgesetzt war, hatten wir den Eindruck, dass es für andere von Vorteil sein könnte, wenn wir die Schritte beschreiben, die wir in unserer Antwort unternommen haben.


Hinweis: Die folgenden Informationen sind für UNIX-basierte Server relevant, auf denen Apache ausgeführt wird (andere Plattformen und Software sind jedoch möglicherweise anwendbar). Voraussetzung für diesen Ansatz ist die Verwendung von iptables, was wahrscheinlich bedeutet, dass Sie Root-Zugriff auf den Server benötigen. Dies wird Ihnen wahrscheinlich nicht helfen, wenn Sie Shared Hosting verwenden. Es tut uns leid! In diesem Fall wenden Sie sich am besten an Ihren Internetdienstanbieter (viel Glück), da es in seinem besten Interesse ist, hohe Belastungen auf den gemeinsam genutzten Servern zu vermeiden. Es ist jedoch wahrscheinlich, dass Ihre Domain-Dienste vorübergehend deaktiviert werden, was definitiv der Fall ist nicht die beste Lösung aus Ihrer Sicht.

Um die Auswirkungen eines Denial-of-Service-Angriffs zu minimieren, sollten Sie sich in Echtzeit auf Probleme mit Ihrem Webserver aufmerksam machen. Es stehen mehrere Serverüberwachungsdienste zur Verfügung. Wir verwenden sowohl Pingdom als auch SiteUptime. Mit diesen Diensten erhalten wir redundante Benachrichtigungen über Serviceunterbrechungen, die per SMS an unsere Mobiltelefone und an mehrere E-Mail-Adressen gesendet werden (von denen keine selbstverständlich von unseren überwachten Servern behandelt wird). Mit diesen Diensten werden wir innerhalb einer Minute über eine fehlgeschlagene Anfrage an unsere Produktionsserver informiert.

Bevor Sie bestimmte Anti-DDoS-Techniken implementieren oder Hilfe von einem DDos Protection-Dienst anfordern, sollten Sie sicherstellen, dass das Problem tatsächlich ein DDoS-Angriff ist. Dienste können eine Anfrage aus einer Reihe von Gründen nicht beantworten, darunter die ausführbare Datei, die den Dienst unerwartet beendet, der ISP, auf dem der Server einen Netzwerk- oder Serverausfall erlebt, oder ein anderer sich selbst korrigierender Fehler in der Matrix. Um zu ermitteln, ob der Dienst aufgrund eines DDoS-Fehlers ausfällt, und um Informationen zu sammeln, die erforderlich sind, um Maßnahmen gegen den Angriff zu ergreifen, müssen Sie zuerst herumgraben.

Sie benötigen Zugriff auf Ihr access_log, die Protokolldatei, die für jede an Ihren Webserver gesendete Anforderung einen Texteintrag enthält. Diese Datei kann an vielen Stellen ausgeblendet werden und hängt von der Server-Konfiguration ab. Im Zweifelsfall können Sie die Dokumentation des Internetdienstanbieters überprüfen (nach Zugriffsprotokoll suchen). Die Protokolldaten sind möglicherweise über eine Webkonsole verfügbar, aber es ist optimal, wenn Sie über Shell-Zugriff auf Ihren Server verfügen. Wenn die Online-Hilfe Ihres Internetdienstanbieters beim Auffinden des Zugriffsprotokolls nicht so hilfreich ist, können Sie den UNIX-Befehl find verwenden.

Wenn Sie Ihr Zugriffsprotokoll gefunden haben, wechseln Sie in das Verzeichnis, in dem sich das Protokoll befindet, und führen Sie den Befehl tail mit der Option -f aus.

tail -f access_log

Der Befehl tail allein zeigt die letzten 10 Zeilen der angegebenen Datei an und wird dann beendet. Die Option -f weist tail an, nach der Anzeige der letzten 10 Zeilen weiterzulaufen, und zeigt nachfolgende Zeilen an, die der Datei hinzugefügt werden. Sie werden wahrscheinlich eine Vielzahl von Einträgen sehen. Wenn nach der Standardeinstellung 10 keine Protokollnachrichten angezeigt werden, sehen Sie entweder die falsche Datei oder der Webserver ist tot oder es wird sonst kein Datenverkehr angezeigt. Es ist möglich, dass ein Server viele Websites hosten kann und jede über eine separate access_log-Datei verfügen kann. Stellen Sie also sicher, dass Sie die richtige verwenden. Wenn der Dienst tot ist, können Sie ihn durch den geeigneten Mechanismus wiederbeleben. Wir werden von jetzt an davon ausgehen, dass Sie eine Unzahl von Zugriffsprotokollnachrichten sehen, die sehr ähnlich aussehen (wahrscheinlich dieselbe URL), die keinen gültigen oder keinen Referrer haben (wenn der Referrer slashdot.org ist oder digg.com, na gut, dann können Sie sowohl glücklich als auch traurig sein, dass der Datenverkehr (obwohl der Server lähmt, legitim ist) und eine Reihe verschiedener IP-Adressen haben. Während unserer letzten Belagerung gab es so viele falsche Anfragen, dass nur sehr wenige legitime Anfragen in die Datei access_log gelangten. Hier ein paar Zeilen aus unserem access_log während des Angriffs:

220.255.7.204 - - [07 / Jul / 2008: 19: 28: 18 -0700] "GET /modules.php?name=Forums&file=index HTTP / 1.1" 200 0 "-" "Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

220.255.7.209 - - [07 / Jul / 2008: 19: 28: 18 -0700] “GET /modules.php?name=Forums&file=index HTTP / 1.1” 200 0 “-” “Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

220.255.7.208 - - [07 / Jul / 2008: 19: 28: 18 -0700] “GET /modules.php?name=Forums&file=index HTTP / 1.1” 200 0 “-” “Mozilla / 4.0 (kompatibel; MSIE 6.0 ; Windows NT 5.1; SV1; .NET CLR 1.1.4322) "

71.232.78.53 - - [07 / Jul / 2008: 19: 28: 19 -0700] “GET /modules.php?name=Forums&file=index HTTP / 1.1” 200 14313 “-” “Mozilla / 4.0 (kompatibel; MSIE 7.0 ; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727) "

Wenn Sie mit der Standardstruktur von Apaches access_log nicht vertraut sind, ist der erste Wert die Quell-IP-Adresse der Anforderung. Datum und Uhrzeit der Anforderung sind in eckigen Klammern angegeben, und die erste Zeichenfolge in Anführungszeichen ist die HTTP-Anforderung gemacht. In unserem Beispiel war die Anfrage immer gleich: „GET /modules.php?name=Forums&file=index HTTP / 1.1“ - eine GET-Anfrage der URL (/modules.php?….) Und des verwendeten HTTP-Protokolls (1.1 ).Der verwendete Teil der URL ist wichtig, da dies die einzige Sache ist, mit der die fehlerhaften IP-Adressen identifiziert werden können. Die zweite Zeichenfolge in Anführungszeichen ist die verweisende URL. In unserem Fall gibt es keine, daher erscheint sie als "-", was dem Verdacht, dass es sich um einen DDoS-Angriff handelt, Glaubwürdigkeit verleiht. Die verbleibende Zeichenfolge beschreibt die Plattform und Software, die die Anforderung gestellt hat und für uns nicht sehr aussagekräftig oder hilfreich ist, da sie leicht gefälscht werden kann.

Nun, da wir wissen, dass ein DDoS-Angriff im Gange ist, benötigen wir eine Liste der an dem Angriff beteiligten IP-Adressen, um ihre nachfolgenden Anforderungen mit iptables zu blockieren. In dem obigen Beispiel für access_log weiß ich, dass die angeforderte URL-Komponente "/modules.php?name=Forums&file=index" verwendet werden kann, um das access_log zu durchsuchen. Weil es Sonderzeichen wie & und? Enthält. Da die meisten UNIX-Shells etwas sehr anderes interpretieren, ist es eine gute Idee, die Suchzeichenfolge in Anführungszeichen in allen Befehlen zu setzen, die sie verwenden. Der folgende Befehl greift nur die Zeilen in access_log auf, die mit der obigen URL-Komponente übereinstimmen, und gibt eine Liste der IP-Adressen zurück, die ihn angefordert haben, sowie eine Zählung, wie oft jede IP-Adresse die Anforderung gestellt hat, sortiert nach der Anzahl.

fgrep "/modules.php?name=Forums&file=index" Zugriffsprotokoll | schneide -d \ -f1 | sort -n | uniq -c | sort -rn

Der Befehl fgrep ist ein schnelles grep, das nicht nach regulären Ausdrücken sucht und riesige Protokolldateien wesentlich effizienter reißen kann. Wenn Ihr System es aus unerfindlichen Gründen nicht hat, ersetzen Sie fgrep durch den alten grep. Ersetzen Sie den Namen Ihres Zugriffsprotokolls, wenn es sich von access_log unterscheidet. Beachten Sie, dass in der Option cut -d \ nach dem Backslash zwei Leerzeichen stehen. Diese Befehlsfolge wird die übereinstimmenden Zeilen in access_log (fgrep) abrufen, das erste durch Leerzeichen getrennte Feld extrahieren (ausschneiden), numerisch sortieren (sort -n), sie zu einer Liste eindeutiger IP-Adressen zusammenfassen und die Vorkommen zählen (uniq), und sortieren Sie sie numerisch in umgekehrter Reihenfolge, sodass die IP-Adressen mit den höchsten Zählern an erster Stelle stehen. Hier ist ein Beispiel für die Ausgabe:

21889 71.232.78.53
17181 220.255.7.208
16162 220.255.7.209
16142 220.255.7.204

Sie werden wahrscheinlich zwei Gruppen sehen, einige IP-Adressen mit einer großen Anzahl von Anfragen (Hunderte, Tausende) und einige mit nur wenigen, vielleicht auch zig Anfragen. Wenn Sie die Anzahl der Anforderungen auswählen, die die beiden Gruppen voneinander trennen, müssen Sie vorsichtig sein, da Sie keine legitimen Anforderungen blockieren möchten. Wenn Sie anfangen, IP-Adressen von oben auf der Liste zu blockieren, wissen Sie wahrscheinlich, wann sich die Zahlen ändern, und werden zu legitimen scheinbaren Werten, wie ein Sprung von vielen Hunderten von Treffern auf einige Dutzend Treffer. Wenn möglich, kopieren Sie die Ausgabe des obigen Befehls in eine beliebige Form eines Texteditors, um sie immer griffbereit zu haben. Ein Hinweis: Wenn Ihr access_log nicht häufig gedreht wird (der Inhalt wird an einen anderen Speicherort kopiert und möglicherweise komprimiert), kann dies sehr umfangreich werden. Sie können den Befehl tail auf eine andere Weise verwenden, damit dieser Befehl schneller ausgeführt wird. Dies wird wahrscheinlich Ihrem geschätzten Server gefallen. Mit dem Befehl „tail -10000 access_log“ werden die letzten 10.000 Zeilen von access_log übernommen und die Verarbeitung wird fortgesetzt (Sie können 10000 ändern zu einer Anzahl von Ihnen):

tail -10000 access_log | fgrep "/modules.php?name=Forums&file=index" | schneide -d \ -f1 | sort -n | uniq -c | sort -rn

Da Sie nun wissen, welche IP-Adressen Sie blockieren müssen, ist es höchste Zeit, das iptable-Gesetz festzulegen. Das iptables-System kann viele verschiedene Vorgänge ausführen. Zum Glück ist das Blockieren einer einzelnen IP-Adresse eine der einfacheren Konfigurationen. Verwenden Sie den Befehl, um alle Anforderungen von einer IP-Adresse wie 71.232.78.53 zu blockieren:

iptables -A INPUT -s 71.232.78.53 -j DROP

Wenn Sie nicht als root am Server angemeldet sind, fügen Sie vor diesem Befehl einfach ein "sudo" hinzu und geben Sie Ihr Kennwort ein, wenn Sie dazu aufgefordert werden. Dieser eine Befehl fügt dem iptables-System eine temporäre Regel hinzu, um alle Pakete zu löschen, die von der angegebenen IP-Adresse stammen. Dieser Effekt ist vorübergehend, da er nach einem Neustart nicht bestehen bleibt. Wenn Sie diese Änderungen dauerhaft machen möchten (wahrscheinlich keine gute Idee, aber auch nicht so schlimm, wenn Sie einen Neustart planen, um Speicherlecks freizugeben), können Sie versuchen, sie auszuführen

/etc/init.d/iptables speichern

Dieser Befehl wird entweder funktionieren und Sie wissen lassen, dass er funktioniert hat, oder er wird fehlerhaft ausgeführt. Im letzteren Fall können Sie die iptables-Befehle je IP-Adresse wiederholen, um sie erneut zu blockieren.

Wenn Sie Anforderungen von mehreren IP-Adressen innerhalb desselben Subnetzes erhalten, können Sie das Subnetz in einem einzigen iptables-Befehl blockieren. In unserem Fall hatten wir eine Reihe von IP-Adressen aus den Subnetzsendeanforderungen von 220.255.7.0. Anstatt den Befehl iptables einige hundert Mal zu wiederholen, vereinfacht die Subnetzkürzel für den Befehl iptables diese Aufgabe erheblich:

iptables -A INPUT -s 220.255.7.0/24 -j DROP

Ich würde nicht mehr als ein Subnetz der Klasse C gleichzeitig blockieren, wie oben gezeigt. Wenn Sie eine Reihe von Anforderungen von IP-Adressen sehen, bei denen die ersten drei Nummern in der IP-Adresse identisch sind, befinden sich alle im selben Subnetz der Klasse C, und Sie können sie alle mithilfe der ersten drei durch Punkte getrennten Nummern blockieren gefolgt von einem .0 / 24 wie oben.

Da ein DDoS-Angriff möglicherweise andauert und möglicherweise mehr Maschinen im Laufe der Zeit an dem Angriff teilnehmen, lohnt es sich möglicherweise, ein schnelles Skript zum einfachen Blockieren einer IP-Adresse zu erstellen. Ich habe das folgende Skript geschrieben und in / usr / sbin / block abgelegt

#! / bin / bash

iptables -A INPUT -s $ 1 -j DROP

Sobald die Datei vorhanden ist, können Sie sie mit ausführbar machen chmod + x / usr / sbin / block und dann verwenden Sie es wie:

Block 71.232.78.53

Jedes System ist einzigartig und verfügt über verschiedene Anwendungen und Anwendungsversionen, die an verschiedenen Orten installiert sind. Ihre Laufleistung kann daher mit den obigen Anweisungen variieren.