Formato legible para humanos para encabezados http con tcpdump


69

Me gustaría ver los encabezados HTTP enviados desde Apache (escuchando en el puerto 80) a Tomcat (en el puerto 4080) en una máquina Linux.

De acuerdo con Wikipedia ,

Los campos de encabezado son pares de nombre-valor separados por dos puntos en formato de cadena de texto sin cifrar.

He intentado algunas variaciones del siguiente tcpdumpcomando:

$ sudo tcpdump -lnX dst port 4080 -c 10

11:29:28.605894 IP SOME_IP.33273 > SOME_IP.4080: P 0:49(49) ack 1 win 23 <nop,nop,timestamp 1191760962 509391143>
    0x0000:  4500 0065 3a9f 4000 3f06 0084 628a 9ec4  E..e:.@.?...b...
    0x0010:  628a 9c97 81f9 0ff0 9e87 eee0 144b 90e1  b............K..
    0x0020:  8018 0017 fb43 0000 0101 080a 4708 d442  .....C......G..B
    0x0030:  1e5c b127 4845 4144 202f 6461 7070 6572  .\.'HEAD./dapper
    0x0040:  5f73 6572 7669 6e67 2f41 644d 6f6e 6b65  _serving/AdMonke
    0x0050:  793f                                     y?

El resultado fue siempre el mismo: una extraña mezcla de galimatías y palabras en inglés (por ejemplo HEAD).

¿Cómo puedo ver los encabezados en un formato legible para humanos?


Tcpdump muestra el paquete completo. Esto incluye los encabezados IP y TCP. AFAIK, no puede mostrar solo la carga útil de TCP.
Zoredache

Respuestas:


93

Aquí hay una frase que se me ocurrió para mostrar los encabezados HTTP de solicitud y respuesta usando tcpdump(que también debería funcionar para su caso):

sudo tcpdump -A -s 10240 'tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | egrep --line-buffered "^........(GET |HTTP\/|POST |HEAD )|^[A-Za-z0-9-]+: " | sed -r 's/^........(GET |HTTP\/|POST |HEAD )/\n\1/g'

Limita los cortes del paquete a 10Kb y solo conoce los comandos GET, POST y HEAD, pero eso debería ser suficiente en la mayoría de los casos.

EDITAR : lo modificó para deshacerse de los búferes en cada paso para que sea más receptivo. Sin embargo, ahora necesita Perl y stdbuf, así que use la versión original si no los tiene: EDITAR : Se cambiaron los objetivos del puerto de script de 80 a 4080, para realmente escuchar el tráfico que ya pasó por Apache, en lugar del tráfico externo directo que llega al puerto 80:

sudo stdbuf -oL -eL /usr/sbin/tcpdump -A -s 10240 "tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)" | egrep -a --line-buffered ".+(GET |HTTP\/|POST )|^[A-Za-z0-9-]+: " | perl -nle 'BEGIN{$|=1} { s/.*?(GET |HTTP\/[0-9.]* |POST )/\n$1/g; print }'

Algunas explicaciones:

  • sudo stdbuf -oL -eL hace que tcpdump se ejecute con buffer de línea
  • El filtro mágico tcpdump se explica en detalle aquí: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep está buscando líneas con GET, HTTP / o POST; o cualquier línea que parezca un encabezado (letras y números seguidos de dos puntos)
  • COMIENZO {$ | = 1} hace que Perl ejecute el buffer de línea
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g agrega una nueva línea antes del comienzo de cada nueva solicitud o respuesta

1
Funciona genial. ¿Podría agregar más detalles sobre cómo funciona esa expresión tcpdump?
Vivek Thomas el

1
aquí se explica la parte 'ip' en parens, por ejemplo: stackoverflow.com/questions/11757477/…
Kibber

Me acabas de salvar tanto dolor de cabeza. Es una pena que solo pueda hacer +1.
Aaron Dobbing

19

Puede obtener algo cercano a lo que desea mediante -A, por ejemplo,

E....c@.@...
.....Ng.d.P..Ch.).....s.......
.A...u.BHEAD / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.google.com
Accept: */*

Recuerde usar -s 0para asegurarse de obtener el paquete completo.

Alternativamente, puede usar wiresharkpara ver los encabezados de forma interactiva.


1
Intenté -Ay -s 0obtuve el mismo resultado.
Adam Matan

2
Intenta sin -X.
Flup

tcpdump -s 0 -A dst port 4080da E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Adam Matan

... que es algo cercano a lo que quieres. Lea desde 'HEAD': esta es la carga de HTTP. Si definitivamente ha utilizado -s 0y no hay nada después HTTP/1.0, no hay encabezados HTTP en la solicitud.
Flup

Gracias. ¿Hay alguna forma de imprimir solo los encabezados de texto, sin la carga útil binaria?
Adam Matan

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.