Июнь 2007 г.
- Введение
- Пример: получение общедоступного канала
- tcpdump
- WireShark
- Проблема: SSL и шифрование
- Скрипач
- Заключение
Введение
Разработка приложений, взаимодействующих с веб-сервисами, создаёт уникальный набор проблем. Распространённой причиной разочарования является невозможность точно знать, какое сообщение было отправлено на сервер или какой ответ был получен. Некоторые из самых сложных для отслеживания ошибок возникают из-за несоответствия между тем, что, по нашему мнению, отправляется на сервер, и тем, что на самом деле передаётся по сети.
В этой статье представлено несколько инструментов, которые помогут сделать данные в сети более наглядными и полезными. Эти инструменты, обычно называемые «анализаторами пакетов», перехватывают все сетевые пакеты, проходящие через сетевой интерфейс. Анализ содержимого этих пакетов и порядка их отправки и получения может быть полезным методом отладки.
Пример: получение общедоступного канала
Я собираю велокоманду для благотворительного велопробега и создал календарь мероприятий, таких как информационные сессии, сбор средств для команды и тренировочные заезды. Я сделал этот календарь общедоступным, чтобы члены команды и другие велосипедисты могли просматривать его и участвовать в мероприятиях. Я также хочу рассылать новостную рассылку с предстоящими мероприятиями. Поэтому вместо того, чтобы копировать информацию с сайта Google Calendar, я могу использовать API данных Google Calendar для запросов к этому календарю и получения событий.
В документации API Календаря Google есть информация о том, как использовать RESTful API Google Data для программного взаимодействия с моим календарем. ( Примечание редактора: начиная с версии 3, API Календаря Google больше не использует формат Google Data.) Первое, что нужно сделать, — это получить URL-адрес ленты событий календаря, нажав на кнопка на странице настроек календаря:
http://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic
Используя документацию Google Calendar в качестве справки, я могу извлекать и отображать события календаря следующим образом, где 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-подобных платформах, но существует также порт WinDump для Windows. Как и большинство анализаторов пакетов, tcpdump переводит вашу сетевую карту в режим прослушивания, требующий прав суперпользователя. Чтобы использовать tcpdump, просто укажите сетевой интерфейс для прослушивания, и сетевой трафик будет отправлен на стандартный вывод:
sudo tcpdump -i eth0
Если вы выполните эту команду, вас завалит потоком всевозможного сетевого трафика, часть которого вы даже не распознаете. Вы можете просто перенаправить вывод в файл и позже выполнить его grep , но это может привести к созданию очень больших файлов. Большинство программ для перехвата пакетов имеют встроенные механизмы фильтрации, поэтому вы будете перехватывать только то, что вам нужно.
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 Data. Обратите внимание, что фид разбит на четыре пакета:
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 &nbsp; PDT<br> <br>Event Status: confirmed</summary><conte nt type='text'>When: Sat Jun 9, 2007 7am to 10am&nbsp; PDT<br> <b r>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&nbsp; PDT<br> <br>Where: Conference Room B <br>Event Status: confirmed</summ ary><content type='text'>When: Mon Jun 4, 2007 10am to 11am&nbsp; PDT<br& gt; <br>Where: Conference Room B <br>Event Status: confirmed <br>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&nbsp; PDT<br> <br>Event Statu s: confirmed</summary><content type='text'>When: Wed Jun 6, 2007 4pm to Wed Jun 6, 2007 5pm&nbsp; PDT<br> <br>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 — это графический инструмент, созданный на основе libpcap, той же библиотеки, что и tcpdump, и доступный в Linux, Mac OS X и Windows. Графический интерфейс WireShark открывает несколько новых способов интерпретации данных перехвата пакетов и взаимодействия с ними. Например, пакеты, перехваченные с вашего сетевого интерфейса, отображаются разными цветами в зависимости от используемого протокола. Вы также можете сортировать трафик по временной метке, источнику, назначению и протоколу.
Если выбрать строку в списке пакетов, Wireshark отобразит информацию об IP, TCP и других протоколах в заголовках пакетов в удобном для восприятия виде. Данные также отображаются в шестнадцатеричном и 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:
- Отправка учетных данных пользователя в службу ClientLogin
- Отправьте HTTP
POST
на https://www.google.com/accounts/ClientLogin со следующими параметрами в теле сообщения:- Электронная почта — адрес электронной почты пользователя.
- Passwd - пароль пользователя.
- Источник — идентифицирует ваше клиентское приложение. Должен иметь вид «имя_компании-имя_приложения-идентификатор_версии». В примерах используется имя ExampleCo-FiddlerSSLExample-1.
- сервис - имя сервиса Google Calendar - «cl».
- Отправьте HTTP
- Получите токен авторизации
- Если запрос на аутентификацию не пройден, вы получите код статуса HTTP 403 Forbidden.
- В случае успеха ответ службы представляет собой код статуса HTTP 200 OK, а также три длинных буквенно-цифровых кода в теле ответа:
SID
,LSID
иAuth
. ЗначениеAuth
представляет собой токен авторизации.
- Запросить личный метаканал календаря
- Отправьте HTTP
GET
на http://www.google.com/calendar/feeds/default со следующим заголовком:
Authorization: GoogleLogin auth=<yourAuthToken>
- Отправьте HTTP
Попробуйте запустить этот фрагмент и просмотреть сетевой трафик в WireShark (используя «http || ssl» в качестве фильтра). Вы увидите пакеты SSL и TLS, участвующие в транзакции, но пакеты запроса и ответа ClientLogin зашифрованы в пакетах «Application Data». Не волнуйтесь, далее мы рассмотрим инструмент, который действительно может раскрыть эту зашифрованную информацию.
Скрипач
Fiddler — ещё один графический инструмент для анализа пакетов, но его функционирование существенно отличается от представленных ранее инструментов. Fiddler выступает в роли прокси-сервера между вашим приложением и удалёнными сервисами, с которыми вы взаимодействуете, фактически становясь посредником. Fiddler устанавливает SSL-соединение как с вашим приложением, так и с удалённым веб-сервисом, расшифровывая трафик с одной конечной точки, перехватывая открытый текст и повторно шифруя трафик перед отправкой. К сожалению, Fiddler доступен только для Windows — прошу прощения у пользователей Mac и Linux.
Примечание: для поддержки SSL требуются Fiddler версии 2 и .NET Framework версии 2.0.
Просмотр сетевого трафика в Fiddler в основном осуществляется через вкладку «Инспектор сеансов». Для отладки проблем с API Google Data наиболее полезны следующие подвкладки:
- Заголовки — отображает заголовки HTTP в сворачиваемом древовидном формате.
- Auth — показывает заголовки аутентификации.
- 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 и заметите что-то подозрительное, воспользуйтесь одним из этих сетевых анализаторов и внимательно изучите, что происходит в сети. Если вы не можете найти проблему, вы всегда можете задать вопрос в нашей группе обсуждения . Включение соответствующих сетевых сообщений поможет другим понять и диагностировать вашу проблему.
Удачи и приятного нюхания!