Удобный для чтения формат для заголовков http с помощью tcpdump

69

Я хотел бы просмотреть заголовки HTTP, отправленные из Apache (прослушивающий порт 80) в Tomcat (через порт 4080) на компьютере с Linux.

Согласно Википедии ,

Поля заголовка - это разделенные двоеточиями пары имя-значение в формате открытого текста.

Я пробовал несколько вариантов следующей tcpdumpкоманды:

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

Результат всегда был один и тот же - странная смесь слов на английском и английском (например HEAD).

Как я могу просмотреть заголовки в удобочитаемом формате?

Адам Матан
источник
Tcpdump показывает весь пакет. Это включает в себя IP и заголовки TCP. AFAIK, вы не можете отобразить только полезную нагрузку TCP.
Zoredache

Ответы:

93

Вот одна строка, которую я придумал для отображения заголовков HTTP запросов и ответов, используя tcpdump(что должно работать и для вашего случая):

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'

Он ограничивает обрезку пакета до 10 Кбайт и знает только команды GET, POST и HEAD, но этого должно быть достаточно в большинстве случаев.

РЕДАКТИРОВАТЬ : изменил его, чтобы избавиться от буферов на каждом этапе, чтобы сделать его более отзывчивым. Однако теперь нужны Perl и stdbuf, поэтому используйте оригинальную версию, если у вас ее нет: EDIT : Изменены целевые значения портов скрипта с 80 на 4080, чтобы фактически прослушивать трафик, уже прошедший через apache, вместо прямого внешнего трафика, поступающего в порт. 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 }'

Некоторые объяснения:

  • sudo stdbuf -oL -eL заставляет tcpdump выполнять буферизацию строки
  • Волшебный фильтр tcpdump подробно объясняется здесь: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
  • grep ищет любые строки с GET, HTTP / или POST; или любые строки, которые выглядят как заголовок (буквы и цифры, за которыми следует двоеточие)
  • BEGIN {$ | = 1} заставляет perl запускаться с буферизацией строки
  • s /.*? (GET | HTTP / [0-9.] * | POST) / \ n $ 1 / g добавляет новую строку перед началом каждого нового запроса или ответа
Киббер
источник
1
Работает отлично. Не могли бы вы добавить более подробную информацию о том, как работает это выражение tcpdump?
Вивек Томас
1
часть «ip» в скобках объясняется здесь, например: stackoverflow.com/questions/11757477/…
Kibber
Вы только что избавили меня от головной боли. Позор я могу только +1.
Аарон Доббинг
19

Вы можете получить что-то близкое к тому, что вы хотите, используя -A, например,

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

Не забудьте использовать, -s 0чтобы убедиться, что вы получите весь пакет.

В качестве альтернативы вы можете использовать wiresharkдля интерактивного просмотра заголовков.

Flup
источник
1
Попробовал -Aи -s 0получил тот же вывод.
Адам Матан
2
Попробуй без -X.
Флюп
tcpdump -s 0 -A dst port 4080дает E..e..@.?.$bb...b....:......w........Q.....G..1.b..HEAD /dapper_serving/AdMonkey?ping=1 HTTP/1.0.
Адам Матан
... что-то близкое к тому, что вы хотите. Чтение из 'HEAD' - это полезная нагрузка HTTP. Если вы определенно использовали -s 0и после этого ничего не HTTP/1.0происходит, в запросе нет заголовков HTTP.
Флюп
Благодарю. Есть ли способ печатать только заголовки текста, без двоичной полезной нагрузки?
Адам Матан
-1

Попробуйте использовать http://justniffer.sourceforge.net/ Это лучший инструмент или Wireshark с опцией «Follow TCP Flow», есть просто много лучших опций, чем tcpdump, для просмотра заголовков (запросов / ответов)

Данила Ладнер
источник
1
Может быть, добавить пример того, как это работает
vikas027
Может быть, вы можете прочитать страницу руководства? justniffer.sourceforge.net/#!/man_page
Данила Ладнер