原创文章,如需转载,请注明来自:https://bigzuo.github.io/
关键词:tcpdump、tcpdump filter、TCP、weblogic t3
背景介绍
在我们的项目中,我们系统被很多外部系统依赖,我们会提供一些接口给外部系统调用。近期发现我们提供给外部系统的接口可能暴露了一些不该暴露的敏感信息给外部系统,造成了较大的安全隐患。所以我们接到了一个梳理所有对外提供的接口清单的任务。
针对 API 接口,我们主要提供的服务有两大类:HTTP 服务和基于 t3 协议的 EJB 服务,EJB 服务主要存在于内部有一些超过 10 年的老系统。HTTP 服务我们有对应成熟的链路监控,可以很容易梳理接口清单。但是因 EJB 服务在我们公司比较边缘,只存在于部分很老的系统,所有的安全监控、运维监控、网络监控、调用链等平台都未覆盖 EJB 服务,所以通用的请求梳理手段都无法满足需求。
在我们公司,提供了 EJB 服务的系统,同时也会提供 HTTP 服务,且两个服务的端口是同一个,所以无法从网络连接排查 EJB 服务。经过理论分析,如果从基础网络协议出发,只要能在网络应用层协议识别出 EJB 请求(EJB 服务底层使用 t3 协议,和 HTTP 一样,都是应用层协议),那就能找到请求方信息,进而梳理出EJB服务的请求链路。在没有更好方式的情况下,抱着死马当活马医的心态,我们进行了反复的测试和验证,最终验证该方案可行。
分析步骤
HTTP 协议请求分析
如下为一次典型的 HTTP 1.0 协议请求过程,蓝色部分为 TCP 协议层的三次握手。红色部分为 TCP 协议三次握手后应用发起的第一次 HTTP 请求,请求的协议为 HTTP,内容为 GET /f5monweb/f5check.jsp HTTP/1.0
本次完整的 HTTP 请求内容如下:
1 | GET /f5monweb/f5check.jsp HTTP/1.0 |
T3 协议请求分析
如下为一次典型的 t3 协议请求过程,同 HTTP 协议请求一样,在应用请求发起前,也要有同样的 TCP 协议层的三次握手,见如下蓝色部分。TCP 连接建立后,应用首次发的 t3 协议请求见如下红色部分。
如下为 t3 协议本身的交互过程。红色部分为客户端发起的请求,蓝色部分为服务端的响应。根据 t3 协议的规范,客户端首次的 t3 协议请求内容都以 t3 8.1.3
开始,其中 8.1.3
为客户端的 t3 协议版本号。使用不同版本的 weblogic 该出显示的会有不同。服务端的首次响应也都以 HELO:10.3.6.0.false
开始,其中10.3.6.0
为服务端支持的 t3 协议版本号。其实首次的请求与响应过程,也是客户端和服务端的协议协商过程。如下抓包结果展示,最后客户端和服务端使用的 t3 协议版本为 8.1.3
。
Tcpdump 抓包找出 t3 协议首次请求
因此 HTTP 协议和 t3 协议在应用层交互的差异性,我们可以通过 tcpdump 抓包,针对性过滤 t3 协议请求,即可以找到服务器上所有的 t3 协议请求。具体抓包命令如下:
1 | 抓包命令,输出网络包信息 |
命令格式解析如下:
tcpdump -nei any
:抓经过本服务器所有网卡的网络包,并输出数据链路层信息;-vv
: 详细输出抓到的报文信息;dst port 7001
: 过滤只抓请求到本服务器 7001 端口的网络报文;7001 为 weblogic 默认端口,实际以 weblogic 部署端口为准;(tcp[13]=24)
:过滤只抓PSH-ACK
的网络报文;tcp[32:2]=0x7433)
: 过滤 TCP 报文从 32 字节开始的后 2 个字节信息,且这 2 个字节内容为t3
;(tcp[34]=0x20)
: 过滤 TCP 报文的第 34 字节为空格字符。ASC 码里空格的值是 32,即 16 进制的0x20
;
命令作用说明:
以上命令的核心就是为了抓取客户端在 TCP 三次握手后,首次发起的 t3 协议请求,即上图中 wireshark 抓包显示的下面这部分信息,只要出现这种请求,就可以确定客户端的 IP,且一定用的是 t3 协议。
1 | t3 8.1.3 |
命令抓包结果展示如下,其中蓝色部分为网络报文的发送时间戳,红色部分为客户端 IP和端口,黄色部分为本服务器 IP。并且这种抓包方式只输出最关键信息,信息量很少,另外输出格式统一,可以通过脚本或日志云集中分析出调用方 IP,极大提高排查效率。
抓包原理分析
确定了 HTTP 协议和 t3 协议的交互差异后,下一步就是如何利用差异性找到 t3 协议的握手请求。根据 t3 协议的握手流程,客户端首次请求具有如下 3 个关键要素:
- 协议为 TCP
- TCP Flag 为 PSH-ACK
- TCP 报文数据段以
t3
(t3后面有空格)开始
我们只要能使用 tcpdump 强大的过滤功能按照上面 3 个条件进行过滤,就能过滤出 t3 的握手请求。但是如何写过滤条件,却比较麻烦,首先我们需要熟悉 TCP 报文的结构,并且能准确定位我们要过滤的信息在 TCP 报文中的具体位置。确定这两个信息之后,就能实现信息过滤。如下为具体实现思路:
- 协议为 TCP:这个比较好过滤,不再赘述;
- TCP Flag 为 PSH-ACK:根据如下 TCP 报文格式,TCP Flag 信息在报文的第 14 个字节,PSH-ACK 的值是 24,所以过滤规则为
(tcp[13]=24)
; - TCP 报文数据段以
t3
(t3后面有空格)开始:同样根据 TCP 报文格式,TCP 的 data 信息从报文的第 33 个字节开始,t3 占用两个字节,且 t3 的 ASC 码值的 16 进制是0x7433
,ASC 码里空格的值是 32,即 16 进制的0x20
,所以t3
(t3后面有空格)的过滤规则为(tcp[32:2]=0x7433) and (tcp[34]=0x20)
。这是分为两个规则来写,不能写成(tcp[32:3]=0x743320)
,因为截取的 data 字节数只能为 1、2 或 4(tcpdump: data size must be 1, 2, or 4
)。
TCP 报文格式:
1 | 0 1 2 3 |
Tcpdump 包头过滤规则:
1 | proto[x:y] : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(第一字节从0开始排) |
操作符:
1 | > : greater 大于 |
IP 报文格式:
1 | 0 1 2 3 |
Wireshark 显示 tcp
data 中 t3 位置和编码信息:
Weblogic t3 协议的心跳保持机制
T3 协议有长连接保持机制,实现机制是基于周期性的客户端和服务器端的点对点心跳保持。心跳间隔默认是 1 分钟,我们实际测试发现,通过 t3 的心跳机制,也能查找出所有的请求方 IP。只是心跳信息要比握手信息多很多,不方便持续抓包、批量分析,所以最终我们没有采用这种方案。
Determining Connection Availability
Any two Java programs with a valid T3 connection—such as two server instances, or a server instance and a Java client—use periodic point-to-point “heartbeats” to announce and determine continued availability. Each end point periodically issues a heartbeat to the peer, and similarly, determines that the peer is still available based on continued receipt of heartbeats from the peer.
- The frequency with which a server instance issues heartbeats is determined by the heartbeat interval, which by default is 60 seconds.
- The number of missed heartbeats from a peer that a server instance waits before deciding the peer is unavailable is determined by the heartbeat period, which by default, is 4. Hence, each server instance waits up to 240 seconds, or 4 minutes, with no messages—either heartbeats or other communication—from a peer before deciding that the peer is unreachable.
- Changing timeout defaults is not recommended.
抓包显示的 t3 协议的心跳信息:
1 | [root@CNSZ032442 ~]# tcpdump -i any -nn -A port 30001 | grep 'beat' |
结论概要
- HTTP 协议和 t3 协议均为以 TCP 协议为基础的应用层协议,TCP 三次握手期间,两者表现完全一致;
- TCP 三次握手后,HTTP 协议和 t3 协议各自的应用层请求完全不同;因此,基于各自应用层协议的差异,可以通过网络抓包找出所有的 t3 协议请求;
- 找到 t3 协议请求后,根据 t3 协议本身的格式,可以找出请求方 IP。经过对抓包命令优化,可以实现批量找出 t3 协议请求方 IP,无需人工二次分析,可以极大提高排查效率;
- 本次排查过程,使用了较为复杂的
tcpdump
命令过滤规则,并且需要对 tcp 协议有一定了解,所以整理成文档,以供后面参考。
参考文档
A tcpdump Tutorial with Examples — 50 Ways to Isolate Traffic