Junio de 2007
- Introducción
- Un ejemplo: Recuperar un feed público
- tcpdump
- WireShark
- Un problema: SSL y encriptación
- Fiddler
- Conclusión
Introducción
El desarrollo de aplicaciones que interactúan con servicios web plantea un conjunto único de problemas. Una fuente común de frustración es no saber exactamente qué mensaje se envió al servidor o qué respuesta se recibió. Algunos de los errores más difíciles de rastrear se deben a una desconexión entre lo que creemos que enviamos al servidor y lo que realmente se transmite por el cable.
En este artículo, se presentan varias herramientas que pueden ayudar a que los datos en la red sean más visibles y útiles. Estas herramientas, conocidas comúnmente como "rastreadores de paquetes", capturan todos los paquetes de red que se mueven a través de tu interfaz de red. Examinar el contenido de estos paquetes y el orden en que se enviaron y recibieron puede ser una técnica de depuración útil.
Ejemplo: Recuperación de un feed público
Estoy organizando un equipo de ciclismo para un paseo benéfico y creé un calendario para eventos como sesiones informativas, recaudaciones de fondos del equipo y paseos de entrenamiento. Hice público este calendario para que los miembros del equipo y otros ciclistas puedan verlo y participar en los eventos. También quiero enviar un boletín informativo con los próximos eventos, por lo que, en lugar de copiar la información del sitio web del Calendario de Google, puedo usar la API de datos del Calendario de Google para consultar este calendario y recuperar eventos.
La documentación de la API de Google Calendar contiene información sobre cómo usar la API de Google Data basada en REST para interactuar con mi calendario de forma programática. (Nota del editor: A partir de la versión 3, la API de Calendar de Google ya no usa el formato de datos de Google). Lo primero que debes hacer es obtener la URL del feed de eventos del calendario. Para ello, haz clic en el botón en la página de configuración del calendario:
http://www.google.com/calendar/feeds/24vj3m5pl125bh2ijbbneh953s%40group.calendar.google.com/public/basic
Con la documentación de Calendario de Google como referencia, puedo recuperar y mostrar eventos del calendario de esta manera, donde PUBLIC_FEED_URL
contiene la URL del feed de eventos.
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();
Esto genera una lista básica de los eventos de mi calendario:
All events on your calendar: MS150 Training ride Meeting with Nicole MS150 Information session
El fragmento de código anterior muestra los títulos de los eventos del calendario, pero ¿qué sucede con el resto de los datos que recibimos del servidor? La biblioteca cliente de Java no facilita la salida de un feed o una entrada como XML, y, aunque lo hiciera, el XML no es todo. ¿Qué sucede con los encabezados HTTP que acompañan la solicitud? ¿Se redireccionó o se envió a través de un proxy la búsqueda? Con operaciones más complejas, estas preguntas se vuelven cada vez más importantes, en especial cuando las cosas salen mal y recibimos errores. El software de rastreo de paquetes puede responder estas preguntas revelando el tráfico de red.
tcpdump
tcpdump es una herramienta de línea de comandos que funciona en plataformas similares a Unix, pero también existe un puerto de Windows llamado WinDump. Al igual que la mayoría de los analizadores de paquetes, tcpdump pone tu tarjeta de red en modo promiscuo, lo que requiere privilegios de superusuario. Para usar tcpdump, solo especifica la interfaz de red en la que se debe escuchar, y el tráfico de red se enviará a stdout:
sudo tcpdump -i eth0
Si ejecutas este comando, recibirás una gran cantidad de tráfico de red, parte del cual ni siquiera reconocerás. Podrías reenviar el resultado a un archivo y usar grep más tarde, pero eso podría generar archivos muy grandes. La mayoría del software de captura de paquetes tiene algunos mecanismos de filtrado integrados para que solo captures lo que necesitas.
tcpdump admite el filtrado según varias características del tráfico de red. Por ejemplo, puedes indicarle a tcpdump que solo capture el tráfico hacia tu servidor o desde él en el puerto 80 (mensajes HTTP) insertando el nombre de host de tu servidor en la siguiente expresión:
dst or src host <hostname> and port 80
Para cada paquete que coincida con la expresión de filtro, tcpdump mostrará una marca de tiempo, el origen y el destino del paquete, y varias marcas de TCP. Esta información puede ser valiosa porque muestra el orden en que se enviaron y recibieron los paquetes.
A menudo, también es útil ver el contenido de los paquetes. La marca "-A" le indica a tcpdump que imprima cada paquete en ASCII, lo que expone los encabezados HTTP y el cuerpo del mensaje. La marca "-s" se usa para especificar cuántos bytes se deben mostrar (donde "-s 0" significa que no se debe truncar el cuerpo del mensaje).
Si juntamos todo, obtenemos el siguiente comando:
sudo tcpdump -A -s 0 -i eth0 dst or src host <hostname> and port 80
Si ejecutas este comando y, luego, el ejemplo corto de .Java anterior, verás toda la comunicación de red involucrada en esta operación. Entre el tráfico, verás la solicitud 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
También verás el mensaje de respuesta 200 OK
que contiene el feed de datos de Google. Observa que el feed se divide en cuatro paquetes:
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>
Este resultado incluye todos los encabezados y el contenido HTTP, así como varias marcas TCP crípticas. Aquí se encuentran todos los datos, pero son difíciles de leer y comprender. Existen varias herramientas gráficas que facilitan la visualización de estos datos.
WireShark (antes llamado Ethereal)

