В сети: инструменты сетевого захвата для разработчиков API

Лейн ЛиаБраатен, команда Google Data API
июнь 2007 г.

Введение

Разработка приложений, взаимодействующих с веб-сервисами, связана с уникальным набором проблем. Распространенным источником разочарования является незнание точно, какое сообщение было отправлено на сервер или какой ответ был получен. Некоторые из наиболее сложных для отслеживания ошибок вызваны несоответствием между тем, что, как мы думаем, мы отправляем на сервер, и тем, что на самом деле передается по сети.

В этой статье представлены несколько инструментов, которые могут помочь сделать данные в сети более наглядными и полезными. Эти инструменты, обычно называемые «анализаторами пакетов», перехватывают все сетевые пакеты, проходящие через сетевой интерфейс. Изучение содержимого этих пакетов и порядка их отправки и получения может оказаться полезным методом отладки.

Пример: получение общедоступного канала

Я собираю велосипедную команду для благотворительной поездки и создал календарь для таких мероприятий, как информационные сессии, сбор средств для команды и тренировочные поездки. Я сделал этот календарь общедоступным, чтобы члены команды и другие гонщики могли просматривать календарь и участвовать в мероприятиях. Я также хочу отправить информационный бюллетень с предстоящими событиями, поэтому вместо того, чтобы копировать информацию с веб-сайта Календаря Google, я могу использовать API данных Календаря Google для запроса этого календаря и получения событий.

В документации по API календаря Google есть информация о том, как использовать RESTful API данных Google для программного взаимодействия с моим календарем. ( Примечание редактора: начиная с версии 3 API календаря Google больше не использует формат данных Google.) Первое, что нужно сделать, — это получить URL-адрес фида событий календаря, щелкнув значок кнопка на странице настроек календаря:

http://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic

Используя документацию Календаря Google в качестве справки, я могу получать и отображать подобные события календаря, где PUBLIC_FEED_URL содержит URL-адрес ленты событий.

CalendarService myService = new CalendarService("exampleCo-fiddlerExample-1");
final String PUBLIC_FEED_URL = "http://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic";
URL feedUrl = new URL(PUBLIC_FEED_URL);
CalendarEventFeed resultFeed = myService.getFeed(feedUrl, CalendarEventFeed.class);

System.out.println("All events on your calendar:");
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEventEntry entry = resultFeed.getEntries().get(i);
  System.out.println("\t" + entry.getTitle().getPlainText());
}
System.out.println();

Это создает основной список событий в моем календаре:

All events on your calendar:
    MS150 Training ride
    Meeting with Nicole
    MS150 Information session

Фрагмент кода выше отображает заголовки событий календаря, а как насчет остальных данных, которые мы получили с сервера? Клиентская библиотека Java не упрощает вывод веб-канала или записи в виде XML, а даже если бы это было возможно, XML — это еще не все. А как насчет заголовков HTTP, которые сопровождают запрос? Был ли запрос проксирован или перенаправлен? С более сложными операциями эти вопросы становятся все более важными, особенно когда что-то идет не так и мы получаем ошибки. Программное обеспечение для анализа пакетов может ответить на эти вопросы, раскрывая сетевой трафик.

tcpdump

tcpdump — это инструмент командной строки, который работает на Unix-подобных платформах, но есть также порт Windows под названием WinDump . Как и большинство анализаторов пакетов, tcpdump переводит вашу сетевую карту в неразборчивый режим, требующий привилегий суперпользователя. Чтобы использовать tcpdump, просто укажите сетевой интерфейс для прослушивания, и сетевой трафик будет отправлен на стандартный вывод:

sudo tcpdump -i eth0

Если вы запустите эту команду, вы будете засыпаны всевозможным сетевым трафиком, некоторые из которых вы не сможете распознать. Вы можете просто перенаправить вывод в файл и выполнить его позже, но это может привести к очень большим файлам. Большинство программ для захвата пакетов имеют встроенные механизмы фильтрации, поэтому вы захватываете только то, что вам нужно.

