本手册适用于代理隧道实验:Windows 浏览器进入本地实验客户端, WSL 抓取到授权实验服务器固定端口的外层隧道流量。
普通网页/新闻/视频直连流量的当前流程已经迁移到 Windows 原生环境, 见普通网站采集。两套流程不要混用。
现有 VMess 数据采用以下基准部署,新协议默认沿用它,以保证采集口径可比:
| 位置 | 基准职责 |
|---|---|
| Win11 | 运行专用 Chrome,通过 127.0.0.1:10808 SOCKS 进入 WSL |
| WSL/Ubuntu | 运行代理客户端容器,并在 WSL 网卡抓取外层隧道 |
| Linux 实验服务器 | 运行代理服务端容器并提供实验出口 |
基准数据路径是:
Win11 Chrome -> WSL SOCKS/客户端内核 -> Linux 实验服务器端内核 -> 目标网站
^
└── WSL 抓“客户端内核 <-> Linux 服务器固定端口”
本手册的命令按这套基准拓扑标注:服务端配置和 lab server ... 在 Linux 服务器执行,
lab client ...、连通性 curl 和 lab capture run 在 WSL 执行,PowerShell Chrome
启动脚本在 Win11 执行。允许等价部署,但不能悄悄改变以下实验口径:
- PCAP 必须采到代理客户端与实验服务器固定端口之间的外层隧道,而不是浏览器到 SOCKS 的本地段。
- case、实际运行内核、外层 TCP/UDP 和 PCAP 标签必须一致。
- 如果采集点或网络命名空间变化,必须写入元数据,不能与旧 VMess 样本假装成完全相同条件。
- 已采集的 VMess 数据不会因为增加新 provider 或调整命令组织方式而失效;是否可用仍由其原始 PCAP、过滤范围、完整性和背景噪声决定。
协议矩阵中的 12 类均已启用。类别 1/2 和 5--10 由 Xray-core 执行,类别 3/4 由源码提交固定的 ShadowsocksR-native 执行,类别 11/12 由官方 Hysteria 2 内核执行。 本项目只生成上游内核的原生配置并管理容器,不自行实现 Shadowsocks、ShadowsocksR、VMess、VLESS、Trojan、Hysteria 2、QUIC、TLS 或 Salamander。
类别 11 是 Hysteria 2 + QUIC + TLS,类别 12 在同一组合上启用 Salamander。 首次正式采集前仍必须在实际 Linux/WSL 与服务器环境完成小规模连通性和 PCAP 纯度验证。
旧的按 1 GiB 采集结果保存在 /home/indole/formal_bak,不混入本轮正式数据。新数据写入 /home/indole/proxy-lab-data/formal。
本轮完全使用 Windows 专用 Chrome 手动访问,不使用自动 URL脚本、爬虫或循环 curl。
每个 PCAP 的目标是3000个完整起始的外层TCP会话:
- 新的 TCP SYN 增加一个流,SYN重传不会重复计数。
- 达到3000后进入
DRAINING,此时停止所有手动操作。 - 活动流没有全部结束时绝不关闭或切换 PCAP。
- 关闭专用 Chrome,让活动连接通过 FIN/RST自然结束。
- 活动流归零并持续空闲15秒后,封尾当前 PCAP,再创建下一份。
--finish-timeout在流模式中只重复告警,不会截断活动流。
类别 11/12 的 --target-flows 统计双向归一化后的外层 UDP 五元组。一个 Hysteria 2
QUIC 连接可以复用许多内层 TCP/UDP 流,因此这个数字不等于网页连接数或 QUIC stream
数量。正式采集 Hysteria 2 时优先使用 --target-gib 容量口径;只有实验设计明确要求
外层 UDP 会话数,并会在样本间重建客户端连接时,才使用 --target-flows。
采集器不设置单流大小上限、不因流大小告警,也不按流大小判定 PCAP 是否合格。流大小在后续离线处理 PCAP 时统计和筛选。
关闭标签页或浏览器是正常用户行为;达到目标流数后,抓包器仍会等待已存在的连接自然关闭,不会在 PCAP 中截断活动 TCP 流。
关闭 Windows VPN、TUN、系统代理、日常 Chrome/Edge 和所有后台下载。只保留当前实验客户端。
先在正式抓包前,于 WSL执行:
cd ~/proxy-traffic-lab
. .venv/bin/activate
lab client status
curl \
--fail \
--socks5-hostname 127.0.0.1:10808 \
--connect-timeout 10 \
--max-time 30 \
-o /dev/null \
-w 'HTTP status: %{http_code}\n' \
https://example.com/只有客户端 healthy=true 且 HTTP返回200才继续。检查完成后停止其他网络操作,再启动正式抓包。
Shadowsocks 是协议,Xray-core 是本矩阵选择的实现内核,因此配置仍由 lab xray
生成,不存在单独的 Shadowsocks 进程:
在基准拓扑中,以下命令在 Linux 实验服务器 执行:
lab xray init-secrets
lab xray render \
--case class-01-shadowsocks-2022-tcp \
--server-address YOUR_SERVER_IP \
--server-port 24443
lab xray validate
lab server start --case class-01-shadowsocks-2022-tcp类别 2 将 case 改为 class-02-shadowsocks-2022-udp,并确保服务器防火墙放行 UDP。
服务器生成 secrets/generated/client.json 后,将它同步到 WSL;然后在 WSL 执行:
lab client start --case class-01-shadowsocks-2022-tcp \
--config "$HOME/proxy-lab-client/client.json"
lab client status --case class-01-shadowsocks-2022-tcp类别 2 不能使用上述 HTTP curl 或浏览器网页访问充当正式业务负载,因为它们不能证明
内层 UDP 已通过 SOCKS5 UDP ASSOCIATE。先在你控制的另一台主机上启动 UDP echo 服务,
并只允许实验代理服务端出口 IP 访问;然后在 WSL 进行小规模试采:
lab experiment udp \
--case class-02-shadowsocks-2022-udp \
--server-ip YOUR_PROXY_SERVER_IP \
--server-port 24443 \
--target-host YOUR_AUTHORIZED_UDP_ECHO_HOST \
--target-port 19000 \
--count 20 \
--payload-bytes 256 \
--output-root "$HOME/proxy-lab-data"--server-ip/--server-port 是 WSL 抓取的 Shadowsocks 2022 外层 UDP 隧道;
--target-host/--target-port 是隧道内部访问的授权 echo 服务。两组参数职责不同。
命令不会默认访问公共 DNS、NTP 或其他第三方 UDP 服务。试采生成的元数据必须显示
inner_network=udp 且 successful > 0。正式大批量采集前,还应按实验设计确定包数、
负载大小和时间间隔,所有类别保持同一套可复现参数。
类别 6 的标签语义拆分为 xhttp_mode=stream-up 和 http_version=h2。这与当前
Xray 原生配置一致,只修正标签表达,不改变已经使用该原生配置采得的包行为。
两类都由官方 Xray-core 执行,不是项目自行实现 VLESS:
- 类别 7:
VLESS + RAW + REALITY + Vision。 - 类别 8:
VLESS Encryption + XHTTP(stream-up) + REALITY + Vision。
类别 8 已由旧的 VLESS + gRPC + TLS 更新为 Xray 当前的 XHTTP 组合,并使用
xray vlessenc 生成、持久化服务端 decryption 与客户端 encryption 参数。项目不显式
改写 xmux,使用 Xray 上游默认连接管理策略,避免为了凑外层连接数而制造不真实流量。
旧的 class-08-vless-grpc-tls PCAP 仍然只能按旧类别解释,不能重命名为新类别 8。
在 Linux 实验服务器 切换类别 8:
cd ~/dev/ProxyLab
. .venv/bin/activate
CASE=class-08-vless-xhttp-reality-vision
SERVER_IP=YOUR_SERVER_IP
lab server stop || true
lab xray render --case "$CASE" --server-address "$SERVER_IP" --server-port 24443
lab xray validate
lab server start --case "$CASE"
lab server status --case "$CASE"把新生成的 secrets/generated/client.json 同步到 WSL 后,在 WSL 重启客户端。
同步和重启步骤与其他 Xray 类别相同,但 --case 必须使用新 ID。启动前可用 jq
确认 protocol=vless、method=xhttp、security=reality、mode=stream-up,且
flow=xtls-rprx-vision。
XHTTP 会复用并轮换有限数量的外层连接,所以网页活动增长不等于外层 TCP 五元组同比
增长。需要固定外层字节量时用 --target-gib;需要研究外层连接行为时才用
--target-flows。不要通过修改 XMUX 参数强行让它产生 3000 个连接。
SSR 不属于 Xray 的 Shadowsocks 实现。本项目从固定的上游 Git commit 构建容器, 避免依赖来源不明的第三方 SSR 镜像。SSR 内核较旧,只能在隔离、授权的实验环境使用。
在基准拓扑中,以下命令在 Linux 实验服务器 执行:
lab shadowsocksr build-image
lab shadowsocksr init-secrets
lab shadowsocksr render \
--case class-03-ssr-auth-aes128-md5 \
--server-address YOUR_SERVER_IP \
--server-port 24443
lab shadowsocksr validate
lab server start --case class-03-ssr-auth-aes128-md5
lab server status --case class-03-ssr-auth-aes128-md5类别 4 将 case 改为 class-04-ssr-auth-aes128-sha1。只把
secrets/generated/shadowsocksr-client.json 同步到 WSL。不要复制服务器生成的
configs/locks/shadowsocksr-native.json:它记录的是该主机本地构建的镜像 ID。
然后在 WSL 执行一次本机镜像构建,并启动客户端:
lab shadowsocksr build-image
lab client start --case class-03-ssr-auth-aes128-md5 \
--config secrets/generated/shadowsocksr-client.json
lab client status --case class-03-ssr-auth-aes128-md5情况5和情况6共用端口24443,但同一时刻只运行一种配置。不要同时启动两个服务。
先在授权实验服务器终端执行(不是 WSL,也不需要从 WSL 反复 SSH):
cd /root/proxy-traffic-lab
. .venv/bin/activate
lab server stop
lab xray render \
--case class-06-vmess-xhttp-h2-tls \
--server-address YOUR_SERVER_IP \
--server-port 24443
lab xray validate
lab server start
lab server status然后只同步一次客户端配置。在 WSL 执行:
export VPS_IP=YOUR_SERVER_IP
scp root@"$VPS_IP":/root/proxy-traffic-lab/secrets/generated/client.json \
"$HOME/proxy-lab-client/client.json"
chmod 600 "$HOME/proxy-lab-client/client.json"
cd ~/proxy-traffic-lab
. .venv/bin/activate
lab client stop
lab client start --config "$HOME/proxy-lab-client/client.json"
lab client status
curl --fail --socks5-hostname 127.0.0.1:10808 \
--connect-timeout 10 --max-time 30 -o /dev/null \
-w 'HTTP status: %{http_code}\n' https://example.com/必须看到 healthy: true 和 HTTP status: 200。切回情况5时,在服务器重新执行同一组命令,只把 --case 改成 class-05-vmess-websocket-tls,再同步一次新生成的 client.json。
以下命令调用官方 Hysteria 2 容器,不包含自研协议实现。先在服务器项目目录锁定镜像、 生成短期实验凭据并渲染配置:
lab hysteria2 lock-image
lab hysteria2 init-secrets --server-name lab.invalid --validity-days 30
lab hysteria2 render \
--case class-11-hysteria2-quic-tls \
--server-address YOUR_SERVER_IP \
--server-port 24443
lab hysteria2 validate
lab server start --case class-11-hysteria2-quic-tls
lab server status --case class-11-hysteria2-quic-tls采类别 12 时,把上面所有 --case 改为
class-12-hysteria2-quic-salamander-tls。两类不能共用正在运行的服务端容器;切换前执行:
lab server stop --case class-11-hysteria2-quic-tls将以下文件通过受控通道同步到客户端对应项目路径,不要提交到 Git:
configs/locks/hysteria2.jsonsecrets/generated/hysteria2-client.yaml
客户端不需要服务端私钥。在基准拓扑的 WSL 客户端项目目录 中执行:
lab client start --case class-11-hysteria2-quic-tls \
--config secrets/generated/hysteria2-client.yaml
lab client status --case class-11-hysteria2-quic-tls
curl --fail --socks5-hostname 127.0.0.1:10808 \
--connect-timeout 10 --max-time 30 -o /dev/null \
-w 'HTTP status: %{http_code}\n' https://example.com/防火墙和云安全组必须允许实验端口的 UDP 入站。只有客户端状态健康、HTTP 返回成功, 且一份短试采 PCAP 中目标端口主要是预期服务器与客户端之间的 UDP,才开始正式采集。
生命周期命令可用 --case 按矩阵选择内核,也可直接用
--core xray-core|hysteria2|shadowsocksr-native。不传二者时读取 configs/lab.yaml 中的
runtime.default_core,默认仍是 xray-core。
Hysteria 2 推荐先按容量采集一份试样:
lab capture run \
--case class-11-hysteria2-quic-tls \
--server-ip YOUR_SERVER_IP \
--server-port 24443 \
--target-gib 0.1 \
--profile pilot-01在 WSL终端 A执行:
cd ~/proxy-traffic-lab
. .venv/bin/activate
export VPS_IP="YOUR_SERVER_IP"
sudo -v
CASE="class-05-vmess-websocket-tls" # 采情况6时改为 class-06-vmess-xhttp-h2-tls
lab capture run \
--case "$CASE" \
--server-ip "$VPS_IP" \
--server-port 24443 \
--target-flows 3000 \
--profile sample-01 \
--profile sample-02 \
--profile sample-03 \
--profile sample-04 \
--profile sample-05 \
--progress-interval 2 \
--idle-seconds 15 \
--idle-kib-per-second 32 \
--finish-timeout 300等待出现:
READY segment 1/5: sample-01
Target: 3000 outer TCP flows
在 Windows PowerShell执行:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File `
"\\wsl.localhost\Ubuntu\home\indole\proxy-traffic-lab\scripts\browser\chrome.ps1"启动器默认打开 about:blank,不会自动访问任何网站。不要在正式抓包期间添加 -CheckProxy。
手动输入你准备访问的真实网站,建议:
- 访问不同站点的首页、文章页、新闻页、论坛或文档页面。
- 正常滚动、点击站内链接、返回、前进和分页。
- 每个页面停留数秒到几十秒,不快速重复刷新。
- 分散访问多个站点,避免单一网站占据绝大多数流。
- 不登录私人账号,不提交密码、消息或敏感数据。
终端 A会持续显示:
[segment 1/5 CAPTURING ...] flows 1842 / 3000, active 9, completed 1833
接近目标时:
- 约2800流:减少新标签页,只完成当前页面。
- 约2950流:不要再打开新站点,使用当前站点少量正常跳转。
- 达到或超过3000流:立即停止操作并关闭整个专用 Chrome窗口。
随后终端 A进入:
[segment 1/5 DRAINING ...] flows 3004 / 3000, active 6, completed 2998
不要按 Ctrl+C。等待:
Segment 1/5 stopped: target_flows_reached_and_all_flows_closed
READY segment 2/5: sample-02
出现新的 READY 后,再次运行同一条 PowerShell启动命令,开始下一份手动会话。五份都按这个循环操作。
先对每个会话运行自动审计:
SESSION="$HOME/proxy-lab-data/formal/class-05-vmess-websocket-tls/sample-01/替换为会话目录"
lab dataset audit "$SESSION" --server-ip YOUR_PROXY_SERVER_IP短命令等价形式为:
lab ds a "$SESSION" -a YOUR_PROXY_SERVER_IP退出码为 0 才表示当前自动门禁通过。审计会检查 PCAP 可读性、文件大小与摘要、
manifest、case 对应的外层 TCP/UDP、服务器端口、意外数据包、流结束状态和内核丢包。
旧会话没有 manifest 或完整抓包日志时会产生 warning;关键元数据缺失、包不可读、
出现非目标隧道包或正式流边界不完整会失败。需要保留审计结果时使用
--output audit.json。
find "$HOME/proxy-lab-data/formal/class-05-vmess-websocket-tls" \
-name capture.json -print0 |
xargs -0 jq -r '[.profile, .capture.flow_count, .capture.completed_flow_count, .capture.active_flow_count, .capture.stop_reason] | @tsv'每份必须满足:
flow_count >= 3000completed_flow_count == flow_countactive_flow_count == 0stop_reason == target_flows_reached_and_all_flows_closed- tcpdump日志包含
0 packets dropped by kernel
独立复核流数:
PCAP="替换为 capture.pcap 完整路径"
tshark -r "$PCAP" -Y 'tcp.flags.syn == 1 && tcp.flags.ack == 0' \
-T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport -e tcp.seq_raw |
sort -u |
wc -l实时计数和 tshark复核只应有极小差异;差异明显时不要入库。