nginx: dump delle richieste HTTP per il debug


17
  • Ubuntu 10.04.2
  • nginx 0.7.65

Vedo alcune strane richieste HTTP in arrivo sul mio server nginx.

Per capire meglio cosa sta succedendo, voglio scaricare interi dati di richiesta HTTP per tali query. (Vale a dire scaricare tutte le intestazioni e il corpo delle richieste da qualche parte in cui posso leggerle.)

Posso farlo con nginx? In alternativa, esiste un server HTTP che mi consente di farlo immediatamente, al quale posso eseguire il proxy di queste richieste tramite nginx?

Aggiornamento: nota che questa casella ha un sacco di traffico normale e vorrei evitare di catturarlo tutto a basso livello (diciamo, con tcpdump) e filtrarlo in seguito.

Penso che sarebbe molto più semplice filtrare il buon traffico prima in una regola di riscrittura (fortunatamente posso scriverne uno abbastanza facilmente in questo caso), e poi occuparmi solo di traffico fasullo.

E non voglio incanalare il traffico fasullo verso un'altra casella solo per poterlo catturare lì tcpdump.

Aggiornamento 2: per fornire ulteriori dettagli, le richieste fasulle hanno un parametro chiamato (diciamo) foonella loro query GET (il valore del parametro può differire). Le buone richieste sono garantite per non avere mai questo parametro.

Se riesco a filtrare in base a questo tcpdumpo in ngrepqualche modo - nessun problema, userò questi.


Puoi caratterizzare / classificare le richieste che ritieni "strane"? Come si potrebbe trovare una regola per aiutarti se non condividi con noi ciò che è "normale" e "falso"?
hobodave,

Non chiedo una regola, posso scriverlo facilmente da solo. Chiedo mezzi per scaricare i dati di richiesta HTTP.
Alexander Gladysh,

@hobodave: ma comunque, da quando l'hai chiesto, ho aggiunto queste informazioni alla domanda.
Alexander Gladysh,

Risposte:


30

Regola il numero di righe pre / post (argomenti -B e -A) secondo necessità:

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

Ciò ti consente di ottenere le richieste HTTP che desideri, sulla scatola, senza generare un enorme file PCAP che devi scaricare altrove.

Tieni presente che il filtro BPF non è mai esatto, se ci sono molti pacchetti che scorrono attraverso qualsiasi scatola, BPF può e rilascerà i pacchetti.


5

Non so esattamente cosa intendi con il dump della richiesta ma puoi usare tcpdump e / o WireShark per analizzare i dati:

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

E puoi usare WireShark per aprire il file e vedere la conversazione tra i server.


Grazie, ma ho un bel po 'di traffico su questo server (il 99% è buono), e penso che sarebbe difficile filtrare quel mucchio di dati per quel falso 1% di cui ho bisogno.
Alexander Gladysh,

... se catturo tutto a un livello così basso. :-)
Alexander Gladysh,

Ho aggiornato la domanda per riflettere ciò.
Alexander Gladysh,

Alexander - beh, ciò significa che 1 su 100 richieste avrà le strane intestazioni che stai cercando. Esegui una cattura per un po 'e poi cerca nel registro risultante cercando le intestazioni che desideri - sicuramente non è una quantità insopportabile di lavoro.
SEE

Il problema non è il lavoro, ma la quantità di dati da elaborare. (Potrebbe essere sopportabile, ma, comunque, mi piacerebbe vedere una soluzione più amichevole.)
Alexander Gladysh,

0

Se esegui il proxy delle richieste su Apache con mod_php installato, puoi utilizzare il seguente script PHP per scaricare le richieste:

<?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);

Nota che dal momento che stai usando nginx $_SERVER['REMOTE_ADDR']potrebbe essere inutile. Dovrai passare il vero IP ad Apache tramite proxy_set_header X-Real-IP $remote_addr;e puoi invece usarlo (o fare semplicemente affidamento sul fatto che sia registrato tramite getallheaders()).


Grazie. Ma non ho PHP sui miei server. Tuttavia l'idea è valida per qualsiasi altro linguaggio di programmazione compatibile con http. :-)
Alexander Gladysh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.