WireShark muestra el tráfico de red de varias maneras.
WireShark es una herramienta gráfica creada con libpcap, la misma biblioteca en la que se basa tcpdump, y está disponible en Linux, Mac OS X y Windows. La GUI de WireShark permite varias formas nuevas de interpretar los datos de captura de paquetes y de interactuar con ellos. Por ejemplo, a medida que se capturan paquetes de tu interfaz de red, se muestran en diferentes colores según el protocolo que usan. También puedes ordenar el tráfico por marca de tiempo, origen, destino y protocolo.
Si seleccionas una fila en la lista de paquetes, Wireshark mostrará información específica de IP, TCP y otros protocolos en los encabezados de los paquetes en un árbol legible. Los datos también se muestran en formato HEX y ASCII en la parte inferior de la pantalla.
Si bien la naturaleza visual de WireShark facilita la comprensión del tráfico de red, en la mayoría de los casos, querrás filtrar el tráfico de red. Wireshark tiene sólidas capacidades de filtrado, incluida la compatibilidad con cientos de protocolos.
SUGERENCIA: Para ver los protocolos disponibles y crear filtros complejos, haz clic en el botón cerca de la parte superior de la ventana de Wireshark.
Para volver a crear el filtro que se usó en el ejemplo de tcpdump anterior, puedes insertar la siguiente expresión en el cuadro de filtro de WireShark:
ip.addr==<your IP address> && tcp.port==80
O bien, aprovecha el conocimiento de HTTP de WireShark:
ip.addr==<your IP address> && http
Esto filtrará los resultados de la captura para mostrar solo los paquetes involucrados en esta interacción con el servidor de Calendario de Google. Puedes hacer clic en cada paquete para ver el contenido y reconstruir la transacción.
SUGERENCIA: Puedes hacer clic con el botón derecho en uno de los paquetes y elegir "Seguir flujo TCP" para mostrar las solicitudes y las respuestas de forma secuencial en una sola ventana.
WireShark ofrece varias formas de guardar la información de captura. Puedes guardar algunos paquetes o todos. Si estás viendo una transmisión TCP, puedes hacer clic en el botón "Guardar como" para guardar solo los paquetes relevantes. También puedes importar el resultado de una captura de tcpdump y verlo en WireShark.
Un problema: SSL y encriptación
Una deficiencia común de las herramientas de captura de paquetes es la incapacidad de ver los datos que se encriptan a través de una conexión SSL. En el ejemplo anterior, se accede a un feed público, por lo que no es necesario el protocolo SSL. Sin embargo, si el ejemplo accediera a un feed privado, el cliente debería autenticarse con el servicio de autenticación de Google, que sí requiere una conexión SSL.
El siguiente fragmento es similar al ejemplo anterior, pero aquí CalendarService
solicita el metafeed del calendario del usuario, que es un feed privado que requiere autenticación. Para autenticarte, solo llama al método setUserCredentials
. Este método activa una solicitud HTTPS al servicio ClientLogin y toma el token de autenticación de la respuesta. Luego, el objeto CalendarService
incluirá el token de autenticación en todas las solicitudes posteriores.
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();
Ten en cuenta el tráfico de red necesario para autenticar y acceder a un feed privado de la API de Google Data:
- Envía las credenciales del usuario al servicio de ClientLogin.
- Envía una solicitud
POST
HTTP a https://www.google.com/accounts/ClientLogin con los siguientes parámetros en el cuerpo del mensaje:- Correo electrónico: Es la dirección de correo electrónico del usuario.
- Passwd: Es la contraseña del usuario.
- source: Identifica tu aplicación cliente. Debe tener el formato companyName-applicationName-versionID. En los ejemplos, se usa el nombre ExampleCo-FiddlerSSLExample-1.
- service: El nombre del servicio del Calendario de Google es "cl".
- Envía una solicitud
- Recibe el token de autorización.
- Si falla la solicitud de autenticación, recibirás un código de estado HTTP 403 Forbidden.
- Si se realiza correctamente, la respuesta del servicio es un código de estado HTTP 200 OK, además de tres códigos alfanuméricos largos en el cuerpo de la respuesta:
SID
,LSID
yAuth
. El valorAuth
es el token de autorización.
- Solicita un metafeed de calendario privado.
- Envía una solicitud HTTP
GET
a http://www.google.com/calendar/feeds/default con el siguiente encabezado:
Authorization: GoogleLogin auth=<yourAuthToken>
- Envía una solicitud HTTP
Intenta ejecutar este fragmento y ver el tráfico de red en WireShark (con "http || ssl" como filtro). Verás los paquetes SSL y TLS involucrados en la transacción, pero los paquetes de solicitud y respuesta de ClientLogin están encriptados en los paquetes de "Datos de la aplicación". No te preocupes, a continuación, veremos una herramienta que puede revelar esta información encriptada.
Fiddler
Fiddler es otra herramienta gráfica de captura de paquetes, pero se comporta de manera muy diferente a las herramientas presentadas hasta ahora. Fiddler actúa como proxy entre tu aplicación y los servicios remotos con los que interactúas, y se convierte en un intermediario. Fiddler establece una conexión SSL con tu aplicación y el servicio web remoto, desencripta el tráfico de un extremo, captura el texto sin formato y vuelve a encriptar el tráfico antes de enviarlo. Lamentablemente, Fiddler solo está disponible para Windows. Lo sentimos por los usuarios de Mac y Linux.
Nota: La compatibilidad con SSL requiere la versión 2 de Fiddler y la versión 2 .0 de.NET Framework.
La visualización del tráfico de red en Fiddler se realiza principalmente a través de la pestaña Session Inspector. Las pestañas secundarias más útiles para depurar problemas con las APIs de Google Data son las siguientes:
- Encabezados: Muestra los encabezados HTTP en un formato de árbol contraíble.
- Auth: Muestra los encabezados de autenticación.
- Sin procesar: Muestra el contenido de los paquetes de red en texto ASCII.
SUGERENCIA: Haz clic en el ícono en la esquina inferior izquierda de la ventana de Fiddler para activar y desactivar la captura.
Fiddler usa .NET Framework para configurar las conexiones de red de modo que usen Fiddler como proxy. Esto significa que cualquier conexión que realices con Internet Explorer o con código .NET aparecerá en Fiddler de forma predeterminada. Sin embargo, el tráfico de la muestra de Java anterior no aparecerá porque Java tiene una forma diferente de configurar los proxies HTTP.
En Java, puedes configurar el proxy HTTP con las propiedades del sistema. Fiddler se ejecuta en el puerto 8888, por lo que, para una instalación local, puedes hacer que el código Java use Fiddler como proxy para HTTP y HTTPS agregando estas líneas:
System.setProperty("http.proxyHost", "localhost"); System.setProperty("http.proxyPort", "8888"); System.setProperty("https.proxyHost", "localhost"); System.setProperty("https.proxyPort", "8888");
Si ejecutas la muestra con estas líneas, obtendrás un registro de seguimiento desagradable del paquete de seguridad de 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 puede desencriptar y mostrar el tráfico SSL.
Este error ocurre cuando no se puede verificar el certificado que devolvió el servidor en una conexión SSL. En este caso, el certificado incorrecto proviene de Fiddler, que actúa como intermediario. Fiddler genera certificados sobre la marcha y, como no es una entidad emisora de confianza, estos certificados harán que Java no pueda configurar la conexión SSL.
Nota: Cuando Fiddler se está ejecutando, cualquier conexión SSL que realices en Internet Explorer activará una "Alerta de seguridad" que te preguntará si deseas continuar a pesar del certificado incompleto. Puedes hacer clic en "Ver certificado" para ver el certificado que generó Fiddler.
Entonces, ¿cómo puedes evitar esta excepción de seguridad? Básicamente, debes volver a configurar el framework de seguridad de Java para que confíe en todos los certificados. Por suerte, no tienes que reinventar la rueda. Consulta la solución de Francis Labrie y agrega el método SSLUtilities.trustAllHttpsCertificates()
al ejemplo anterior.
Una vez que hayas configurado Java para usar Fiddler como proxy y hayas inhabilitado la verificación de certificados predeterminada, podrás ejecutar el ejemplo y ver todo el tráfico que se envía a través de la red en texto sin formato. ¡No me robes la contraseña!
Recuerda que esta transacción de autenticación es solo un pequeño ejemplo del tráfico SSL. Algunas aplicaciones web usan conexiones SSL de forma exclusiva, por lo que depurar el tráfico HTTP está fuera de discusión sin una forma de descifrar los datos.
Conclusión
tcpdump está disponible en Linux, Mac OS X y Windows, y es una excelente herramienta cuando sabes lo que buscas y solo necesitas una captura rápida. Sin embargo, existen algunas herramientas gráficas que presentan el tráfico de red en formatos más fáciles de comprender. tcpdump tiene muchas más opciones y capacidades de filtrado que las que se trataron aquí. Para obtener una descripción completa de la funcionalidad de tcpdump, escribe "man tcpdump" o visita la página del manual de tcpdump en línea.
WireShark también está disponible en Linux, Mac OS X y Windows. La compatibilidad integrada con cientos de protocolos hace que WireShark sea una herramienta útil para muchas aplicaciones, no solo para la depuración de HTTP. Esta introducción apenas roza la superficie de las muchas capacidades de WireShark. Para obtener más información, escribe "man wireshark" o visita el sitio web de WireShark.
Fiddler también tiene muchas funciones excelentes, pero lo que lo diferencia es su capacidad para desencriptar el tráfico SSL. Para obtener más información, visita el sitio web de Fiddler2.
Estas aplicaciones de rastreo de paquetes son herramientas excelentes para tener en tu caja de herramientas, y los lectores observadores habrán notado que todas son gratuitas. La próxima vez que trabajes con las APIs de Google y veas algo sospechoso, usa uno de estos analizadores de red y observa con más detalle lo que sucede en la red. Si no encuentras el problema, puedes publicar una pregunta en nuestro grupo de debate. Incluir los mensajes de red pertinentes ayudará a otras personas a comprender y diagnosticar tu problema específico.
¡Buena suerte y que disfrutes de la experiencia!