Formato legível humano para cabeçalhos http com tcpdump

69

Gostaria de visualizar os cabeçalhos HTTP enviados do Apache (escutando na porta 80) para o Tomcat (na porta 4080) em uma máquina Linux.

Segundo a Wikipedia ,

Os campos do cabeçalho são pares nome-valor separados por dois pontos no formato de sequência de texto não criptografado.

Eu tentei algumas variações do seguinte 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?

O resultado sempre foi o mesmo - uma mistura estranha de palavras sem sentido e inglesas (por exemplo HEAD).

Como posso visualizar os cabeçalhos em um formato legível por humanos?

Adam Matan
fonte
Tcpdump mostra o pacote inteiro. Isso inclui os cabeçalhos IP e TCP. AFAIK, você não pode exibir apenas a carga útil do TCP.
Zoredache

Respostas:

93

Aqui está uma linha que eu criei para exibir cabeçalhos HTTP de solicitação e resposta usando tcpdump(o que também deve funcionar no seu 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 o corte de pacotes em 10 KB e apenas conhece os comandos GET, POST e HEAD, mas isso deve ser suficiente na maioria dos casos.

EDIT : modificado para se livrar dos buffers a cada passo para torná-lo mais responsivo. No entanto, agora é necessário o Perl e o stdbuf, portanto, use a versão original se você não os tiver: EDIT : Destinos de porta de script alterados de 80 a 4080, para realmente ouvir o tráfego que já passou pelo apache, em vez de o tráfego externo direto chegar à porta 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 }'

Algumas explicações:

  • sudo stdbuf -oL -eL faz o tcpdump rodar em buffer de linha
  • O filtro mágico tcpdump é explicado em detalhes aqui: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • O grep está procurando por qualquer linha com GET, HTTP / ou POST; ou qualquer linha que pareça um cabeçalho (letras e números seguidos de dois pontos)
  • BEGIN {$ | = 1} faz com que o perl seja executado no buffer de linha
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g adiciona uma nova linha antes do início de cada nova solicitação ou resposta
Kibber
fonte
11
Funciona bem. Você poderia adicionar mais detalhes sobre como essa expressão tcpdump funciona?
Vivek Thomas
11
a parte 'ip' em parens é explicada aqui, por exemplo: stackoverflow.com/questions/11757477/…
Kibber
Você acabou de me salvar muita dor de cabeça. Pena que eu posso apenas +1.
Aaron Dobbing 10/09/2015
19

Você pode obter algo próximo do que deseja usando -A, por exemplo,

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

Lembre-se de usar -s 0para garantir que você obtenha o pacote inteiro.

Como alternativa, você pode usar wiresharkpara visualizar os cabeçalhos interativamente.

Flup
fonte
11
Tentei -Ae -s 0, tenho a mesma saída.
Adam Matan
2
Tente sem -X.
Flup
tcpdump -s 0 -A dst port 4080E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Adam Matan
... que é algo parecido com o que você deseja. Leia a partir de 'HEAD' - essa é a carga útil do HTTP. Se você definitivamente usou -s 0e não há nada depois HTTP/1.0, não há cabeçalhos HTTP na solicitação.
Flup
obrigado. Existe uma maneira de imprimir apenas os cabeçalhos de texto, sem a carga binária?
Adam Matan
-1

Tente usar http://justniffer.sourceforge.net/ É a melhor ferramenta ou o Wireshark com a opção "Follow TCP Flow", existem apenas muitas opções melhores que o tcpdump para ver os cabeçalhos (solicitações / respostas)

Danila Ladner
fonte
11
Talvez adicionar um exemplo bem de como começar este trabalho
vikas027
Talvez você possa ler uma página de manual? justniffer.sourceforge.net/#!/man_page
Danila Ladner