内容


配置 Tomcat 和 Wireshark 来获取并解码 SSL 通信

调试安全通信

前言

开发一个涉及网络通信的系统,在今天的分布式世界是极为普遍的。在开发这类系统的过程中,一个通信问题可能会使得评估或者调试软件变得困难。这时,您可以借助像 Wireshark 这样的工具,它可以捕获您系统中的所有网络流量,并使您能够进行读取。它常常为解决问题提供所需的洞察力。如果您的系统使用 SSL 保障通信,那么虽然您可以捕获网络流量,但是这些数据都经过了加密,使开发人员无法从中获取任何有用信息。幸运的是,带有 SSL Dissector 的 Wireshark,如果加以正确配置,就能解密已捕获的流量数据。本教程会分步指导如何设置这些条件,把 Tomcat 用作服务器,把浏览器当做客户机。

目标

学习过本教程后,您将会了解到怎样设置各种条件来使 Wireshark 的 SSL Dissector 正常工作。不仅如此,您还可以在 Tomcat 的安装中配置这些条件以使其得以满足

先决条件

本教程的前提是需要您对网络通信机制有一个基本的了解。您不需要有使用 Tomcat 和 Wireshark 的经验,不过如果曾有相关经验将会很有帮助。特别指出,本教程并未对正确配置后如何使用 Wiresharkn 进行深入探讨。

请注意:本教程主旨不在给出为什么 这些命令能够运行的深入说明,或者给出该命令多种可能性的考虑。它的目的是使您能够在开发环境中记录并解码网络流量。需要重点指出的是,随后的过程和在此生成的部分加密工件是非常不安全的,所以一定不能应用于生产环境中。

系统需求

