Utilizzo di WireShark per tracciare le chiamate WCF da SharePoint 2010 ad Azure su SSL
Articolo originale pubblicato domenica 20 marzo 2011
Una delle sfide più interessanti da affrontare quando si esegue in remoto la risoluzione dei problemi relativi a sistemi connessi è rappresentata dalla possibilità di determinare quali comunicazioni avvengano fra tali sistemi. Il CASI Kit che ho inserito in precedenza in questo blog (https://blogs.msdn.com/b/sharepoint_it/archive/2010/12/17/toolkit-casi-claims-azure-and-sharepoint-integration-parte-1.aspx) è un buon esempio perché ha come scopo principale quello di garantire il plumbing per interconnettere cloud di data center. Una delle difficoltà che si presentano durante la risoluzione dei problemi è costituita dal fatto che il traffico transita su SSL, pertanto può essere piuttosto difficile diagnosticarne e risolverne i problemi. Ho valutato l'utilizzo di NetMon 3.4, che ora dispone di un componente aggiuntivo Expert per SSL scaricabile da https://nmdecrypt.codeplex.com/, e WireShark. Personalmente ho sempre utilizzato NetMon, ma ho avuto qualche difficoltà a far funzionare il suddetto componente aggiuntivo SSL. Ho quindi deciso di provare WireShark.
Sembra che il supporto di WireShark per SSL ormai sia disponibile da un paio di anni. È solo necessario specificare la chiave privata utilizzata con il certificato SSL che crittografa la conversazione. Poiché il servizio WCF è stato scritto da me, è abbastanza facile reperirlo. In gran parte della documentazione relativa a WireShark viene suggerito che è necessario convertire il PFX del certificato SSL (ovvero il formato che si ottiene esportando il certificato e includendo la chiave privata) in un formato PEM. Se tuttavia si legge il sito wiki più recente su WireShark con SSL (https://wiki.wireshark.org/SSL), pare che ciò non sia del tutto vero. Per Citrix è disponibile un articolo esauriente su come configurare WireShark per l'utilizzo di SSL (https://support.citrix.com/article/CTX116557), ma le istruzioni risultano poco chiare riguardo ai valori da utilizzare per la proprietà relativa all'elenco delle chiavi RSA nelle impostazioni del protocollo SSL. In caso di dubbi, leggere l'articolo di supporto relativo a Citrix sopra citato. Combinando tale articolo su Citrix e le informazioni presenti nel sito wiki su WireShark, di seguito riporto un breve riepilogo di questi valori:
- Indirizzo IP - Indirizzo IP del server da cui si riceve il contenuto crittografato con SSL che si desidera decrittografare.
- Porta - Porta attraverso cui passa il traffico crittografato. Per un endpoint WCF, probabilmente sarà sempre la porta 443.
- Protocollo - Per un endpoint WCF, deve essere sempre http.
- Nome del file della chiave - Percorso su disco in cui si trova il file della chiave.
- Password - Se si utilizza un certificato PFX, questo è un quinto parametro e corrisponde alla password per sbloccare il file PFX. Tale parametro non viene trattato nell'articolo relativo a Citrix, ma è illustrato nel sito wiki su WireShark.
Si supponga pertanto che l'endpoint WCF di Azure si trovi all'indirizzo 10.20.30.40 e che in C:\certs\myssl.pfx sia disponibile un certificato PFX con la password "FooBar". Il valore da inserire nella proprietà relativa all'elenco delle chiavi RSA in WireShark sarà perciò il seguente:
10.20.30.40,443,http,C:\certs\myssl.pfx,FooBar.
In alternativa, è ora possibile scaricare OpenSSL per Windows e creare un file PEM da un certificato PFX. Mi è appena capitato di trovare questo pacchetto all'indirizzo https://code.google.com/p/openssl-for-windows/downloads/list, ma sembra che sul Web siano disponibili diversi percorsi di download. Dopo avere scaricato il pacchetto appropriato per l'hardware di cui si dispone, è possibile creare un file PEM dal certificato PFX con questa riga di comando nella directory bin di OpenSSL:
openssl.exe pkcs12 -in <unità:\percorso\del\cert>.pfx -nodes -out <unità:\percorso\del\nuovo\cert>.pem
Presupponendo che abbiate eseguito queste operazioni e creato un file PEM in C:\certs\myssl.pem, la proprietà relativa all'elenco delle chiavi RSA in WireShark sarà quindi la seguente:
10.20.30.40,443,http,C:\certs\myssl.pem
Un altro aspetto da sottolineare è la possibilità di aggiungere più voci separate dal punto e virgola. Ad esempio, come spiegato nella serie relativa al CASI Kit, comincio perciò con un servizio WCF ospitato nella farm locale, forse in esecuzione nell'infrastruttura Azure Dev. Lo pubblico quindi in Windows Azure. Ma durante la risoluzione dei problemi ho la necessità di connettermi al servizio locale oppure al servizio Windows Azure. Uno dei vantaggi collaterali dell'approccio che ho descritto nel CASI Kit, ovvero l'utilizzo di un certificato con caratteri jolly, è la possibilità di utilizzare lo stesso certificato SSL sia per l'istanza locale che per l'istanza di Windows Azure. In WireShark posso pertanto utilizzare il medesimo certificato anche per decrittografare il traffico semplicemente specificando due voci come mostrato di seguito (presupponendo che il servizio WCF locale sia in esecuzione all'indirizzo 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
Queste sono le nozioni fondamentali per impostare WireShark che avrei potuto effettivamente utilizzare l'altra notte invece di fare mattina per trovare una soluzione. :-) Ora l'altra questione spinosa è la decrittografia di SSL. Dal lavoro che ho svolto, sembra che il problema principale sia la necessità di verificare che i dati vengano acquisiti durante la negoziazione con l'endpoint SSL. Ho sfortunatamente scoperto con tutti i diversi comportamenti di memorizzazione nella cache di Internet Explorer e Windows che l'esecuzione di tale verifica era veramente difficile durante il tentativo di tracciare le chiamate WCF provenienti dal browser tramite il CASI Kit. Dopo altre due ore circa di tentativi nel browser, ho ottenuto solo una traccia fino all'endpoint Azure decrittografabile in WireShark, quindi stavo letteralmente impazzendo. In mio soccorso è però arrivato ancora una volta Client di test WCF.
Per far funzionare sempre tutto, ho perciò capito che è necessario procedere come segue:
- Eseguire WireShark e avviare un'acquisizione.
- Avviare Client di test WCF.
- Aggiungere a WCF (locale o di Windows Azure) un riferimento al servizio.
- Richiamare uno o più metodi su WCF da Client di test WCF.
- Tornare a WireShark e interrompere l'acquisizione.
- Trovare un frame in cui il protocollo indichi TLSV1.
- Fare clic con il pulsante destro del mouse su di esso e scegliere Follow SSL Stream dal menu.
Verrà visualizzata una finestra di dialogo con il contenuto decrittografato della conversazione. Se la conversazione è vuota, è probabile che la chiave privata non sia stata caricata correttamente oppure che nell'acquisizione non fosse inclusa la sessione negoziata. Se invece funziona, è molto utile perché è possibile visualizzare l'intera conversazione oppure solo i dati del mittente o del destinatario. Di seguito è riportato un breve stralcio dei dati ottenuti da una traccia del mio metodo WCF su SSL fino a 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="https://www.w3.org/2003/05/soap-envelope" blah blah blah
Ecco qua. Ho impiegato un bel po' di tempo per sistemare tutto, perciò spero che questo vi sia utile per avviare la risoluzione dei problemi più rapidamente di me.
Questo è un post di blog localizzato. L'articolo originale è disponibile in Using WireShark to Trace Your SharePoint 2010 to Azure WCF Calls over SSL.