1. 前言
TLS协议是一种在不可信链路上建立可信通信的协议方法。Openconnect协议是基于TLS协议的SSLVPN隧道模式解决方案,其在TLS基础上,服务端与客户端间完成终端用户身份认证、客户端IP地址下发、路由下发、DNS下发等功能,使得客户端能访问服务端后端的子网。
Openconnect基于思科的Anyconnect发展起来,目前已发布V1.2 RFC草案。
抓包工具wireshark无法直接解析TLS报文里被加密封装的载荷。由于openconnect协议构建于TLS之上,因此wireshark也无法直接解析openconnect报文。
要使wireshark可解密出TLS报文,有如下两种方法:
- 记录TLS握手过程中的各种key,再组织成log文件,像浏览器组织那样。
- 在wireshark里导入服务器端私钥。
第一种方法需要对TLS协议有非常深的认识才能记录下握手过程中的信息。第二种方法则对小白友好,只需要往wireshark里导入服务器端私钥即可。但遗憾的,TLSv1.3的算法套件里不再支持数字信封方式交换密钥。
因此,在了解如何使用wireshark解析openconnect协议报文之前,我们先对TLS算法套件做一定的了解。
2. TLS算法套件解读
TLSv1.0与TLSv1.1已处于废弃状态,因此本文仅对TLSv1.2、TLSv1.3、国密SSL协议(TLCP)的算法套件进行讨论。
TLSv1.3不再支持数字信封,只支持DH(E)交换。
TLSv1.2不单支持RSA数字信封,还支持DH(E)交换。
国密SSL同样既支持数字信封又支持DH(E)交换,与TLSv1.2不同的是,国密的加密证书和私钥与签名证书和私钥是不混用的。
2.1. TLSv1.2算法
RFC 5246 附录B中给出了TLSv1.2 的算法套件,如下:
(图片摘自RFC 5246)
TLSv1.2的算法套件组织结构为:"TLS_"前缀 + 密钥交换方法 + "WITH" + 加密算法(含分组长度与分组模式) + 认证算法。
TLSv1.2的密钥交换方法支持数字信封,也支持DH(E)交换。
以 TLS_RSA_WITH_AES_256_CBC_SHA256 为例分析,采用RSA证书的数字信封方式做密钥交换并推导出会话密钥,采用AES_256_CBC加密算法加密业务数据,采用SHA256认证算法对业务数据做认证。
再以TLS_DHE_RSA_WITH_AES_256_CBC_SHA256为例分析,采用DHE算法做密钥交换并推导出会话密钥,密钥交换过程中采用RSA证书验签,采用AES_256_CBC加密算法加密业务数据,采用SHA256认证算法对业务数据做认证。
2.2. TLSv1.3算法
RFC 8446 附录B.4中给出了TLSv1.3 的算法套件,如下:
(图片摘自RFC 8446)
(图片摘自RFC 8446)
与TLSv1.2算法套件不同,TLSv1.3算法套件名里不再体现密钥交换类型(由“key_share”载荷界定,进一步可细分为DH交换与ECDHE交换)。值得一提的是,TLSv1.3不再支持数字信封密钥交换。
TLSv1.3算法名里也不再体现证书验签算法。
2.3. 国密SSL(TLCP)算法套件
我国国家标准《信息安全技术 传输层密码协议(TLCP)》GB/T 38636-2020里给出了国密SSL的算法套件,如下:
(图片摘自GB/T 38636-2020)
其中,实现 ECC 和 ECDHE 的算法为 SM2,实现IBC 和IBSDH 的算法为 SM9。
密钥交换方法中ECC、IBC、RSA均为数字信封方式,其余为DH交换的衍生算法。
3. openconnect协议
RFC 草案 draft-mavrogiannopoulos-openconnect-04 给出了openconnect的协议方法,如下:
(图片摘自RFC草案 draft-mavrogiannopoulos-openconnect-04)
其中,TLS会话是必备项,DTLS会话是可选项。本文仅对TLS会话进行分析。
构建于TLS之上的openconnect协议,总体分为三个阶段。
第一阶段为TLS协议握手阶段,客户端与服务器间进行TLS协议交换,建立TLS会话。
第二阶段为openconnect协议握手阶段,客户端与服务器间完成CSTP VPN会话的建立,即完成TLS隧道的包装,完成终端用户身份认证、客户端IP地址下发、路由下发、DNS下发等。openconnect协议握手阶段被TLS会话密钥加密。
第三阶段为SSLVPN业务承载阶段。
4. wireshark对openconnect协议抓包解读
若让openconnect客户端与服务器自由协商TLS会话,那么按照协议高优先命中原则,客户端与服务端间一定会建立起TLSv1.3的会话,这样的会话wireshark是无法直接解密开来的。
前文所述的两种wireshark解密出TLS报文方法中,第一种方法需要对TLS协议有非常深的认识,因此本文重点介绍第二种。
由于TLSv1.3不再支持数字信封方式交换密钥,无法使用小白友好的方式将openconnect报文用wireshark解析出来,因此,本文通过修改openconnect代码的方法,将TLS协议强制降低为TLSv1.2,再强制指定算法套件为RSA数字信封方式,之后在wireshark里导入服务端私钥,便可解密出openconnect协议交换细节来了。
4.1. openconnect改动
Openconnect客户端做的改动有如下两点:
1. 代码里,文件openssl.c 中增加如下语句,强制将TLSv1.3排除掉:
SSL_CTX_set_options(vpninfo->https_ctx, SSL_OP_NO_TLSv1_3);
2. 启动时,带参数--openssl-ciphers "RSA",将协商交换方法限定为RSA数字信封。
Openconnect服务器端不需要做任何改动。
4.2. wireshark解析TLS
4.2.1 识别TLS报文
选中一个报文,右键 进入 Decode AS 配置页面。
在Decode AS页面里增加如下一行,让wireshark能将目的端口为1194的报文识别为TLS协议。
4.2.2 加载RSA私钥
选中一个报文,右键进入首选项配置页面,找到TLS协议。
点“RSA keys list”行的“Edit...”按钮,增加一行私钥信息。
之后,wireshark便能自动刷出解密后的协议了。
4.3. Openconnect报文明细
4.3.1 config-auth init
4.3.2 config-auth auth-request(请求用户名)
4.3.3 config-auth auth-reply(应答用户名)
4.3.4 config-auth auth-request(请求用户密码)
4.3.5 config-auth auth-reply(应答用户密码)
4.3.6 config-auth complete
4.3.7 CONNECT
4.3.8 CONNECTED
服务端在CONNECTED报文中携带为客户端分配的IP地址、路由、DNS等信息。