nginx: volcar solicitudes HTTP para depuración

17
  • Ubuntu 10.04.2
  • nginx 0.7.65

Veo algunas solicitudes HTTP extrañas que llegan a mi servidor nginx.

Para comprender mejor lo que está sucediendo, quiero volcar datos de solicitud HTTP completos para tales consultas. (Es decir, volcar todos los encabezados y el cuerpo de la solicitud en algún lugar donde pueda leerlos).

¿Puedo hacer esto con nginx? Alternativamente, ¿hay algún servidor HTTP que me permita hacer esto fuera de la caja, al cual puedo enviar estas solicitudes por medio de nginx?

Actualización: Tenga en cuenta que este cuadro tiene un montón de tráfico normal, y me gustaría evitar capturarlo todo en un nivel bajo (digamos, con tcpdump) y filtrarlo más tarde.

Creo que sería mucho más fácil filtrar un buen tráfico primero en una regla de reescritura (afortunadamente, puedo escribir uno con bastante facilidad en este caso), y luego lidiar solo con tráfico falso.

Y no quiero canalizar tráfico falso a otro cuadro solo para poder capturarlo allí tcpdump.

Actualización 2: para dar un poco más de detalles, la solicitud falsa tiene un parámetro llamado (digamos) fooen su consulta GET (el valor del parámetro puede diferir). Se garantiza que las buenas solicitudes no tendrán este parámetro nunca.

Si puedo filtrar por esto tcpdumpo de ngrepalguna manera, no hay problema, los usaré.

Alexander Gladysh
fuente
Puede que caracterizan / clasificar las solicitudes que considere "raro"? ¿Cómo se podría llegar a una regla que te ayude si no comparten con nosotros lo que es 'falsa' 'normal' y?
hobodave
Yo no pido una regla - Puedo escribir fácilmente a mí mismo. Pido medios a los datos de solicitud HTTP volcado.
Alexander Gladysh
@hobodave: pero de todos modos, ya lo solicitado, he añadido esta información a la pregunta.
Alexander Gladysh

Respuestas:

30

Ajuste la cantidad de líneas previas / posteriores (-B y -A args) según sea necesario:

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

Esto le permite obtener las solicitudes HTTP que desea, en la caja, sin generar un gran archivo PCAP que debe descargar en otro lugar.

Tenga en cuenta que el filtro BPF nunca es exacto, si hay una gran cantidad de paquetes que fluyen a través de cualquier caja, BPF puede y dejará caer paquetes.

oo.
fuente
5

No sé exactamente qué quiere decir con volcar la solicitud, pero puede usar tcpdump y / o wireshark para analizar los datos:

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

Y puede usar wireshark para abrir el archivo y ver la conversación entre servidores.

volcado de memoria
fuente
Gracias, pero tengo bastante tráfico en este servidor (el 99% es bueno), y creo que sería difícil filtrar ese montón de datos para ese falso 1% que necesito.
Alexander Gladysh
... si capturo todo en un nivel tan bajo. :-)
Alexander Gladysh
He actualizado la pregunta para reflejar eso.
Alexander Gladysh
Alexander: bueno, eso significa que 1 de cada 100 solicitudes tendrá los encabezados extraños que estás buscando. Ejecute una captura por un tiempo y luego busque en el registro resultante buscando los encabezados que desea, eso seguramente no es una cantidad insoportable de trabajo.
EEAA
El problema no es el trabajo, sino la cantidad de datos a procesar. (Sin embargo, puede ser soportable, pero, de todos modos, me gustaría ver una solución más amigable).
Alexander Gladysh
0

Si envía las solicitudes a Apache con mod_php instalado, puede usar el siguiente script PHP para volcar las solicitudes:

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

Tenga en cuenta que dado que está utilizando nginx, $_SERVER['REMOTE_ADDR']puede no tener sentido. Tendrá que pasar la IP real a Apache a través de proxy_set_header X-Real-IP $remote_addr;, y puede usar eso en su lugar (o simplemente confiar en que se registre a través de getallheaders()).

hobodave
fuente
Gracias. Pero no tengo PHP en mis servidores. Aún así, la idea es válida para cualquier otro lenguaje de programación compatible con http. :-)
Alexander Gladysh