tcpdump поддерживает фильтрацию на основе различных характеристик сетевого трафика. Например, вы можете указать tcpdump захватывать только входящий или исходящий трафик вашего сервера через порт 80 (сообщения HTTP), вставив имя хоста вашего сервера в следующее выражение:

dst or src host <hostname> and port 80

Для каждого пакета, который соответствует выражению фильтра, tcpdump будет отображать метку времени, источник и назначение пакета, а также несколько флагов TCP. Эта информация может быть полезной, поскольку она показывает порядок отправки и получения пакетов.

Часто бывает полезно также просмотреть содержимое пакетов. Флаг «-A» указывает tcpdump печатать каждый пакет в ASCII, раскрывая заголовки HTTP и тело сообщения. Флаг «-s» используется для указания количества отображаемых байтов (где «-s 0» означает вообще не усекать тело сообщения).

Собрав все вместе, мы получим следующую команду:

sudo tcpdump -A -s 0 -i eth0 dst or src host <hostname> and port 80

Если вы запустите эту команду, а затем выполните приведенный выше короткий пример .Java, вы увидите всю сетевую связь, связанную с этой операцией. Среди трафика вы увидите запрос HTTP GET :

22:22:30.870771 IP dellalicious.mshome.net.4520 > po-in-f99.google.com.80: P 1:360(359) ack 1 win 65535
E.....@....\...eH..c...P.=.....zP......GET /calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic HTTP/1.1
User-Agent: exampleCo-fiddlerExample-1 GCalendar-Java/1.0.6 GData-Java/1.0.10(gzip)
Accept-Encoding: gzip
Cache-Control: no-cache
Pragma: no-cache
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

Вы также увидите ответное сообщение 200 OK , содержащее фид данных Google. Обратите внимание, что фид разбит на четыре пакета:

22:22:31.148789 IP po-in-f99.google.com.80 > dellalicious.mshome.net.4520: . 1:1431(1430) ack 360 win 6432
E...1 ..2.I.H..c...e.P.....z.=.:P..M...HTTP/1.1 200 OK
Content-Type: application/atom+xml; charset=UTF-8
Cache-Control: max-age=0, must-revalidate, private
Last-Modified: Mon, 11 Jun 2007 15:11:40 GMT
Transfer-Encoding: chunked
Date: Sun, 24 Jun 2007 02:22:10 GMT
Server: GFE/1.3

13da
<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gCal='http://sc
hemas.google.com/gCal/2005' xmlns:gd='http://schemas.google.com/g/2005'><id>http
://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.goo
gle.com/public/basic</id><updated>2007-06-11T15:11:40.000Z</updated><category sc
heme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2
005#event'></category><title type='text'>MS150 Training Schedule</title><subtitl
e type='text'>This calendar is public</subtitle><link rel='http://schemas.google
.com/g/2005#feed' type='application/atom+xml' href='http://www.google.com/calend
ar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic'></
link><link rel='self' type='application/atom+xml' href='http://www.google.com/ca
lendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic
?max-results=25'></link><author><name>Lane LiaBraaten</name><email>api.lliabraa@
gmail.com</email></author><generator version='1.0' uri='http://www.google.com/ca
lendar'>Google Calendar</generator><openSearch:totalRe


22:22:31.151501 IP po-in-f99.google.com.80 > dellalicious.mshome.net.4520: . 1431:2861(1430) ack 360 win 6432
E...1!..2.I.H..c...e.P.......=.:P.. 2...sults>3</openSearch:totalResults><openSe
arch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch
:itemsPerPage><gd:where valueString=''></gd:where><gCal:timezone value='America/
Los_Angeles'></gCal:timezone><entry><id>http://www.google.com/calendar/feeds/24v
j3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic/dgt40022cui2k3j
740hnj46744</id><published>2007-06-11T15:11:05.000Z</published><updated>2007-06-
11T15:11:05.000Z</updated><category scheme='http://schemas.google.com/g/2005#kin
d' term='http://schemas.google.com/g/2005#event'></category><title type='text'>M
S150 Training ride</title><summary type='html'>When: Sat Jun 9, 2007 7am to 10am

