nginx: HTTP-Anfragen zum Debuggen sichern

16
  • Ubuntu 10.04.2
  • Nginx 0,7,65

Ich sehe einige seltsame HTTP-Anfragen an meinen Nginx-Server.

Um besser zu verstehen, was los ist, möchte ich für solche Abfragen ganze HTTP-Anforderungsdaten sichern. (Dh alle Anforderungsheader und -körper werden irgendwo abgelegt, wo ich sie lesen kann.)

Kann ich das mit Nginx machen? Gibt es alternativ einen HTTP-Server, mit dem ich diese Anfragen über Nginx übermitteln kann?

Update: Beachten Sie, dass diese Box eine Menge normalen Datenverkehrs hat, und ich möchte vermeiden, dass alles auf niedriger Ebene (z. B. mit tcpdump) erfasst und später herausgefiltert wird.

Ich denke, es wäre viel einfacher, guten Datenverkehr zuerst in einer Umschreiberegel zu filtern (zum Glück kann ich in diesem Fall eine recht einfach schreiben) und dann nur falschen Datenverkehr zu behandeln.

Und ich möchte gefälschten Datenverkehr nicht auf eine andere Box lenken, nur um ihn dort mit zu erfassen tcpdump.

Update 2: Um ein bisschen mehr Details zu geben, haben gefälschte Requests einen Parameter namens (say) fooin ihrer GET-Abfrage (der Wert des Parameters kann abweichen). Gute Anfragen haben diesen Parameter garantiert nie.

Wenn ich danach filtern kann tcpdumpoder ngrepirgendwie - kein Problem, werde ich diese verwenden.

Alexander Gladysh
quelle
Können Sie die Anforderungen charakterisieren / klassifizieren, die Sie für "seltsam" halten? Wie könnte man sich eine Regel ausdenken, um Ihnen zu helfen, wenn Sie uns nicht mitteilen, was „normal“ und „falsch“ ist?
Hobodave
Ich frage nicht nach einer Regel - ich kann sie leicht selbst schreiben. Ich bitte um Mittel, um HTTP-Anforderungsdaten zu sichern.
Alexander Gladysh
@hobodave: aber trotzdem habe ich, seit du gefragt hast, diese Informationen zu der Frage hinzugefügt.
Alexander Gladysh

Antworten:

29

Passen Sie die Anzahl der Pre- / Post-Zeilen (-B und -A-Argumente) nach Bedarf an:

tcpdump -n -S -s 0 -A 'tcp dst port 80' | grep -B3 -A10 "GET /url"

Auf diese Weise können Sie die gewünschten HTTP-Anforderungen in der Box abrufen, ohne eine große PCAP-Datei zu generieren, die Sie an anderer Stelle auslagern müssen.

Beachten Sie, dass der BPF-Filter niemals genau ist. Wenn eine große Anzahl von Paketen durch eine Box fließt, kann und wird BPF Pakete verwerfen.

oo.
quelle
5

Ich weiß nicht genau, was Sie mit dump the request meinen, aber Sie können tcpdump und / oder wireshark verwenden , um die Daten zu analysieren:

# tcpdump port 80 -s 0 -w capture.cap

Mit wireshark können Sie die Datei öffnen und die Konversation zwischen Servern verfolgen.

Core-Dump
quelle
Danke, aber ich habe ziemlich viel Verkehr auf diesem Server (99% davon sind gut), und ich denke, dass es schwierig sein würde, diese Datenmenge für diese falschen 1% herauszufiltern, die ich benötige.
Alexander Gladysh
... wenn ich das alles auf so niedrigem Niveau einfange. :-)
Alexander Gladysh
Ich habe die Frage entsprechend aktualisiert.
Alexander Gladysh
Alexander - das bedeutet, dass 1 von 100 Anfragen die seltsamen Überschriften enthält, nach denen Sie suchen. Führen Sie ein Capture für eine Weile aus und durchsuchen Sie dann das resultierende Protokoll nach den gewünschten Headern - das ist sicherlich kein unerträglicher Arbeitsaufwand.
EEAA
Das Problem ist nicht die Arbeit, sondern die zu verarbeitende Datenmenge. (Es mag erträglich sein, aber ich würde trotzdem gerne eine freundlichere Lösung sehen.)
Alexander Gladysh
0

Wenn Sie die Anfragen an Apache mit installiertem mod_php per Proxy senden, können Sie die Anfragen mit dem folgenden PHP-Skript sichern:

<?php
$pid = getmypid();
$now = date('M d H:i:s');
$fp = fopen('/tmp/intrusion.log', 'a');

if (!function_exists('getallheaders')) 
{ 
    function getallheaders() 
    { 
           $headers = ''; 
       foreach ($_SERVER as $name => $value) 
       { 
           if (substr($name, 0, 5) == 'HTTP_') 
           { 
               $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 
           } 
       } 
       return $headers; 
    } 
} 

function ulog ($str) {
    global $pid, $now, $fp;
    fwrite($fp, "$now $pid {$_SERVER['REMOTE_ADDR']} $str\n");
}

foreach (getallheaders() as $h => $v) {
    ulog("H $h: $v");
}
foreach ($_GET as $h => $v) {
    ulog("G $h: $v");
}
foreach ($_POST as $h => $v) {
    ulog("P $h: $v");
}
fclose($fp);

Da Sie Nginx verwenden, ist dies $_SERVER['REMOTE_ADDR']möglicherweise sinnlos. Sie müssen die reale IP über an Apache übergeben proxy_set_header X-Real-IP $remote_addr;und können diese stattdessen verwenden (oder sich einfach darauf verlassen, dass sie über protokolliert wird getallheaders()).

Hobodave
quelle
Vielen Dank. Aber ich habe kein PHP auf meinen Servern. Trotzdem gilt die Idee für alle anderen http-fähigen Programmiersprachen. :-)
Alexander Gladysh