Artículo original publicado el domingo, 20 de marzo de 2011

Uno de los retos interesantes al intentar solucionar problemas en sistemas conectados de forma remota es averiguar qué se dicen entre sí. El kit de CASI sobre el que escribí otras veces en este blog (http://blogs.msdn.com/b/sharepoint_sp/archive/2010/12/14/parte-1-del-kit-de-herramientas-de-integraci-243-n-de-notificaciones-azure-y-sharepoint.aspx ) es un buen ejemplo cuya finalidad principal es proporcionar establecimiento para conectar nubes de centro de datos entre sí. Una de las dificultades en la solución de problemas es el caso en que el tráfico viaja a través de SSL, lo que puede ser bastante difícil de solucionar. He indagado mediante WireShark y NetMon 3.4, que ahora incluye un complemento experto para SSL que se puede obtener de http://nmdecrypt.codeplex.com/. Personalmente siempre he usado NetMon, pero he tenido algunas dificultades para lograr que el experto de SSL funcione, por lo que decidí probar con WireShark.

Parece que WireShark ha tenido compatibilidad con SSL desde hace un par de años; solo se requiere proporcionar la clave privada que se usa con el certificado SSL que cifra la conversación. Dado que el servicio WCF es uno que escribí, es bastante fácil de entender. Mucha de la documentación en torno a WireShark sugiere que se necesita convertir el PFX del certificado SSL (el formato que se obtiene al exportar el certificado e incluir la clave privada) en un formato PEM. Si lee el sitio wiki más reciente del SSL de WireShark (http://wiki.wireshark.org/SSL), parece que realmente no es cierto. Citrix realmente tiene un buen artículo sobre cómo configurar WireShark para usar SSL (http://support.citrix.com/article/CTX116557), pero las instrucciones son algo crípticas en cuanto a los valores que se deben usar para la propiedad de la "lista de claves RSA" en la configuración del protocolo SSL (si no está seguro de qué se trata, simplemente lea el artículo de soporte técnico de Citrix citado anteriormente). Para combinar ese artículo de Citrix y la información sobre el sitio wiki de WireShark, a continuación se presentan rápidamente esos valores:

  • Dirección IP: es la dirección IP del servidor que envía el contenido cifrado de SSL que se va a descifrar
  • Puerto: es el puerto desde el que se transmite el tráfico cifrado Para un extremo de WCF, probablemente siempre será 443.
  • Protocolo: para un extremo de WCF, siempre debe ser http
  • Nombre del archivo de clave: es la ubicación en disco en la que se encuentra el archivo de clave
  • Contraseña: si va a usar un certificado PFX, este es un quinto parámetro: la contraseña para desbloquear el archivo PFX. El artículo de Citrix no trata acerca de esto, pero el sitio wiki de WireShark sí.

Por lo tanto, suponga que el extremo de Azure WCF está en la dirección 10.20.30.40 y tiene un certificado PFX en C:\certs\myssl.pfx con la contraseña "FooBar". El valor que se colocaría en la propiedad de la lista de claves RSA en WireShark sería:

10.20.30.40,443,http,C:\certs\myssl.pfx,FooBar.

Ahora bien, otra alternativa es descargar OpenSSL para Windows y crear un archivo PEM a partir de un certificado PFX. Casualmente, acabo de encontrar esta descarga en http://code.google.com/p/openssl-for-windows/downloads/list, aunque parece que se puede descargar de muchos sitios en Internet. Una vez que haya descargado los bits que son adecuados para el hardware, puede crear un archivo PEM a partir del certificado PFX con esta línea de comandos en el directorio bin de OpenSSL:

openssl.exe pkcs12 -in <drive:\path\to\cert>.pfx -nodes -out <drive:\path\to\new\cert>.pem

Suponga que hizo lo anterior y creó un archivo PEM en C:\certs\myssl.pem; la propiedad de la lista de claves RSA en WireShark sería:

10.20.30.40,443,http,C:\certs\myssl.pem

Otra cosa que hay que señalar es que se pueden agregar varias entradas separadas por punto y coma. Así, por ejemplo, tal como lo describí en la serie de kit de CASI, se empieza con un servicio WCF que se hospeda en el conjunto o granja de servidores local y tal vez se ejecuta en el tejido de Azure. A continuación, se publica en Windows Azure. Pero al solucionar problemas, puede que sea conveniente usar el servicio local o el servicio de Windows Azure. Uno de los efectos secundarios positivos de adoptar el enfoque que he descrito en el kit de CASI de usar un certificado comodín es que permite usar el mismo certificado SSL para la instancia local, así como la instancia de Windows Azure. Por lo tanto, en WireShark, también se puede usar el mismo certificado para descifrar tráfico con tan solo especificar dos entradas como esta (suponga que el servicio WCF local se ejecuta en la dirección IP 192.168.20.100):

10.20.30.40,443,http,C:\certs\myssl.pem;192.168.20.100,443,http,C:\certs\myssl.pem

Esos son los aspectos básicos de la configuración de WireShark, que realmente podría haber usado anoche. :-)  Ahora bien, el otro aspecto realmente complicado es descifrar el SSL. El problema principal que veo por el trabajo que he hecho es que se necesita comprobar que durante la negociación se está capturando con el extremo de SSL. Por desgracia, con los distintos comportamientos de almacenamiento en caché de Internet Explorer y Windows he comprobado que era muy difícil conseguirlo cuando intentaba realizar un seguimiento de las llamadas de WCF que salían del explorador a través del kit de CASI. Después de unas 2 horas intentándolo en el explorador, solo terminé obteniendo un seguimiento al extremo de Azure, que de hecho pude descifrar en WireShark, por lo que casi me vuelvo loco. Una vez más, el cliente de prueba de WCF vino al rescate. 

La forma que he descubierto ahora para lograr que esto funcione de forma coherente consiste en:

  1. Iniciar WireShark y comenzar una captura.
  2. Iniciar el cliente de prueba de WCF.
  3. Agregar una referencia de servicio a WCF (ya sea el WCF local o el WCF de Windows Azure).
  4. Invocar uno o más métodos en WCF desde el cliente de prueba de WCF.
  5. Volver a WireShark y detener la captura.
  6. Buscar cualquier marco en el que el protocolo diga TLSV1.
  7. Hacer clic con el botón secundario en él y seleccionar Seguir la secuencia SSL en el menú.

Aparecerá un cuadro de diálogo que debería mostrar el contenido sin cifrar de la conversación. Si la conversación está vacía, probablemente significa que la clave privada no se cargó correctamente o que la captura no incluía la sesión negociada. Si funciona, es bastante interesante, ya que puede ver toda la conversación o solo cosas del remitente o el receptor. Este es un recorte rápido de lo que obtuve de un seguimiento al método WCF a través de SSL en Windows Azure:

  • POST /Customers.svc HTTP/1.1
  • Content-Type: application/soap+xml; charset=utf-8
  • Host: azurewcf.vbtoys.com
  • Content-Length: 10256
  • Expect: 100-continue
  • Accept-Encoding: gzip, deflate
  • Connection: Keep-Alive
  • HTTP/1.1 100 Continue
  • HTTP/1.1 200 OK
  • Content-Type: application/soap+xml; charset=utf-8
  • Server: Microsoft-IIS/7.0
  • X-Powered-By: ASP.NET
  • Date: Sat, 19 Mar 2011 18:18:34 GMT
  • Content-Length: 2533
  • <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" blah blah blah

Y ahí lo tiene; tardé un tiempo para lograr que esto funcionara, así que espero que le ayude a entrar al modo de solución de problemas un poco más rápido que yo.

Esta entrada de blog es una traducción. Puede consultar el artículo original en Using WireShark to Trace Your SharePoint 2010 to Azure WCF Calls over SSL