nginx: zrzuć żądania HTTP dotyczące debugowania

17
  • Ubuntu 10.04.2
  • nginx 0,7.65

Widzę dziwne żądania HTTP przychodzące na mój serwer Nginx.

Aby lepiej zrozumieć, co się dzieje, chcę zrzucić całe dane żądania HTTP dla takich zapytań. (Tj. Zrzucam wszystkie nagłówki i treści żądania gdzieś, gdzie mogę je przeczytać).

Czy mogę to zrobić za pomocą nginx? Alternatywnie, czy jest jakiś serwer HTTP, który pozwala mi to zrobić po wyjęciu z pudełka, do którego mogę proxy tych żądań za pomocą nginx?

Aktualizacja: Zauważ, że to pole ma sporo normalnego ruchu i chciałbym uniknąć przechwytywania go na niskim poziomie (powiedzmy, z tcpdump) i filtrowania go później.

Myślę, że znacznie łatwiej byłoby najpierw odfiltrować dobry ruch według reguły przepisywania (na szczęście w tym przypadku mogę dość łatwo napisać), a następnie zająć się tylko fałszywym ruchem.

I nie chcę przekierowywać fałszywego ruchu do innej skrzynki tylko po to, aby móc go tam uchwycić tcpdump.

Aktualizacja 2: Aby podać nieco więcej szczegółów, fałszywe żądanie ma parametr o nazwie (powiedzmy) foow swoim zapytaniu GET (wartość parametru może się różnić). Gwarantujemy, że dobre żądania nigdy nie będą miały tego parametru.

Jeśli mogę to filtrować tcpdumplub ngrepjakoś - nie ma problemu, użyję ich.

Alexander Gladysh
źródło
Czy potrafisz scharakteryzować / sklasyfikować wnioski, które uważasz za „dziwne”? Jak można wymyślić regułę, która pomoże ci, jeśli nie podzielisz się z nami tym, co „normalne” i „fałszywe”?
hobodave 13.03.11
Nie pytam o regułę - sam mogę ją łatwo napisać. Proszę o zrzucenie danych żądania HTTP.
Alexander Gladysh
@hobodave: ale i tak, skoro o to pytałeś, dodałem tę informację do pytania.
Alexander Gladysh

Odpowiedzi:

30

Dostosuj liczbę linii przed / po (argumenty -B i -A) zgodnie z potrzebami:

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

Dzięki temu możesz odbierać żądane żądania HTTP w pudełku, bez generowania ogromnego pliku PCAP, który musisz przenieść gdzie indziej.

Należy pamiętać, że filtr BPF nigdy nie jest dokładny, jeśli przez dowolne pudełko przepływa duża liczba pakietów, BPF może i upuści pakiety.

z oo
źródło
5

Nie wiem dokładnie, co masz na myśli mówiąc o zrzucie żądania, ale możesz użyć tcpdump i / lub wireshark do analizy danych:

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

I możesz użyć wireshark, aby otworzyć plik i zobaczyć konwersację między serwerami.

rdzeń rdzeniowy
źródło
Dzięki, ale mam dość ruchu na tym serwerze (99% z tego jest dobre) i myślę, że ciężko byłoby odfiltrować tę wiązkę danych dla tego fałszywego 1%, którego potrzebuję.
Alexander Gladysh
... jeśli uchwycę to wszystko na tak niskim poziomie. :-)
Alexander Gladysh
Zaktualizowałem pytanie, aby to odzwierciedlić.
Alexander Gladysh
Alexander - to znaczy, że 1 na 100 żądań będzie zawierał dziwne nagłówki, których szukasz. Uruchom przechwytywanie przez chwilę, a następnie przeszukaj wynikowy dziennik, szukając żądanych nagłówków - z pewnością nie jest to nieznośny nakład pracy.
EEAA
Problemem nie jest praca, ale ilość danych do przetworzenia. (Może to być znośne, ale i tak chciałbym znaleźć bardziej przyjazne rozwiązanie.)
Alexander Gladysh
0

Jeśli proxy do Apache z zainstalowanym mod_php jest zainstalowany, możesz użyć następującego skryptu PHP do zrzucenia żądań:

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

Zauważ, że skoro używasz nginx, $_SERVER['REMOTE_ADDR']może to być bezcelowe. Musisz przekazać prawdziwy adres IP do Apache przez proxy_set_header X-Real-IP $remote_addr;i możesz go użyć zamiast tego (lub po prostu polegać na logowaniu się przez niego getallheaders()).

hobodave
źródło
Dziękuję Ci. Ale nie mam PHP na moich serwerach. Mimo to pomysł jest ważny dla każdego innego języka programowania opartego na HTTP. :-)
Alexander Gladysh