Layer 7-Angriffe auf Websites umfassen Angriffe auf die Webserverschicht (Nginx, Apache usw.) und Angriffe auf die Anwendungsserverschicht (PHP-Fpm, NodeJS usw.), die sich normalerweise hinter dem Proxyserver (Nginx, Apache) befindet , usw.). Aus Sicht des Netzwerkprotokolls handelt es sich bei beiden um Angriffe auf Anwendungsebene. Aus praktischer Sicht müssen wir diese beiden Fälle jedoch trennen. Der Webserver (Nginx, Apache usw.) stellt in der Regel unabhängig statische Dateien (Bilder, Stile, Skripte) bereit und überträgt Anforderungen für dynamischen Inhalt an den Anwendungsserver (php-fpm, nodejs usw.). Diese Anforderungen werden zu Zielen für Angriffe, da Anwendungsserver beim Generieren von dynamischem Inhalt im Gegensatz zu statischen Anforderungen mehrere um Größenordnungen begrenzte Systemressourcen benötigen, was Angreifer verwenden.
So banal es auch klingt, um sich gegen einen Angriff zu verteidigen, muss er zuerst identifiziert werden. Tatsächlich können nicht nur DDoS-Angriffe zu Site-Fehlern führen, sondern auch andere Gründe, die mit Fehlern von Entwicklern und Systemadministratoren verbunden sind. Zur Vereinfachung der Analyse müssen Sie den Parameter $ request_time zum Nginx-Protokollformat hinzufügen (leider habe ich keine Option für Apache) und Anforderungen an den Anwendungsserver in einer separaten Datei protokollieren:
log_format timed '$remote_addr - $remote_user [$time_local] '
'$host:$server_port "$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ($request_time s.)';
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
access_log /var/log/ngunx/application_access.log timed;
}
Nachdem Sie Protokolle in einer separaten Datei (ohne statische Protokolle) an den Anwendungsserver gesendet haben und die Anforderungszeit in Sekunden angegeben ist, können Sie schnell feststellen, wann der Angriff beginnt, wann die Anzahl der Anforderungen und die Antwortzeit stark zunehmen.
Nachdem Sie den Angriff identifiziert haben, können Sie zur Verteidigung übergehen.
Sehr oft versuchen Systemadministratoren, die Site zu schützen, indem sie die Anzahl der Anforderungen von einer einzelnen IP-Adresse begrenzen. Verwenden Sie dazu 1) die Direktive nginx limit_req_zone ( siehe Dokumentation ), 2) fail2ban und 3) iptables. Natürlich sollten diese Methoden angewendet werden. Diese Schutzmethode ist jedoch seit 10-15 Jahren unwirksam. Dafür gibt es zwei Gründe:
1) Der vom Netzwerk der Bots während eines Angriffs auf der 7. Ebene erzeugte Datenverkehr kann geringer sein als der Datenverkehr eines normalen Site-Besuchers, da ein gewöhnlicher Site-Besucher eine "schwere" Anfrage an den Anwendungsserver (php-fpm) hat , nodejs usw.) Es gibt ungefähr 100 "leichte" Anforderungen zum Herunterladen statischer Dateien, die vom Webserver gesendet werden (Nginx, Apache usw.). Iptables schützt nicht vor solchen Anforderungen, da es den Datenverkehr nur durch quantitative Indikatoren einschränken kann und die Trennung von Anforderungen in Statik und Dynamik nicht berücksichtigt.
2) Der zweite Grund ist die Verteilung des Bot-Netzwerks (der erste Buchstabe ist D in der DDoS-Abkürzung). Der Angriff umfasst normalerweise ein Netzwerk von mehreren tausend Bots. Sie können weniger häufig Anfragen stellen als der durchschnittliche Benutzer. In der Regel berechnet ein Angreifer beim Angriff auf eine Site die Parameter limit_req_zone und fail2ban empirisch. Und konfiguriert das Bot-Netzwerk so, dass dieser Schutz nicht funktioniert. Oft beginnen Systemadministratoren, diese Parameter zu unterschätzen, wodurch echte Clients deaktiviert werden, ohne dass der Schutz vor Bots wesentlich beeinträchtigt wird.
Um eine Site erfolgreich vor DDoS zu schützen, müssen alle möglichen Schutzmaßnahmen auf dem Server im Komplex verwendet werden. In meinem vorherigen Beitrag zu diesem Thema wurde der DDoS-Schutz auf Webserverebene beschriebenEs gibt Links zu Materialien zur Konfiguration von iptables und zu den Parametern des Systemkerns, die auf den optimalen Wert eingestellt werden müssen (dh zunächst die Anzahl der geöffneten Dateien und Sockets). Dies ist eine Voraussetzung, eine notwendige, aber nicht ausreichende Voraussetzung für den Schutz vor Bots.
Darüber hinaus muss ein Schutz erstellt werden, der auf der Erkennung von Bots basiert. Alles, was zum Verständnis der Mechanik der Erkennung von Bots erforderlich ist, wurde im historischen Artikel über Habré ausführlich beschrieben. Das Nginx-Modul zur Bekämpfung von DDoS durch den Autor kyprizel ist in der Bibliothek desselben Autors testcookie-nginx-module implementiert
Es ist eine C-Bibliothek und wird weiterhin von einer kleinen Autorengemeinschaft entwickelt. Wahrscheinlich sind nicht alle Systemadministratoren bereit, eine unbekannte Bibliothek auf einem Produktionsserver zu kompilieren. Wenn Sie zusätzliche Änderungen an der Arbeit der Bibliothek vornehmen müssen, liegt dies völlig außerhalb des Rahmens eines normalen Systemadministrators oder Entwicklers. Glücklicherweise gibt es jetzt neue Funktionen: die Lua-Skriptsprache, die auf dem Nginx-Server ausgeführt werden kann. Es gibt zwei beliebte Builds von Nginx mit einer integrierten Lua-Scripting-Engine: openresty, das ursprünglich von Taobao, dann Cloudfare, inspiriert wurde, und nginx-Extras, die in einigen Linux-Distributionen wie Ubuntu enthalten sind. Beide Optionen verwenden dieselben Bibliotheken, sodass es keinen großen Unterschied macht, welche verwendet werden soll.
Der Bot-Schutz kann auf der Bestimmung der Fähigkeit des Web-Clients basieren, 1) JavaScript-Code auszuführen, 2) Weiterleitungen vorzunehmen und 3) Cookies zu setzen. Von all diesen Methoden erwies sich die Ausführung von JavaScript-Code als am wenigsten vielversprechend, und ich lehnte dies ab, da der JavaScript-Code nicht ausgeführt wird, wenn der Inhalt mit Hintergrundanforderungen (Ajax) geladen ist und das Neuladen der Seite mit JavaScript die verzerrt Statistik der Übergänge zur Site (seit dem Titel Referer). Daher gibt es Weiterleitungen, die Cookies setzen, deren Werte einer Logik unterliegen, die auf dem Client nicht reproduziert werden kann, und die es Clients ohne diese Cookies nicht ermöglichen, auf die Website zu gelangen.
Bei meiner Arbeit habe ich mich auf die Bibliothek leeyiw / ngx_lua_anticc verlassen, die derzeit nicht entwickelt wird, und ich habe die Verbesserungen an meiner apapacy / ngx_lua_anticc-Gabel fortgesetzt , da die Arbeit der ursprünglichen Bibliothek nicht für alles geeignet war .
Um die Abfragezähler in der Bibliothek zu betreiben, werden Speichertabellen verwendet, die Inkr-Methoden unterstützen, die zum Inkrementieren von Zählerwerten und zum Setzen von Werten mit TTL geeignet sind. Das folgende Codefragment erhöht beispielsweise die Anzahl der Anforderungen von einer einzelnen IP-Adresse, wenn für den Client kein Cookie mit einem bestimmten Namen festgelegt ist. Wenn der Zähler noch nicht initialisiert wurde, wird er mit einer TTL von 60 Sekunden auf 1 initialisiert. Nach dem Überschreiten der Anzahl der Anforderungen 256 (in 60 Sekunden) darf der Client die Site nicht mehr betreten:
local anticc = ngx.shared.nla_anticc
local remote_id = ngx.var.remote_addr
if not cookies[config.cookie_name] then
local count, err = anticc:incr(remote_id, 1)
if not count then
anticc:set(remote_id, 1, 60)
count = 1
end
if count >= 256 then
if count == 256 then
ngx.log(ngx.WARN, "client banned by remote address")
end
ngx.exit(444)
return
end
end
Nicht alle Bots sind schädlich. Beispielsweise müssen Sie Such-Bots und Bots von Zahlungssystemen überspringen, die Änderungen des Zahlungsstatus an die Site melden. Es ist gut, wenn Sie eine Liste aller IP-Adressen erstellen können, von denen solche Anforderungen stammen können. In diesem Fall können Sie eine "weiße" Liste erstellen:
local whitelist = ngx.shared.nla_whitelist
in_whitelist = whitelist:get(ngx.var.remote_addr)
if in_whitelist then
return
end
Dies ist jedoch nicht immer möglich. Eines der Probleme ist die Unsicherheit mit den Adressen der Google-Bots. Das Überspringen aller Bots, die Google-Bots fälschen, bedeutet, den Schutz von der Website zu entfernen. Daher verwenden wir das Modul resty.exec, um den Host-Befehl auszuführen:
local exec = require 'resty.exec'
if ngx.re.find(headers["User-Agent"],config.google_bots , "ioj") then
local prog = exec.new('/tmp/exec.sock')
prog.argv = { 'host', ngx.var.remote_addr }
local res, err = prog()
if res and ngx.re.find(res.stdout, "google") then
ngx.log(ngx.WARN, "ip " .. ngx.var.remote_addr .. " from " .. res.stdout .. " added to whitelist")
whitelist:add(ngx.var.remote_addr, true)
return
end
if res then
ngx.log(ngx.WARN, "ip " .. ngx.var.remote_addr .. " from " .. res.stdout .. "not added to whitelist")
else
ngx.log(ngx.WARN, "lua-resty-exec error: " .. err)
end
end
Die Erfahrung zeigt, dass Sie mit einer solchen Schutzstrategie die Website vor einer bestimmten Klasse von Angriffen schützen können, die häufig für unlauteren Wettbewerb eingesetzt werden. Das Verständnis der Angriffsmechanismen und Schutzmethoden hilft, viel Zeit bei erfolglosen Verteidigungsversuchen gegen fail2ban zu sparen. Wenn Sie den Schutz von Drittanbietern (z. B. von Cloudfare) verwenden, wählen Sie die Schutzparameter gezielter aus.
apapacy@gmail.com
9. Mai 2021