&amp;nbsp; PDT&lt;br&gt;   &lt;br&gt;Event Status:     confirmed</summary><conte
nt type='text'>When: Sat Jun 9, 2007 7am to 10am&amp;nbsp; PDT&lt;br&gt;   &lt;b
r&gt;Event Status:     confirmed</content><link rel='alternate' type='text/html'
 href='http://www.google.com/calendar/event?eid=ZGd0NDAwMjJjdWkyazNqNzQwaG5qNDY3
NDQgMjR2ajNtNXBsMTI1YmgyaWpiYm5laDk1M3NAZw' title='alternate'></link><link rel='
self' type='application/atom+xml' href='http://www.google.com/calendar/feeds/24v
j3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic/dgt40022cui2k3j
740hnj46744'></link><author><name>MS150 Training Schedule</name></author><gCal:s
endEventNotifications value='false'></gCal:sendEventNotifications></entry><entry

><id>http://www.google.com/cal

22:22:31.153097 IP po-in-f99.google.com.80 > dellalicious.mshome.net.4520: . 2861:4291(1430) ack 360 win 6432
E...1#..2.I.H..c...e.P.......=.:P.. ....endar/feeds/24vj3m5pl125bh2ijbbneh953s%4
0group.calendar.google.com/public/basic/51d8kh4s3bplqnbf1lp6p0kjp8</id><publishe
d>2007-06-11T15:08:23.000Z</published><updated>2007-06-11T15:10:39.000Z</updated
><category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.g
oogle.com/g/2005#event'></category><title type='text'>Meeting with Nicole</title

><summary type='html'>When: Mon Jun 4, 2007 10am to 11am&amp;nbsp; PDT&lt;br&gt;
  &lt;br&gt;Where: Conference Room B &lt;br&gt;Event Status:     confirmed</summ
ary><content type='text'>When: Mon Jun 4, 2007 10am to 11am&amp;nbsp; PDT&lt;br&
gt;  &lt;br&gt;Where: Conference Room B &lt;br&gt;Event Status:     confirmed

&lt;br&gt;Event Description: Discuss building cycling team for MS150</content><l
ink rel='alternate' type='text/html' href='http://www.google.com/calendar/event?
eid=NTFkOGtoNHMzYnBscW5iZjFscDZwMGtqcDggMjR2ajNtNXBsMTI1YmgyaWpiYm5laDk1M3NAZw'
title='alternate'></link><link rel='self' type='application/atom+xml' href='http
://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.goo
gle.com/public/basic/51d8kh4s3bplqnbf1lp6p0kjp8'></link><author><name>MS150 Trai
ning Schedule</name></author><gCal:sendEventNotifications value='false'></gCal:s
endEventNotifications></entry><entry><id>http://www.google.com/calendar/feeds/24
vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic/va41amq3r08dhh
kpm3lc1abs2o</id><published>20


22:22:31.190244 IP po-in-f99.google.com.80 > dellalicious.mshome.net.4520: P 4291:5346(1055) ack 360 win 6432
E..G1$..2.K.H..c...e.P.....<.=.:P.. ....07-06-11T15:10:08.000Z</published><updat
ed>2007-06-11T15:10:08.000Z</updated><category scheme='http://schemas.google.com
/g/2005#kind' term='http://schemas.google.com/g/2005#event'></category><title ty
pe='text'>MS150 Information session</title><summary type='html'>When: Wed Jun 6,
 2007 4pm to Wed Jun 6, 2007 5pm&amp;nbsp; PDT&lt;br&gt;   &lt;br&gt;Event Statu
