使用 WireShark 跟踪 SharePoint 2010 与 Azure WCF 通过 SSL 进行的对话
原文发布于 2011 年 3 月 20 日(星期日)
尝试对远程连接的系统进行故障诊断时,其中一个有趣的挑战是确定它们之间的通信内容是什么。我以前在此博客上发布的有关 CASI 工具包的文章 (https://blogs.msdn.com/b/sharepoint_chs/archive/2010/12/17/azure-sharepoint-1.aspx) 就是一个很好的示例,其唯一的主要目标就是提供通道以将各个数据中心云连接在一起。故障诊断时遇到的困难之一就是流量是通过 SSL 传送的,所以诊断起来很麻烦。我调查了使用 NetMon 3.4(其现在具有用于 SSL 的 Expert 加载项,该加载项可从 https://nmdecrypt.codeplex.com/(该链接可能指向英文页面) 获得)和使用 WireShark 这两种情况。我个人一直使用 NetMon,但是在让 SSL Expert 工作方面遇到了点问题,所以决定试下 WireShark。
WireShark 对于 SSL 的支持到现在已经有好几年了;只需要您提供加密会话的 SSL 证书所使用的私钥即可。因为我写过 WCF 服务这篇文章,所以我很轻松地就获得了该密钥。有关 WireShark 的很多文档都建议您将 PFX 格式(导出证书并包括私钥时获得的格式)的 SSL 证书转换为 PEM 格式。如果您阅读了最新的 WireShark SSL wiki (https://wiki.wireshark.org/SSL(该链接可能指向英文页面)),就会发现这实际上不是真的。Citrix 实际上有不错的文章介绍如何将 WireShark 配置为使用 SSL (https://support.citrix.com/article/CTX116557(该链接可能指向英文页面)),只是当谈及应对 SSL 协议设置中的“RSA 密钥列表”属性使用哪些值时,说明有点模糊不清(如果您不确定其内容,只需按照上面的 Citrix 支持文章执行就可以了)。因此,为了将那篇 Citrix 文章和 WireShark wiki 上的信息结合起来,下面提供了这些值的简单介绍:
- IP 地址 - 这是将向您发送 SSL 加密内容的服务器的 IP 地址,您需要这些内容进行解密
- 端口 - 这是加密的信息流通过的端口。对于 WCF 端点,应该始终是 443。
- 协议 - 对于 WCF 端点,这应该始终是 http
- 密钥文件名 - 这是您在磁盘上放置密钥文件的位置
- 密码 - 如果您使用 PFX 证书,这是第五个参数,即用于解锁 PFX 文件的密码。这在 Citrix 文章中并没有介绍,但是在 WireShark wiki 中有介绍。
所以,假设您的 Azure WCF 端点的地址为 10.20.30.40,而且密码为“FooBar”的 PFX 证书位于 C:\certs\myssl.pfx。那么您要在 WireShark 的 RSA 密钥列表属性中输入的值将为:
10.20.30.40,443,http,C:\certs\myssl.pfx,FooBar。
现在,您还可以下载用于 Windows 的 OpenSSL 并从 PFX 证书创建一个 PEM 文件。我刚好在 https://code.google.com/p/openssl-for-windows/downloads/list(该链接可能指向英文页面) 上找到了该下载文件,但是网络上似乎有很多位置可以下载。只要下载的位数适合您的硬件,即可使用下面的命令行在 OpenSSL bin 目录中从 PFX 证书创建 PEM 文件:
openssl.exe pkcs12 -in <drive:\path\to\cert>.pfx -nodes -out <drive:\path\to\new\cert>.pem
所以,假设您完成该操作并在 C:\certs\myssl.pem 处创建了一个 PEM 文件。那么 WireShark 中的 RSA 密钥列表属性将为:
10.20.30.40,443,http,C:\certs\myssl.pem
另一件要说明的事情是您可以添加用分号隔开的多个条目。例如,就像我在 CASI 工具包系列中介绍的那样,我的本地场中托管的 WCF 服务可能运行在 Azure 开发结构中。然后我将其发布到 Windows Azure。但是当我进行故障诊断时,我可能希望命中本地服务或 Windows Azure 服务。采用我在 CASI 工具包中介绍的使用通配符证书的方法的一个好处就是,它允许我对本地实例和 Windows Azure 实例使用同一 SSL 证书。所以在 WireShark 中,我还可以使用同一证书来解密信息流,只需通过指定类似下面的两个条目即可(假定我的本地 WCF 服务运行在 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
以上是设置 WireShark 的基础,昨天深夜我本来可尝试使用一下的。:-) 现在,另一件棘手的事情就是解密 SSL。从我目前所做的工作来看,主要的问题在于您需要确保在与 SSL 端点协商的期间即开始捕获。很遗憾,观察 IE 和 Windows 的所有各种各样的缓存行为之后,我发现当尝试通过 CASI 工具包跟踪从浏览器传出的 WCF 调用时,很难真正做到这一点。在浏览器上尝试了大约 2 个多小时之后,我最终仅将一个跟踪捕获回 Azure 端点并在 WireShark 中进行实际解密,所以我差点就疯了。再一次启用急救方案,但使用的是 WCF 测试客户端。
我目前找到的解决此问题的一贯做法是:
- 启动 WireShark 并开始捕获。
- 启动 WCF 测试客户端
- 添加对 WCF 的服务引用(不论它是本地 WCF 还是 Windows Azure WCF)
- 从 WCF 测试客户端对 WCF 调用一个或多个方法。
- 返回 WireShark 并停止捕获。
- 找到协议为 TLSV1 的任何帧
- 右键单击该帧,然后从菜单中选择“跟踪 SSL 流”
随即弹出一个对话框,向您显示未加密的对话内容。如果对话为空,则可能意味着未正确加载私钥,或捕获不包括协商的会话。如果工作还算顺利的话,您可以看到整个对话,或者仅看到发送方(或接收方)的内容。下面是从我的 WCF 方法通过 SSL 对 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" .....
到此就完了;我花了点时间才完成了这些,所以希望这能帮助您比我更快进入故障诊断模式。
这是一篇本地化的博客文章。请访问 Using WireShark to Trace Your SharePoint 2010 to Azure WCF Calls over SSL 以查看原文