如何记录交互 socat TCP/TLS 会话?

max*_*zig 7 tcp tcpdump tls socat

Socat非常适合交互式测试基于行的人类可读协议,如 HTTP 或 IMAP。

例如:

$ socat -d -d READLINE,history=$HOME/s.hist openssl:host:port,crnl,cafile=some.ca
Run Code Online (Sandbox Code Playgroud)

为了更好地分析,我需要捕获这样一个交互式会话 - 即接收和发送的字节。

仅仅通过 eg 硬拷贝终端输出tux是不够的,因为客户端/服务器部分没有被标记,像 '\t' 这样的字符会丢失/静默转换。

使用tcpdump捕获仅对未加密的连接有帮助。

因此我的问题。

答案不一定是基于 socat。如果另一个工具更适合该用例,我想阅读它。

解决方案的奖励积分,其中

  • 时间戳也被记录
  • 可以选择交错记录(客户端/服务器端)或记录到单独的文件

小智 6

我非常喜欢用 tcpdump 来记录网络连接。您实际上可以将它用于您想要实现的目标。不要在您的 socat 连接中使用 READLINE 端点,而是让它侦听某个端口。

remote server with ssl
     ^
     |       (ssl-encrypted)
   socat
     |       (not ssl-encrypted)
     v
local port   <-- run tcpdump here
     ^
     |       
   socat
     |
     v
 your terminal
Run Code Online (Sandbox Code Playgroud)

然后使用第二个 socat 连接连接到第一个 socat 正在侦听的本地端口。这是未加密的。在这个端口上你可以运行 tcpdump。

$ # easiest to use a separate terminal window for each command
$ socat TCP-LISTEN:9000,reuseaddr openssl:host:port,cafile=some.ca
$ tcpdump -i lo -w /tmp/tcpdump.output port 9000
$ socat READLINE,history=$HOME/.socat.hist TCP:localhost:9000
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 5

这通常是 the-v-xoptions 的socat用途。

-v将数据转储到 stderr 并进行一些转换,例如 CR 字符变成\r这样,您可以看到它。

-x 进行十六进制转储(虽然不是很有用,因为没有时间戳或指示转储的流量流入的方向)。

结合-v-x组合,你会得到一种hd带有时间戳和方向的转储:

> 2014/03/08 08:46:23.370824  length=4 from=0 to=3
 61 64 73 0a                                      ads.
--
< 2014/03/08 08:46:23.398666  length=1371 from=0 to=1370
 48 54 54 50 2f 31 2e 30 20 34 30 30 20 42 61 64  HTTP/1.0 400 Bad
 20 52 65 71 75 65 73 74 0d 0a                     Request..
 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65  Content-Type: te
[...]
Run Code Online (Sandbox Code Playgroud)

如果你想把它转储到一个文件,你可以将 stderr 重定向到一个文件,并将调试输出重定向到 stdout:

socat -d -d -lf /dev/stdout -x -v 2> dump.txt \
   "READLINE,history=$HOME/s.hist" \
   openssl:host:port,crnl,cafile=some.ca
Run Code Online (Sandbox Code Playgroud)

您还可以text2pcap在经过一些后期处理后将其转换为带有(wireshark 附带的)的 pcap ,使用:

{
  socat -d -d -lf /dev/stdout -x -v 2>&1 >&3 3>&- \
    "READLINE,history=$HOME/s.hist" \
    openssl:host:port,crnl,cafile=some.ca |
    awk '/^[<>]/{a=0;print $1 == "<" ? "I" : "O", $2, $3; next}
         {$0 = substr($0, 1, 48);printf "%.4x %s\n",a,$0;a+=NF}' |
    text2pcap -l 147 -Dnqt '%Y/%m/%d %H:%M:%S.' - dump.pcap
} 3>&1
Run Code Online (Sandbox Code Playgroud)

那个pcap使用封装147。那不是链路层类型,但wireshark将其理解为用户封装。

然后,我们可以告诉wireshark数据包包含HTTP流量,例如:

wireshark -o 'uat:user_dlts:"User 0 (DLT=147)","http","0","","0",""' \
  -o 'gui.column.format:"No.","%m","Time","%Yt",
    "Direction","%Cus:frame.packet_flags_direction:0:R","Protocol","%p",
    "Length","%L","Information", "%i"' -r dump.pcap
Run Code Online (Sandbox Code Playgroud)

(这里也修改显示的列,以及,因为没有地址,但我们有业务方向(由提供text2pcap -D,我们已经转换后<>IO))。

您可以wireshark通过将text2pcap输出管道传输到wireshark调用 with-ki -而不是来查看实时流量-r dump.pcap,但随后wireshark仅支持旧pcap格式,pcap-ng这并不意味着我们必须删除-n选项text2pcap并且我们会丢失方向信息:

{
  socat -d -d -lf /dev/fd/3 -x -v 2>&1 >&3 3>&- \
    "READLINE,history=$HOME/s.hist" \
    openssl:host:port,crnl,cafile=some.ca |
    awk '/^[<>]/{a=0;print $1 == "<" ? "I" : "O", $2, $3; next}
         {$0 = substr($0, 1, 48);printf "%.4x %s\n",a,$0;a+=NF}' |
    text2pcap -l 147 -Dqt '%Y/%m/%d %H:%M:%S.' - - |
    wireshark -o 'uat:user_dlts:"User 0 (DLT=147)","http","0","","0",""' \
      -o 'gui.column.format:"No.","%m","Time","%Yt",
        "Direction","%Cus:frame.packet_flags_direction:0:R","Protocol","%p",
        "Length","%L","Information", "%i"' -ki -
} 3>&1
Run Code Online (Sandbox Code Playgroud)