s:     confirmed</summary><content type='text'>When: Wed Jun 6, 2007 4pm to Wed
Jun 6, 2007 5pm&amp;nbsp; PDT&lt;br&gt;   &lt;br&gt;Event Status:     confirmed<

/content><link rel='alternate' type='text/html' href='http://www.google.com/cale
ndar/event?eid=dmE0MWFtcTNyMDhkaGhrcG0zbGMxYWJzMm8gMjR2ajNtNXBsMTI1YmgyaWpiYm5la
Dk1M3NAZw' title='alternate'></link><link rel='self' type='application/atom+xml'
 href='http://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.c
alendar.google.com/public/basic/va41amq3r08dhhkpm3lc1abs2o'></link><author><name
>MS150 Training Schedule</name></author><gCal:sendEventNotifications value='fals
e'></gCal:sendEventNotifications></entry></feed>

Этот вывод включает в себя все заголовки и содержимое HTTP, а также несколько загадочных флагов TCP. Все данные присутствуют здесь, но их сложно читать и понимать. Есть несколько графических инструментов, облегчающих просмотр этих данных.

WireShark (ранее Ethereal)

Скриншот Wireshark
WireShark отображает сетевой трафик несколькими способами.

WireShark — это графический инструмент, созданный с помощью libpcap, той же библиотеки, на которой построен tcpdump, и доступной в Linux, Mac OS X и Windows. Графический интерфейс WireShark позволяет использовать несколько новых способов интерпретации и взаимодействия с данными захвата пакетов. Например, когда пакеты перехватываются с вашего сетевого интерфейса, они отображаются разными цветами в зависимости от используемого протокола. Вы также можете сортировать трафик по отметке времени, источнику, получателю и протоколу.

Если вы выберете строку в списке пакетов, Wireshark отобразит IP, TCP и другую информацию, относящуюся к протоколу, в заголовках пакетов в удобочитаемом дереве. Данные также отображаются в HEX и ASCII в нижней части экрана.

Хотя визуальная природа WireShark упрощает понимание сетевого трафика, в большинстве случаев вам все равно потребуется фильтровать сетевой трафик. WireShark обладает надежными возможностями фильтрации, включая поддержку сотен протоколов.

СОВЕТ. Чтобы просмотреть доступные протоколы и создать сложные фильтры, щелкните значок кнопку в верхней части окна WireShark.

Чтобы воссоздать фильтр, использованный в приведенном выше примере tcpdump, вы можете вставить следующее выражение в поле фильтра WireShark:

ip.addr==<your IP address> && tcp.port==80

Или используйте знания WireShark о HTTP:

ip.addr==<your IP address> && http

Это отфильтрует результаты вашего захвата только для пакетов, участвующих в этом взаимодействии с сервером Календаря Google. Вы можете щелкнуть по каждому пакету, чтобы увидеть его содержимое и собрать воедино транзакцию.

СОВЕТ. Вы можете щелкнуть правой кнопкой мыши один из пакетов и выбрать «Следовать за потоком TCP», чтобы последовательно отображать запросы и ответы в одном окне.

WireShark предоставляет несколько способов сохранения информации о захвате. Вы можете сохранить один, несколько или все пакеты. Если вы просматриваете поток TCP, вы можете просто нажать кнопку «Сохранить как», чтобы сохранить только соответствующие пакеты. Вы также можете импортировать вывод из захвата tcpdump и просмотреть его в WireShark.

Проблема: SSL и шифрование

Общим недостатком инструментов захвата пакетов является невозможность просмотра данных, зашифрованных через соединение SSL. В приведенном выше примере осуществляется доступ к общедоступному каналу, поэтому SSL не требуется. Однако, если в примере доступ к частной ленте, клиенту потребуется пройти аутентификацию с помощью службы аутентификации Google, для которой действительно требуется SSL-соединение.

Следующий фрагмент похож на предыдущий пример, но здесь CalendarService запрашивает метаканал календаря пользователя, который является частным каналом, требующим проверки подлинности. Для аутентификации просто вызовите метод setUserCredentials . Этот метод инициирует HTTPS-запрос к ClientLogin и получает токен проверки подлинности из ответа. Затем объект CalendarService будет включать токен проверки подлинности во все последующие запросы.

