Czytelny dla człowieka format nagłówków http z tcpdump

69

Chciałbym wyświetlić nagłówki HTTP wysłane z Apache (nasłuch na porcie 80) do Tomcat (na porcie 4080) na komputerze z systemem Linux.

Według Wikipedii ,

Pola nagłówka to pary nazwa-wartość rozdzielone dwukropkami w formacie ciągu tekstowego.

Próbowałem kilka wariantów następującego tcpdumppolecenia:

$ 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?

Wynik był zawsze taki sam - dziwna mieszanka bełkotu i angielskich słów (np HEAD.).

Jak wyświetlić nagłówki w formacie czytelnym dla człowieka?

Adam Matan
źródło
Tcpdump pokazuje cały pakiet. Obejmuje to nagłówki IP i TCP. AFAIK, nie możesz wyświetlić tylko ładunku TCP.
Zoredache

Odpowiedzi:

93

Oto jeden linijka, którą wymyśliłem do wyświetlania nagłówków HTTP żądań i odpowiedzi za pomocą tcpdump(co powinno również działać w twoim przypadku):

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'

Ogranicza odcięcie pakietu przy 10 KB i zna tylko polecenia GET, POST i HEAD, ale powinno to wystarczyć w większości przypadków.

EDYCJA : zmodyfikowałem go, aby pozbywał się buforów na każdym kroku, aby był bardziej responsywny. Potrzebuje teraz Perla i stdbufa, więc użyj oryginalnej wersji, jeśli ich nie masz: EDYCJA : Zmieniono docelowe skrypty portu z 80 na 4080, aby faktycznie nasłuchiwać ruchu, który przeszedł już przez apache, zamiast bezpośredniego ruchu zewnętrznego docierającego do portu 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 }'

Kilka wyjaśnień:

  • sudo stdbuf -oL -eL powoduje, że tcpdump uruchamia buforowany wiersz
  • magiczny filtr tcpdump jest szczegółowo wyjaśniony tutaj: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep szuka dowolnych linii z GET, HTTP / lub POST; lub dowolne wiersze, które wyglądają jak nagłówek (litery i cyfry, po których następuje dwukropek)
  • BEGIN {$ | = 1} powoduje, że perl uruchamia buforowany wiersz
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g dodaje nowy wiersz przed rozpoczęciem każdego nowego żądania lub odpowiedzi
Kibber
źródło
1
Działa świetnie. Czy możesz dodać więcej szczegółów na temat działania tego wyrażenia tcpdump?
Vivek Thomas,
1
wyjaśniono tutaj część „ip” w parens, na przykład: stackoverflow.com/questions/11757477/…
Kibber
Właśnie zaoszczędziłeś mi tyle bólu głowy. Szkoda, że ​​mogę dać +1.
Aaron Dobbing,
19

Możesz uzyskać coś zbliżonego do tego, czego chcesz -A, np

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

Pamiętaj, aby -s 0upewnić się, że otrzymałeś cały pakiet.

Alternatywnie możesz użyć wiresharkdo interaktywnego przeglądania nagłówków.

Flup
źródło
1
Próbowałem -Ai -s 0uzyskałem tę samą wydajność.
Adam Matan
2
Spróbuj bez -X.
Flup
tcpdump -s 0 -A dst port 4080daje E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Adam Matan
... co jest czymś zbliżonym do tego, czego chcesz. Odczyt z „HEAD” - jest to ładunek HTTP. Jeśli na pewno już używałeś, -s 0a potem nic HTTP/1.0nie ma, żądanie nie zawiera nagłówków HTTP.
Flup
dzięki. Czy istnieje sposób, aby wydrukować tylko nagłówki tekstu bez binarnego ładunku?
Adam Matan