性能测试:流量回放工具-GoReplay!结合一款无需CA证书即可抓取HTTPS明文的工具,简直无敌。
GoReplay 是一个开源网络监控工具,可以将实时 HTTP 流量捕获并重放到测试环境。
应用成熟的过程中,测试所需的工作量往往会成倍增长。针对这个问题,GoReplay 为使用者提供了重用现有通信量进行测试的简单方法。它可以在不改动产品基础结构、且不影响现有流量的情况下,对这些流量进行分析和记录,从而增强使用者对代码部署、配置和基础结构进行更改的信心。
下载及安装
下载地址:https://github.com/buger/goreplay/releases
下载后将包放到需要录制的服务,同服务器下,并解压
参数介绍
--input-raw#用来捕捉http流量,需要指定ip地址和端口
--input-file#接收流量
--output-file#保存流量的文件
--input-tcp#将多个Goreplay实例获取的流量聚集到一个Goreplay实例
--output-stdout#终端输出
--output-tcp#将获取的流量转移至另外的Goreplay实例
--output-http#流量释放的对象server,需要指定IP地址和端口
--output-file#录制流量时指定的存储文件
--http-disallow-url#不允许正则匹配的URL
--http-allow-header#允许的Header头
--http-disallow-header#不允许的Header头
--http-allow-method#允许的请求方法,传入值为GET,POST,OPTIONS等
--input-file-loop#无限循环,而不是读完这个文件就停止了
--output-http-workers#并发请求数
--stats --out-http-stats#每5秒输出一次TPS数据(查看统计信息)
--split-outputtrue#按照轮训方式分割流量
--output-http-timeout30s #http超时30秒时间设置,默认是5秒
命令行使用
#捕捉流量,并通过终端输出,将监控8000端口上所有的流量,并通过终端stdout输出
sudo ./gor --input-raw:8000--output-stdout
#捕捉流量,并实时回放到另一台服务器的相同服务上,将8000端口的流量实时同步访问http://example:8001服务器,你在访问第一台服务器时,将看到流量以相同的顺序请求到第二台。
sudo ./gor --input-raw:8000--output-http="http://localhost:8001"
#将捕捉的流量存到文件中,并回放到其它服务器
#首先保存流量,将8000端口的流量,保存到requests.gor文件中(必须是.gor后缀,其它后缀回放时有问题)。
sudo ./gor --input-raw:8000--output-file= requests.gor
#然后回放保存的流量 将保存在request.gor中的请求,通过相同的时间顺序回放到服务器http://localhost:8001
sudo ./gor --input-file requests.gor --output-http= "http://localhost:8001"
GoReplay的限速和请求过滤
限速机制
#限制每秒的请求数
sudo ./gor --input-tcp :28020 --output-http "http://localhost:8001|10"# (每秒请求数限制10个以内)
sudo ./gor --input-raw :80 --output-tcp "http://localhost:8001|10%" # (每秒请求数限制10%以内)
#基于Header或URL的参数限制一些请求,为指定的Header或者URL的请求设定限制的百分比
sudo ./gor --input-raw :80 --output-tcp "http://localhost:8001|10%" --http-header-limiter "X-API-KEY: 10%"
sudo ./gor --input-raw :80 --output-tcp "http://localhost:8001|10%" --http-param-limiter "api_key: 10%"
请求过滤
#当需要捕捉指定路径的请求流量时,可以使用该机制,如只同步/api路径下的请求
sudo ./gor --input-raw :8080 --output-http staging.com --http-allow-url /api
Demo
#如果是性能测试,可以不考虑请求的顺序和速率,并且要求无限循环
# --input-file 从文件中获取请求数据,重放的时候 100x 倍速
# --input-file-loop 无限循环,而不是读完这个文件就停止
# --output-http 发送请求到 http://host2.com
# --output-http-workers 并发 100 发请求
# --stats --output-http-stats 每 5 秒输出一次 TPS 数据
./gor--input-file'request.gor|10000%'--input-file-loop--output-http'http://localhost:8001'--output-http-workers100--stats--output-http-stats
#抓取80端口的HTTP请求,只抓取URL是/api/v1的,并输出到终端
./gor --input-raw:80--http-allow-url'/api/v1'--output-stdout
#抓取80端口的所有请求,并保存到文件,实际会分批保存为request_0.gor,request_1.gor这种文件名
./gor --input-raw:80--output-file'request.gor'
#流量回放到多个站点(复制引流)
./gor --input-tcp:28020--output-http"http://localhost:8001"--output-http"http://localhost:8002"
#按照轮询方式分割流量(平分流量)
./gor --input-raw:80--output-http"http://localhost:8001"--output-http"http://localhost:8002"--split-outputtrue
#HTTP超时设置
./gor --input-tcp replay.local:80--output-http http://staging.com --output-http-timeout30s
#性能测试(表示放大2倍速度来回放)
./gor --input-file"requests.gor|200%"--output-http"http://localhost:8001"
#回放速率不超过10QPS(绝对值)
./gor --input-tcp:80--output-http"http://localhost:8001|10"
#回放不超过原流量的10%(百分比,这里是总流量的占比)
./gor --input-raw:80--output-tcp"http://localhost:8001|10%"
#禁止的URL正则(除/api之外的请求)
./gor --input-raw:8080--output-http"http://localhost:8001"--http-disallow-url/api
#基于方法(表示只允许GET,OPTIONS的请求)
./gor --input-raw:80--output-http"http://localhost:8001"--http-allow-method GET --http-allow-method OPTIONS
#基于请求头
./gor --input-raw:8080--output-http"http://localhost:8001"--http-allow-header api-version:^1\.0\d
./gor --input-raw:8080--output-http"http://localhost:8001"--http-disallow-header"User-Agent: Replayed by Gor"
#重写请求
./gor --input-raw:8080--output-http"http://localhost:8001"--http-rewrite-url/v1/user/([^\\/]+)/ping:/v2/user/$1/ping
#设置URL参数
./gor --input-raw:8080--output-http"http://localhost:8001"--http-set-param api_key=1
#设置HEADER
./gor --input-raw:80--output-http"http://localhost:8001"--http-header"User-Agent: Replayed by Gor"--http-header"Enable-Feature-X: true"
#导出到ES
./gor --input-raw:8000--output-http"http://localhost:8001"--output-http-elasticsearch localhost:9200/gor
#基于Header或URL参数值的一致限制
# Limit based on header value
./gor --input-raw:80--output-tcp"http://localhost:8001|10%"--http-header-limiter"X-API-KEY: 10%"
# Limit based on header value
./gor --input-raw:80--output-tcp"http://localhost:8001|10%"--http-param-limiter "api_key: 10%"
一款无需CA证书即可抓取HTTPS明文的工具,基于eBPF技术实现。
-
eCapture的特点
它是一款基于eBPF技术的HTTPS明文抓取工具,可用于MySQL数据库查询审计和bash命令捕获等场景,仅支持Linux和Android系统。
-
其他优秀的开源项目
如Reactive-Resume,这是一款简历生成器,支持多种配置和语言,可快速生成和分享简历;还有documenso,这是一个社区驱动的文档签署工具,旨在提供透明、高效的文档签署流程;以及Flowise,这是一个可视化UI定制LLM的工具,允许用户通过拖放操作设计机器学习工作流程。
eCapture(旁观者): 基于eBPF技术实现SSL/TLS加密的明文捕获,无需CA证书。
提醒:
支持Linux系统内核x86_64 4.18及以上版本,aarch64 5.5及以上版本;
需要ROOT权限;
不支持Windows、macOS系统;
介绍
eCapture的中文名字为旁观者 ,即「当局者迷,旁观者清 」,与其本身功能旁路、观察
契合,且发音与英文有相似之处。eCapture使用eBPF Uprobe
/Traffic Control
技术,实现各种用户空间/内核空间的数据捕获,无需改动原程序。
快速上手
下载
ELF可执行文件
提醒
支持 Linux/Android的x86_64/aarch64 CPU架构。
下载 release 的二进制包,可直接使用。
Docker容器镜像
提醒
仅支持Linux x86_64/aarch64。
shell
# 拉取镜像
docker pull gojue/ecapture:latest
# 运行
docker run --rm --privileged=true --net=host -v ${宿主机文件路径}:${容器内路径} gojue/ecapture ARGS
小试身手
捕获基于Openssl动态链接库加密的网络通讯。
shell
sudo ecapture tls
2024-09-15T11:50:28Z INF AppName="eCapture(旁观者)"
2024-09-15T11:50:28Z INF HomePage=https://ecapture.cc
2024-09-15T11:50:28Z INF Repository=https://github.com/gojue/ecapture
2024-09-15T11:50:28Z INF Author="CFC4N <cfc4ncs@gmail.com>"
2024-09-15T11:50:28Z INF Description="Capturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64."
2024-09-15T11:50:28Z INF Version=linux_arm64:0.8.6-20240915-d87ae48:5.15.0-113-generic
2024-09-15T11:50:28Z INF Listen=localhost:28256
2024-09-15T11:50:28Z INF eCapture running logs logger=
2024-09-15T11:50:28Z INF the file handler that receives the captured event eventCollector=
2024-09-15T11:50:28Z WRN ========== module starting. ==========
2024-09-15T11:50:28Z INF listen=localhost:28256
2024-09-15T11:50:28Z INF https server starting...You can update the configuration file via the HTTP interface.
2024-09-15T11:50:28Z INF Kernel Info=5.15.152 Pid=233458
2024-09-15T11:50:28Z INF BTF bytecode mode: CORE. btfMode=0
2024-09-15T11:50:28Z INF master key keylogger has been set. eBPFProgramType=Text keylogger=
2024-09-15T11:50:28Z INF module initialization. isReload=false moduleName=EBPFProbeOPENSSL
2024-09-15T11:50:28Z INF Module.Run()
2024-09-15T11:50:28Z WRN OpenSSL/BoringSSL version not found from shared library file, used default version OpenSSL Version=linux_default_3_0
2024-09-15T11:50:28Z INF Hook masterKey function ElfType=2 Functions=["SSL_get_wbio","SSL_in_before","SSL_do_handshake"] binrayPath=/usr/lib/aarch64-linux-gnu/libssl.so.3
2024-09-15T11:50:28Z INF target all process.
2024-09-15T11:50:28Z INF target all users.
2024-09-15T11:50:28Z INF setupManagers eBPFProgramType=Text
2024-09-15T11:50:28Z INF BPF bytecode file is matched. bpfFileName=user/bytecode/openssl_3_0_0_kern_core.o
2024-09-15T11:50:28Z INF perfEventReader created mapSize(MB)=4
2024-09-15T11:50:28Z INF perfEventReader created mapSize(MB)=4
2024-09-15T11:50:28Z INF module started successfully. isReload=false moduleName=EBPFProbeOPENSSL
2024-09-15T11:50:31Z ??? UUID:233479_233479_curl_5_1_39.156.66.10:443, Name:HTTPRequest, Type:1, Length:73
GET / HTTP/1.1
Host: baidu.com
Accept: */*
User-Agent: curl/7.81.0
2024-09-15T11:50:32Z ??? UUID:233479_233479_curl_5_0_39.156.66.10:443, Name:HTTPResponse, Type:3, Length:357
HTTP/1.1 302 Moved Temporarily
Content-Length: 161
Connection: keep-alive
Content-Type: text/html
Date: Sun, 15 Sep 2024 11:50:30 GMT
Location: http://www.baidu.com/
Server: bfe/1.0.8.18
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>bfe/1.0.8.18</center>
</body>
</html>
模块介绍
eCapture 有8个模块,分别支持openssl/gnutls/nspr/boringssl/gotls等类库的TLS/SSL加密类库的明文捕获、Bash、Mysql、PostGres软件审计。
- bash 捕获bash命令行的输入输出
- gnutls 捕获基于gnutls类库加密通讯的明文内容
- gotls 捕获使用Golang语言编写的,基于内置crypt类库实现TLS/HTTPS加密通讯的明文内容
- mysqld 捕获Mysqld的SQL查询,适用于数据库审计场景,支持Mysqld 5.6/5.7/8.0等
- nss 捕获基于nss类库加密通讯的明文内容
- postgres 支持postgres 10+的数据库审计,捕获查询语句
- tls 捕获基于Openssl/Boringssl的加密通讯的明文内容,支持Openssl 1.0.x/1.1.x/3.x以及更新版本,支持BoringSSL所有发行版本
你可以通过ecapture -h
来查看这些自命令列表。
openssl 模块
执行sudo ecapture -h
查看详细帮助文档。
eCapture默认查找/etc/ld.so.conf
文件,查找SO文件的加载目录,并查找openssl
等动态链接路位置。你也可以通过--libssl
参数指定动态链接库路径。
如果目标程序使用静态编译方式,则可以直接将--libssl
参数设定为该程序的路径。
openssl模块支持3种捕获模式
- pcap/pcapng模式,将捕获的明文数据以pcap-NG格式存储。
- keylog/key模式,保存TLS的握手密钥到文件中。
- text模式,直接捕获明文数据,输出到指定文件中,或者打印到命令行。
Pcap 模式
支持了TLS加密的基于TCP的http 1.0/1.1/2.0
应用层协议, 以及基于UDP的 http3 QUIC
应用层协议。
你可以通过-m pcap
或-m pcapng
参数来指定,需要配合--pcapfile
、-i
参数使用。其中--pcapfile
参数的默认值为ecapture_openssl.pcapng
。
shell
sudo ecapture tls -m pcap -i eth0 --pcapfile=ecapture.pcapng tcp port 443
2024-09-15T06:54:12Z INF AppName="eCapture(旁观者)"
2024-09-15T06:54:12Z INF HomePage=https://ecapture.cc
2024-09-15T06:54:12Z INF Repository=https://github.com/gojue/ecapture
2024-09-15T06:54:12Z INF Author="CFC4N <cfc4ncs@gmail.com>"
2024-09-15T06:54:12Z INF Description="Capturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64."
2024-09-15T06:54:12Z INF Version=linux_arm64:0.8.6-20240915-d87ae48:5.15.0-113-generic
2024-09-15T06:54:12Z INF Listen=localhost:28256
2024-09-15T06:54:12Z INF eCapture running logs logger=
2024-09-15T06:54:12Z INF the file handler that receives the captured event eventCollector=
2024-09-15T06:54:12Z WRN ========== module starting. ==========
2024-09-15T06:54:12Z INF Kernel Info=5.15.152 Pid=230440
2024-09-15T06:54:12Z INF BTF bytecode mode: CORE. btfMode=0
2024-09-15T06:54:12Z INF listen=localhost:28256
2024-09-15T06:54:12Z INF module initialization. isReload=false moduleName=EBPFProbeOPENSSL
2024-09-15T06:54:12Z INF Module.Run()
2024-09-15T06:54:12Z INF https server starting...You can update the configuration file via the HTTP interface.
2024-09-15T06:54:12Z WRN OpenSSL/BoringSSL version not found from shared library file, used default version OpenSSL Version=linux_default_3_0
2024-09-15T06:54:12Z INF HOOK type:Openssl elf ElfType=2 IFindex=2 IFname=ens160 PcapFilter= binrayPath=/usr/lib/aarch64-linux-gnu/libssl.so.3
2024-09-15T06:54:12Z INF Hook masterKey function Functions=["SSL_get_wbio","SSL_in_before","SSL_do_handshake"]
2024-09-15T06:54:12Z INF target all process.
2024-09-15T06:54:12Z INF target all users.
2024-09-15T06:54:12Z INF setupManagers eBPFProgramType=PcapNG
2024-09-15T06:54:12Z INF BPF bytecode file is matched. bpfFileName=user/bytecode/openssl_3_0_0_kern_core.o
2024-09-15T06:54:12Z INF packets saved into pcapng file. pcapng path=/home/ecapture/ecapture.pcapng
2024-09-15T06:54:12Z INF perfEventReader created mapSize(MB)=4
2024-09-15T06:54:12Z INF perfEventReader created mapSize(MB)=4
2024-09-15T06:54:12Z INF module started successfully. isReload=false moduleName=EBPFProbeOPENSSL
2024-09-15T06:54:14Z INF packets saved into pcapng file. count=4
2024-09-15T06:54:16Z INF non-TLSv1.3 cipher suite found CLientRandom=f08e8d784962d1693c042f9fe266345507ccfaba58b823904a357f30dbfa1e71 CipherId=0
2024-09-15T06:54:16Z INF non-TLSv1.3 cipher suite found CLientRandom=f08e8d784962d1693c042f9fe266345507ccfaba58b823904a357f30dbfa1e71 CipherId=0
2024-09-15T06:54:16Z INF packets saved into pcapng file. count=183
2024-09-15T06:54:16Z INF CLIENT_RANDOM save success CLientRandom=f08e8d784962d1693c042f9fe266345507ccfaba58b823904a357f30dbfa1e71 TlsVersion=TLS1_2_VERSION bytes=176
2024-09-15T06:54:18Z INF packets saved into pcapng file. count=65
^C2024-09-15T06:54:18Z INF module close.
2024-09-15T06:54:18Z INF packets saved into pcapng file. count=3
2024-09-15T06:54:18Z INF packets saved into pcapng file. count=255
2024-09-15T06:54:18Z INF Module closed,message recived from Context
2024-09-15T06:54:18Z INF iModule module close
2024-09-15T06:54:18Z INF bye bye.
将捕获的明文数据包保存为pcapng文件,再使用Wireshark
打开查看,之后就可以看到明文的网络包了。
keylog 模式
你可以通过-m keylog
或-m key
参数来指定,需要配合--keylogfile
参数使用,默认为ecapture_masterkey.log
。
捕获的openssl TLS的密钥Master Secret
信息,将保存到--keylogfile
中。你也可以同时开启tcpdump
抓包,再使用Wireshark
打开,设置Master Secret
路径,查看明文数据包。
shell
sudo ecapture tls -m keylog -keylogfile=openssl_keylog.log
也可以直接使用tshark
软件实时解密展示。
shell
tshark -o tls.keylog_file:ecapture_masterkey.log -Y http -T fields -e http.file_data -f "port 443" -i eth0
text 模式
sudo ecapture tls -m text
将会输出所有的明文数据包。(v0.7.0起,不再捕获SSLKEYLOG信息。)
gotls 模块
与openssl模块类似。
验证方法:
shell
cfc4n@vm-server:~$# uname -r
4.18.0-305.3.1.el8.x86_64
cfc4n@vm-server:~$# cat /boot/config-`uname -r` | grep CONFIG_DEBUG_INFO_BTF
CONFIG_DEBUG_INFO_BTF=y
启动eCapture
shell
sudo ecapture gotls --elfpath=/home/cfc4n/go_https_client --hex
启动该程序:
确保该程序会触发https请求。
shell
/home/cfc4n/go_https_client
更多帮助
shell
sudo ecapture gotls -h
其他模块
eCapture 还支持其他模块,如bash
、mysql
、nss
、postgres
等,你可以通过ecapture -h
查看详细帮助文档。