CalendarService myService = new CalendarService("exampleCo-fiddlerSslExample-1");
myService.setUserCredentials(username, userPassword);
final String METAFEED_URL = "http://www.google.com/calendar/feeds/default";
URL feedUrl = new URL(METAFEED_URL);
CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);

System.out.println("Your calendars:");
for (int i = 0; i < resultFeed.getEntries().size(); i++) {
  CalendarEntry entry = resultFeed.getEntries().get(i);
  System.out.println("\t" + entry.getTitle().getPlainText());
}
System.out.println();

Рассмотрим сетевой трафик, необходимый для аутентификации и доступа к частному каналу API данных Google:

  1. Отправить учетные данные пользователя в службу ClientLogin
    • Отправьте HTTP POST на https://www.google.com/accounts/ClientLogin со следующими параметрами в теле сообщения:
      • Электронная почта — адрес электронной почты пользователя.
      • Passwd - пароль пользователя.
      • source — идентифицирует ваше клиентское приложение. Должен иметь форму имя_компании-имя_приложения-идентификатор_версии. В примерах используется имя ExampleCo-FiddlerSSLExample-1.
      • service — имя службы Календаря Google — «cl».
  2. Получите токен авторизации
    • Если запрос аутентификации не пройден, вы получите код состояния HTTP 403 Forbidden.
    • В случае успеха ответ службы представляет собой код состояния HTTP 200 OK, а также три длинных буквенно-цифровых кода в теле ответа: SID , LSID и Auth . Значение Auth — это токен авторизации.
  3. Запросить метафид личного календаря
    • Отправьте запрос HTTP GET на адрес http://www.google.com/calendar/feeds/default со следующим заголовком:
    • Authorization: GoogleLogin auth=<yourAuthToken>
      

Попробуйте запустить этот фрагмент и просмотреть сетевой трафик в WireShark (используя «http || ssl» в качестве фильтра). Вы увидите пакеты SSL и TLS, участвующие в транзакции, но пакеты запроса и ответа ClientLogin зашифрованы в пакетах «Данные приложения». Не волнуйтесь, далее мы рассмотрим инструмент, который действительно может раскрыть эту зашифрованную информацию.

Скрипач

Fiddler — еще один графический инструмент для анализа пакетов, но он ведет себя совершенно иначе, чем представленные до сих пор инструменты. Fiddler действует как прокси-сервер между вашим приложением и удаленными службами, с которыми вы взаимодействуете, фактически становясь посредником. Fiddler устанавливает SSL-соединение как с вашим приложением, так и с удаленной веб-службой, расшифровывая трафик с одной конечной точки, захватывая открытый текст и повторно шифруя трафик перед его отправкой. К сожалению, Fiddler доступен только для Windows, извините, для всех пользователей Mac и Linux.

Примечание. Для поддержки SSL требуется Fiddler версии 2 и .NET Framework версии 2.0.

Просмотр сетевого трафика в Fiddler в основном осуществляется через вкладку Session Inspector. Вложенные вкладки, наиболее полезные для отладки проблем с API данных Google:

  • Заголовки — показывает заголовки HTTP в формате сворачиваемого дерева.
  • Auth — показывает заголовки Authentication.
  • Raw — показывает содержимое сетевых пакетов в текстовом формате ASCII.

СОВЕТ: нажмите кнопку значок в левом нижнем углу окна Fiddler, чтобы включать и выключать захват.

Fiddler использует .NET Framework для настройки сетевых подключений для использования Fiddler в качестве прокси-сервера. Это означает, что любые подключения, которые вы устанавливаете с помощью Internet Explorer или кода .NET, будут отображаться в Fiddler по умолчанию. Однако трафик из приведенного выше примера Java не будет отображаться, поскольку в Java используется другой способ настройки прокси-серверов HTTP.

