Der Nginx-Webserver verfügt über einen wunderbaren 444-Antwortcode, der die Verbindung "schließt", ohne Daten zu senden. Diese Funktion ist sehr nützlich, um unechten Datenverkehr zu filtern. Wenn wir sicher sind, dass der Client nach bestimmten Kriterien nicht gültig ist, müssen Sie ihn beispielsweise nicht mit der 403. Antwort benachrichtigen. Es ist effizienter, die Datenübertragung einfach zu stoppen, was häufig die Belastung des Servers erheblich verringern kann.
Empfehlungen zur Verwendung solcher Antworten finden Sie überall in Anweisungen zum Blockieren von Klicks auf Links von beliebten Websites und zu Empfehlungs-Spam, zum Schutz vor DDoS usw.
Und im Allgemeinen könnten diese Tipps im Laufe der Jahre fast ohne zu schauen verwendet werden, aber ... moderne Browser stehen nicht still und präsentieren uns regelmäßig neue Überraschungen.
Obligatorisches ProgrammServer:$ uname -orm FreeBSD 11.1-STABLE amd64
$ nginx -v nginx version: nginx/1.15.0
Kunde: >ver Microsoft Windows [Version 10.0.15063]
Google Chrome 67.0.3396.99 (offizieller Build), (64 Bit)
Firefox Quantum 61.0 (64-Bit)
Ich habe nur die Browser Chrome und Firefox als Erfahrung genommen. Nicht weil der Rest ohne Sünde ist, war nur das unten beschriebene Verhalten bei beiden ziemlich stabil.
Wir haben also eine Website und möchten den Zugang zum Standort ohne Bedingungen und ohne Datenübertragung einschränken:
server { ... location = /code/444 { return 444; } ... }
Warten:
- Der Browser sendet eine Anfrage.
- Der Server empfängt eine Anfrage, schließt die Verbindung und schreibt eine Zeile mit dem Code 444 in das Protokoll.
- Wenn der Browser keine Daten empfängt, zeigt er einen Fehler an und beendet die Kommunikation mit dem Server.
Zur besseren Übersicht zeigen wir unsere Erwartungen mit der Nginx-Protokollzeile an:
18.12.12.29 - - [28/Jun/2018:11:50:10 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
Chrome Realität:
18.12.12.29 - - [28/Jun/2018:11:50:10 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 18.12.12.29 - - [28/Jun/2018:11:50:10 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 18.12.12.29 - - [28/Jun/2018:11:50:15 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 18.12.12.29 - - [28/Jun/2018:11:52:04 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
Chrome hat eine Anfrage gesendet, keine Antwort erhalten und sofort eine weitere Anfrage gesendet. Danach wurde die Website regelmäßig auf Verfügbarkeit überprüft.
Firefox Realität:
18.12.12.29 - - [28/Jun/2018:12:34:38 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:38 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:38 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:38 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:38 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:39 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:40 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:40 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:40 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:40 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:40 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:41 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:41 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:41 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:34:41 +0000] "GET /code/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0"
Firefox entschied sich, nicht kleinlich zu sein und schickte sofort 20 Anfragen (manchmal 10). Aber dann werden keine "Überprüfungen" durchgeführt.
Gleichzeitig meldet es im Debugger wie für eine Anfrage:
Wenn wir also erwarten, eine Anfrage vom Kunden zu erhalten, erhalten wir tatsächlich 3-20 Anfragen. Zusätzlich zu Aufrufen, die für uns völlig unnötig sind, besteht die Gefahr, dass ein solches Protokoll beispielsweise einem Anti-DDoS-Skript zugeführt und diese IP blockiert wird. Und es scheint die halbe Mühe zu sein, denn wir haben ihm bereits 444 "gegeben", das heißt, wir haben kein Mitleid mit ihm, aber es kann umgekehrt passieren - wir werden dem Kunden zeigen, was wir überhaupt nicht geplant haben.
Ändern Sie die Konfiguration:
map $http_referer $code_if { "~*https://habr.com/post/415565/" 1; "http://tison.ru/ref" 1; default 0; } ... server { ... location = /code/444 { return 444; } ... location = /codeif/444 { if ( $code_if = 1 ) { return 444; } add_header "Content-Type" "text/html; charset=UTF-8" always; return 200 "Expected code 444"; } ... }
Hier haben wir die Lieferung von Inhalten an alle Kunden mit einem Referrer verboten "
https://habr.com/post/415565/
"beim Wechsel zur Seite
tison.ru/codeif/444Warten:
In Kenntnis der oben bereits beschriebenen Funktionen gehen wir davon aus, dass Browser mehr als eine Anfrage stellen, jedoch nicht die 200. Antwort vom Server erhalten.
Auch in Form eines Protokolls erwarten wir eine oder mehrere Zeilen des Formulars:
18.12.12.29 - - [28/Jun/2018:12:52:02 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
Beim Debuggen in der Konsole funktioniert alles wie erwartet. Der Server hat die Verbindung geschlossen und wir haben keinen Inhalt erhalten:
$ curl --referer "https://habr.com/post/415565/" tison.ru/codeif/444 curl: (52) Empty reply from server
Nun, Browser-Realität.
Chrome:
18.12.12.29 - - [28/Jun/2018:12:58:12 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 18.12.12.29 - - [28/Jun/2018:12:58:12 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" 18.12.12.29 - - [28/Jun/2018:12:58:13 +0000] "GET /codeif/444 HTTP/1.1" 200 17 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
Firefox:
18.12.12.29 - - [28/Jun/2018:12:56:29 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:29 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:29 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:29 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:30 +0000] "GET /codeif/444 HTTP/1.1" 444 0 "http://tison.ru/ref" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:31 +0000] "GET /codeif/444 HTTP/1.1" 200 17 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0" 18.12.12.29 - - [28/Jun/2018:12:56:31 +0000] "GET /favicon.ico HTTP/1.1" 200 6782 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0"
Nachdem beide Browser mehrere "ehrliche" Anforderungsanfragen gestellt hatten, löschten sie den Referrer und zeigten ruhig die blockierte Seite an. Firefox tut dies jedoch nicht immer. Bei meinen Tests ~ in 15% der Anfragen, was bei der Analyse noch mehr hilft.
Dieses Verhalten wurde lange beobachtet, aber als genau Chrome und Firefox auf diese Betriebsart umgestellt haben, kann ich nicht sagen. Aber auch und wie lange dieser Modus noch funktioniert.
Daher führt die Verwendung von
return 444 heute nicht immer zu den erwarteten Ergebnissen. Morgen freuen wir uns auf weitere Browserentwickler.