本教程设定您当前使用的环境是 Windows®。跟随此教程,您需要先进行如下安装(参见 参考资料

  • Tomcat 5.5
  • 一个合适 Tomcat 的 JVM
  • Wireshark — 版本 1.2.2 用于本教程开发。Wireshark 下载必须 用 GnuTLS 和 Gcrypt 编译。这点可以在 Wireshark 的 “About” 窗口核实。
  • Cygwin 包括 openssl — 版本 0.9.8i openssl 用于本教程开发。
  • Jetty — 版本 6.1.21 用于本教程开发。其他版本(更新版本和更旧版本)也可以运行,但它所需的各类文件的位置会发生改变。

此外,您还需要另一台机器,利用这台机器上的浏览器来访问您的 Tomcat 服务器。

概述

满足下列关键条件才允许 Wireshark 对一个安全连接进行解密:

  • 配置 Tomcat 必须有一个服务器证书。
  • 用于客户机和服务器(浏览器和 tomcat)之间的特殊加密密码必须能用 Wireshark 的解密方式进行解密。
  • Wireshark 必须获得与服务器证书关联的私钥。

本教程将会按这个顺序执行这些步骤,然后使用浏览器连接 Tomcat 服务器,我们将获得一个请求和响应,然后就能在 Wireshark 中进行检查。

关于密码的一点说明

在本教程中,您需要设置三个独立的密码。每个密码都被谨慎地命名,在教程中也有引用,但是为了方便应用,您可以考虑设置同一密码应用于三个地方。

创建一个私钥和证书

首先我会说明怎样用 openssl 创建一个私钥。开启 Cygwin,执行以下命令:

openssl genrsa -des3 -out ./serverkey.pem 2048

它将要求您为生成的 pem 文件提供一个通行短语。我稍后会在此教程中将此通行短语称为 <server key pass phrase>。在提供和核实了这个通行短语之后,这个命令就完成了,一个新的私钥已经生成并存储在文件 serverkey.pem. 里了。

现在执行以下命令(注意:所有命令应在同一行上;此处没有显示在同一行上是受教程模板的限制):

openssl req -new -x509 -key ./serverkey.pem -out ./servercert.pem -subj 
'/C=GB/ST=XX/O="My Org"/CN="Wireshark dissectable Cert"'

这时将有提示需要您提供通行短语,您输入先前选择的 <server key pass phrase> 即可。这样就会生成一个服务器证书,存储在 servercert.pem 中,与您先前生成的私钥保持一致。

将证书转换为 JKS keystore

很不幸,上一步生成的服务器证书不是 Tomcat 所要求的格式,所以您必须将其转换为 JKS keystore 形式。第一步您先要执行以下命令(在 Cygwin 中运行)将其转换为 PKCS12 格式:

openssl pkcs12 -export -in ./servercert.pem -inkey ./serverkey.pem  
-certfile ./servercert.pem -out ./servercert.p12 -name "cert-name"

这时又会提示您输入通行短语,您需要输入 <server key pass phrase>。然后会提示您再输入一个新的通行短语,本教程后面将其称为 <server p12 pass phrase>。在输入和核实了新的通行短语之后,该命令就完成了,新的文件 servercert.p12 也将生成完毕。

然后,我们利用 Jeffy 发行版中的工具来把这个证书移动到 JKS keystore。不同版本的 Jeffy 可能将这个类放到不同的 jar 文件中,甚至是在发行版的不同的数据包中。在 Jetty 6.1.21 发行版中,所需的类被放在 org.mortbay.jetty.security 包的主 jetty-6.1.21 jar 中。需要运行的命令(假设这个 jar 文件位于当前目录)如下所示:

java -classpath ./jetty-6.1.21.jar org.mortbay.jetty.security.PKCS12Import 
./server.p12 ./dissectable.keystore

它首先会提示您输入 Keystore 的通行短语,就是您之前选择的 <server p12 pass phrase>。然后会要求您为新的 Keystore 选择一个新的通行短语。我将在本教程中称其为 <server jks pass phrase>。注意:因为不会要求您确认这个通行短语,所以请务必正确输入。

注意:如果您使用的不是同一个版本的 Jetty,您可能会发现 PKCS12Import class 在不同的 jar 文件中,甚至在不同的数据包下。

解除对私钥的保护

使用 openssl 的最后一步工作就是删除当前用于保护您的私钥的通行短语。只有完成了这一步,Wireshark 才能正确读取 key 文件。在 cygwin 中,下列命令能够从 key 文件中移除通行短语保护:

openssl rsa –in ./serverkey.pem –out ./open-private-key.pem

这个命令将会提示您输入通行短语。您应输入之前选择的 <server key pass phrase>。此命令会生成一个新的文件 open-private-key.pem,它包含一个您的私钥的未受保护的副本。

配置 Tomcat

现在您已经有了所需的加密工件,您可以配置 Tomcat 来使用它们。有三个配置步骤是您必须完成的:

  • 把 dissectable.keystore 复制到 Tomcat 的根目录下。
  • 命令 Tomcat 使用您已创建的服务器证书。
  • 将密码集限制为 Wireshark 可以处理的密码。

通过编辑同一文件能够完成最后两步。在 Tomcat 的安装过程中,浏览 conf 目录,编辑 server.xml 文件。定位文件中定义 SSL 连接器的部分,如清单 1 所示:

清单 1. 默认 SSL 连接器定义
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
    <!--
    <Connector port="8443" 
        maxHttpHeaderSize="8192"
        maxThreads="150"
        minSpareThreads="25" 
        maxSpareThreads="75"       
        enableLookups="false" 
        disableUploadTimeout="true"          
        acceptCount="100" 
        scheme="https" secure="true"           
        clientAuth="false" 
        sslProtocol="TLS" />
    -->

删除第二行和最后一行,使 xml 看起来像清单 2 所示的代码。

清单 2. 取消注释的 SSL 连接器定义
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
    <Connector 
        port="8443" 
        maxHttpHeaderSize="8192"      
        maxThreads="150" 
        minSpareThreads="25" 
        maxSpareThreads="75"     
        enableLookups="false" 
        disableUploadTimeout="true"        
        acceptCount="100" 
        scheme="https" 
        secure="true"       
        clientAuth="false" 
        sslProtocol="TLS" 
    />

然后修改连接器元素使其包含以下的粗体文档。这将假设您将 dissectable.keystore 文件复制到 Tomcat 的安装根目录下(即与 LICENSE 和 NOTICE 文件相同的位置)。在下例中出现 "password here" 的位置,您需要输入之前选择的 <jks server pass phrase>。

清单 3. 修改后的 SSL 连接器定义
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
    <Connector 
        port="8443" 
        maxHttpHeaderSize="8192"      
        maxThreads="150" 
        minSpareThreads="25" 
        maxSpareThreads="75"     
        enableLookups="false" 
        disableUploadTimeout="true"        
        acceptCount="100" 
        scheme="https" 
        secure="true"       
        clientAuth="false" 
        sslProtocol="TLS" 
 keystoreFile="dissectable.keystore"keystorePass=""ciphers="SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,  SSL_RSA_WITH_3DES_EDE_CBC_SHA"
    />

验证 Tomcat 配置

这时验证 Tomcat 是否正确配置是很有必要的。为此,只需在 bin 目录下运行 startup.bat 脚本就能确认 Tomcat 的配置。如果您已经正确配置一切,并将 ssectable.keystore 文件复制到正确位置,那么 Tomcat 就会正确无误地开始运行。

如果 Tomcat 没有正确开始运行,要么屏幕上显示有错误,要么是运行失败,那么您就需要检查两方面的内容,看您所做的 xml 编辑是否有输入错误,或者 keystore 文件是否位于正确的位置。

一旦 Tomcat 启动,您就可以通过启动 Web 浏览器和导航到 https://localhost:8443/ 来确认 SSL 连接开始运行。最初会出现服务器证书申诉,并询问您是否希望信任服务器(具体的术语因所使用的浏览器而异)。产生这个问题的原因是您之前创建的自签名证书,您应该回答您信任服务器。然后您会看到 Tomcat 的欢迎页面,这就表示您已经将 Tomcat 正确配置为支持安全连接。

配置 Wireshark

您已经完成了 Tomcat 的配置,现在需要配置 Wireshark。在您运行 Tomcat 的机器上启动 Wireshark,在菜单中选择 Edit --> Preferences(Ctrl-Shift P)

图 1. Wireshark 优选参数屏幕
Wireshark 应用程序优选参数屏幕的截图
Wireshark 应用程序优选参数屏幕的截图

展开左侧的 Protocols 项,并从显示的列表中选择 SSL

图 2. Wireshark SSL 配置会话
Wireshark SSL 配置会话的屏幕截图
Wireshark SSL 配置会话的屏幕截图

Options boxes

您需要选中所有选项框。

RSA keys list

RSA keys list 字段告诉 Wireshark 使用哪个私钥去解码会话,取决于会话的 IP 地址和端口。其格式是:

IPAddress,Port,Protocol,PrivateKey

多个条目可以采用如下所示的分号隔离列表,但是在本教程中我们只需要使用一个条目。

IPAddress1,Port1,Protocol1,PrivateKey1; IPAddress2,Port2,Protocol2,PrivateKey2

我假设现在运行 Tomcat 的 IP 地址是 192.168.45.22,它正在对端口 8443 的 SSL 流量进行监听。这个流量是 HTTP 流量,之前我们生成的 open-private-key.pem 文件已经被复制到 C 驱动器的根目录下。因此,输入 RSA keys list 字段的字符串是:

192.168.45.22,8443,http,c:\open-private-key.pem

您需要标识自己机器的 IP 地址。在 Cygwin 中,您可以运行

ipconfig /all

来完成。

注意:如果您的机器有多个网络适配器,您的机器可能会有多个 IP 地址。您所选的 IP 地址必须使第二台机器可以连接到当前机器的 Tomcat 服务器上。

SSL 调试文件

您需要先提供一个 Wireshark 能在其中输出调试结果的文件的名称。这对于检查您的 Wireshark 配置非常有用。

完成配置

单击 OK 完成配置。

验证配置

您现在应打开之前选择的 SSL 调试日志文件。如果您配置成功,您将会看到有文本提示您 Wireshark 已成功加载私钥。示例请参见清单 4。

清单 4. SSL 调试日志内容
ssl_association_remove removing TCP 9443 - http handle 040820A0
ssl_init keys string:
9.175.228.55,8443,http,C:\temp\open-private-key.pem
ssl_init found host entry 9.175.228.55,8443,http,C:\temp\open-private-key.pem
ssl_init addr '9.175.228.55' port '8443' filename 'C:\temp\open-private-key.pem'
 password(only for p12 file) '(null)'
Private key imported: KeyID 0E:BA:EA:08:5D:FA:FB:85:59:4A:7B:A9:B2:56:C3:16:...
ssl_init private key file C:\temp\open-private-key.pem successfully loaded
association_add TCP port 8443 protocol http handle 040820A0

这表明您已经正确完成了所有加密操作步骤和 Wireshark 配置步骤。如果您没有看到这条信息,您就需要重新审查之前的相关步骤。最有可能出现的问题是 RSA keys 列表中的 key 文件的路径,或是实际生成的私钥文件。

捕获会话

一旦您已经正确配置 Wireshark,您就可以开始记录会话了。在 Wireshark 中,从菜单中选择 Capture --> Interfaces(Ctrl I -- 大写 i)。这将会出现一个类似下面所示的会话:

图 3. Wireshark 界面显示会话
 Wireshark Capture Interfaces 屏幕截图,显示不同的适配器,其中包含 Start、Options 或 Details 按钮。
Wireshark Capture Interfaces 屏幕截图,显示不同的适配器,其中包含 Start、Options 或 Details 按钮。

您需要决定您的第二台机器通过已列出的网络接口的哪一个来连接到 Tomcat。这点已经很明显了,因为您需要知道用于 Wireshark 配置步骤的正确 IP 地址。如果您不确定,可以用第二台机器的 Web 浏览器进入 Tomcat 服务器,查看哪个接口显示数据包的数量增加。

一旦您选择了想要监听的接口,单击 options,然后就会出现另一个会话:

图 4. Wireshark 捕捉选项对话框
 Wireshark Capture Options 对话框的屏幕截图。
Wireshark Capture Options 对话框的屏幕截图。

您要在 Capture Filter 中输入以下内容来减少所捕获会话中的无关内容:

tcp port 8443

现在单击 Start 开始捕获流量。这时您还看不到任何数据包被捕获。您要转到第二台机器,用一个 url,例如 https://192.168.45.22:8443/ 来进入 Tomcat,但是要输入运行 Tomcat 的那台机器的 IP 地址或者主机名。当您在进行这一步骤时,将会告知您存在证书问题,并询问您是否信任服务器。和之前一样,您要选择信任服务器。之后浏览器上就会出现 Tomcat 的欢迎页面,并且在 Wireshark 中会出现多行数据。您现在可以通过在菜单中选择 Capture --> Stop 来停止捕捉。

如果您已经正确完成这些操作,您将会看到一个带有绿色行的屏幕,显示它们已经被解密,就像这样:

图 5. 成功的捕捉输出
Wireshark 数据包捕捉结果的屏幕截图 —— 几条用绿色突出显示的数据行表示它们已经被正确解密。
Wireshark 数据包捕捉结果的屏幕截图 —— 几条用绿色突出显示的数据行表示它们已经被正确解密。

然后您就可以像平时一样随意使用 Wireshark 分析 HTTP 会话并继续调查问题。

最后要说的是,如果您通常使用 follow tcp stream 来查看一个 HTTP 会话,那么现在就要用 follow ssl stream。它会用纯文本来显示您的 HTTP 会话:

图 6. 跟踪 SSL 流
Wireshark 中跟踪 SSL 流的屏幕截图,数据包被紧密集成在一起,显示标题和 HTML 代码。以 'Host:' 开始的行和最后以 'Cookie:' 开头的五行都被删除。
Wireshark 中跟踪 SSL 流的屏幕截图,数据包被紧密集成在一起,显示标题和 HTML 代码。以 'Host:' 开始的行和最后以 'Cookie:' 开头的五行都被删除。

故障数据包

在捕获的过程中,您很可能会遇到故障数据包,如下所示:

图 7. Wireshark 中的故障数据包
Wireshark 数据包捕获屏幕截图 —— 屏幕上有一些用黑色背景突出显示的数据包,表示它们在接收时出错。
Wireshark 数据包捕获屏幕截图 —— 屏幕上有一些用黑色背景突出显示的数据包,表示它们在接收时出错。

这会造成 SSL Dissector 局部中断。虽然能在靠近底部的地方看到一条绿行,但那个 GET 的响应并没有被解密。为了解决这个问题,您需要用 File --> Save As 来保存这个捕获。然后在 Cygwin 中运行 editcap –d capture.pcap fixed.pcap ,其中,editcap 被包含在 Wireshark 安装中,capture.pcap 是已保存的捕获文件,fixed.pcap 在命令运行后包含修正过的捕获文件。运行完这条命令之后,您可以重新把修正过的数据包获取文件加载到 Wireshark,然后您就会看到预期的已解密数据包。

没有出现绿行

Wireshark 依赖于捕获完整的 SSL 会话。如果您在本教程中从您的浏览器上发出多个请求,这就会造成部分已协定的安全连接被缓存,那么已捕获的会话就不会包含全部协定。 这将会妨碍 SSL Dissector 工作。检查捕获的启动,在 INFO 行中查找一个包含 “Server Hello, Certificate, Server Hello Done” 的条目。如果您未能找到这个条目,那么您的浏览器将会拒绝之前的部分协定。重启浏览器,重新尝试应该就能解决这个问题。

结束语

在本教程中,您学习了如何捕获和读取两个系统间的安全 HTTP 通信,了解了如何生成一个必需的密码工件以及如何配置 Wireshark 和 Tomcat 来正确使用它们。所涉及的步骤并不复杂,并且在熟悉了以后,执行起来也非常简单。在如今的安全和分布式系统领域中,这是一个非常强大的工具,但希望人们需要用到它的情况越少越好。

这一机制在 Web 浏览器连接到 Tomcat 服务器的上下文中进行了演示,但它也可以很容易地应用到任何通过 SSL 连接和 Tomcat 进行会话的系统中。通过进行更进一步的调查,这一程序也可以比较容易地应用于其他服务器。


相关主题

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development, Open source
ArticleID=462213
ArticleTitle=配置 Tomcat 和 Wireshark 来获取并解码 SSL 通信
publish-date=01182010