В Java вы можете установить прокси-сервер HTTP, используя системные свойства. Fiddler работает на порту 8888, поэтому для локальной установки вы можете заставить Java-код использовать Fiddler в качестве прокси-сервера для HTTP и HTTPS, добавив следующие строки:

System.setProperty("http.proxyHost", "localhost");
System.setProperty("http.proxyPort", "8888");
System.setProperty("https.proxyHost", "localhost");
System.setProperty("https.proxyPort", "8888");

Если вы запустите образец с этими строками, вы фактически получите неприятную трассировку стека из пакета безопасности Java:

[java] Caused by:
  sun.security.validator.ValidatorException: PKIX path building failed:
  sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Скриншот Скрипача
Fiddler может расшифровывать и отображать SSL-трафик.

Эта ошибка возникает, когда сертификат, возвращенный с сервера в соединении SSL, не может быть проверен. В этом случае плохой сертификат исходит от Fiddler, выступающего в роли посредника. Fiddler генерирует сертификаты на лету, и, поскольку Fiddler не является доверенным эмитентом, эти сертификаты приведут к сбою Java при настройке SSL-соединения.

Примечание. Когда Fiddler запущен, любое SSL-соединение, которое вы устанавливаете в Internet Explorer, вызовет «Предупреждение системы безопасности» с вопросом, хотите ли вы продолжить, несмотря на схематичный сертификат. Вы можете нажать «Просмотреть сертификат», чтобы увидеть сертификат, созданный Fiddler.

Так как же обойти это исключение безопасности? В основном вам нужно перенастроить структуру безопасности Java, чтобы доверять всем сертификатам. К счастью, здесь вам не нужно изобретать велосипед — ознакомьтесь с решением Фрэнсиса Лабри и добавьте метод SSLUtilities.trustAllHttpsCertificates() в приведенный выше пример.

После того как вы настроили Java для использования Fiddler в качестве прокси-сервера и отключили проверку сертификата по умолчанию, вы можете запустить пример и увидеть весь трафик, отправляемый по сети, в виде открытого текста. Не укради мой пароль!

Помните, что эта транзакция аутентификации — всего лишь один небольшой пример SSL-трафика. Некоторые веб-приложения используют исключительно SSL-соединения, поэтому отладка HTTP-трафика невозможна без возможности расшифровки данных.

Заключение

tcpdump доступен в Linux, Mac OS X и Windows и является отличным инструментом, когда вы знаете, что ищете, и вам просто нужен быстрый захват. Однако есть некоторые графические инструменты, которые представляют сетевой трафик в более понятных форматах. tcpdump имеет гораздо больше опций и возможностей фильтрации, чем те, которые были рассмотрены здесь. Чтобы получить полное описание функциональности tcpdump, введите «man tcpdump» или посетите справочную страницу tcpdump в Интернете.

WireShark также доступен для Linux, Mac OS X и Windows. Встроенная поддержка сотен протоколов делает WireShark полезным инструментом для многих приложений, а не только для отладки HTTP. Это введение едва затрагивает многие возможности WireShark. Для получения дополнительной информации введите «man wireshark» или посетите веб-сайт WireShark .

Fiddler также имеет множество замечательных функций, но что отличает его, так это способность расшифровывать трафик SSL. Для получения дополнительной информации посетите веб-сайт Fiddler2 .

Эти приложения для перехвата пакетов — отличные инструменты для вашего набора инструментов, и наблюдательные читатели заметят, что все они бесплатны! В следующий раз, когда вы будете работать с API Google и обнаружите что-то подозрительное, достаньте один из этих сетевых анализаторов и внимательно изучите, что происходит в сети. Если вы не можете найти проблему, вы всегда можете задать вопрос в нашей группе обсуждения . Включение соответствующих сетевых сообщений поможет другим понять и диагностировать вашу конкретную проблему.

Удачи и приятного нюхания!

Ресурсы