maxlluky/VPN-Traffic-Obfuscation-Lab

GitHub: maxlluky/VPN-Traffic-Obfuscation-Lab

一个基于 Docker 的 VPN 流量检测与混淆测试平台,用于评估不同隧道技术在 IDS/IPS 中的可见性。

Stars: 0 | Forks: 0

# VPN 混淆实验室(学士项目) 一个可重现的基于 Docker 的测试平台,用于评估 VPN 流量(原始 WireGuard)和 VPN 混淆技术(UDP2RAW、OBFS4)的可检测性,使用 Suricata IDS、Zeek NSM 和 nDPI 深度包检测。 **Max Luckert** · Wrexham University · [mluckert@outlook.de](mailto:mluckert@outlook.de) ## 目录 1. [项目结构](#project-structure) 2. [快速开始](#quickstart) 3. [流量模式](#traffic-modes) 4. [场景](#scenarios) 5. [IDS 验证](#ids-validation) 6. [分析(Jupyter 笔记本)](#analysis-jupyter-notebook) 7. [架构](#architecture) 8. [清理](#cleanup) 9. [故障排除](#troubleshooting) 10. [许可证](#license) ## 项目结构 ### 组合文件(`compose/`) | 文件 | 用途 | |---|---| | `compose.yml` | 基础堆栈:目标、Suricata、Zeek、ndpi、网络 | | `compose.baseline.yml` | 场景 1:原始 WireGuard | | `compose.udp2raw.yml` | 场景 2:封装在 TCP/443 中的 WireGuard | | `compose.obfs4.yml` | 场景 3:通过 Shadowsocks-rust + obfs4proxy 的 WireGuard | | `compose.validate.yml` | IDS 正向控制(明文 HTTP,无 VPN) | ### 脚本(`scripts/`) ``` scripts/ ├── run_scenario.sh – Main experiment runner (all scenarios + traffic modes) ├── lib.sh – Shared functions (stack management, capture, artifact collection) ├── validate_ids.sh – IDS positive control ├── cleanup.sh – Tears down all containers, networks, volumes └── pcap_to_packet_csv.sh – Internal: extracts packet features via tshark ``` ### 服务(`services/`) ``` services/ │ │ ── Detection ────────────────────────────────────────────────────── ├── suricata/ – IDS (ET Open ~49 k rules + custom WG behavioral rules) ├── zeek/ – NSM (JSON conn.log output) ├── ndpi/ – DPI (nDPI 5.0, built from source) │ │ ── VPN & Proxies ─────────────────────────────────────────────────── ├── vpn-client/ – WireGuard client configurations │ ├── baseline/ – wg0.conf for Baseline │ ├── udp2raw/ – wg0.conf for UDP2RAW │ └── obfs4/ – wg0.conf for OBFS4 ├── vpn-gateway/ – WireGuard server configurations │ ├── baseline/ – Standard MTU config │ ├── udp2raw/ – Low MTU + sidecar entrypoint.sh │ └── obfs4/ – Low MTU config ├── proxy-obfs4/ – Shadowsocks-rust + obfs4proxy (SIP003 plugin via pt_adapter.py) ├── proxy-udp2raw/ – UDP2RAW proxy (fake-TCP/443 wrapping) │ │ ── Clients & Traffic ─────────────────────────────────────────────── ├── traffic-client/ – Traffic generator (Python HTTP + iperf3 streaming) ├── target-server/ – Nginx + iperf3 server (pre-installed in Dockerfile) │ └── html/ – Static assets for HTTP burst traffic └── http-client/ – IDS validation client (curl/bind-tools, no VPN) ``` ### 结果(`results/`) ``` results/runs/// ├── metadata.json – Scenario, mode, seed, tool versions ├── pcap/ – Raw packet capture (.pcap) ├── pcap_features/ – Tshark-extracted packets.csv ├── suricata/ – eve.json, fast.log ├── zeek/ – conn.log ├── ndpi/ – summary.txt, flows.csv └── iperf/ – iperf.json (streaming mode only) ``` ## 快速开始 ### 先决条件 - Linux 主机(已在 Ubuntu / Arch Linux 上测试) - Docker Engine ≥ 24.x + Docker Compose v2 - 内核 WireGuard 支持(`wireguard`、`udp_tunnel` 模块) - 主机上的 `tcpdump` 和 `tshark`: # Ubuntu/Debian sudo apt install tcpdump tshark # Arch Linux sudo pacman -S tcpdump wireshark-cli ### 安装 ``` # 1. 克隆 git clone https://github.com/maxlluky/VPN-Traffic-Obfuscation-Lab.git cd VPN-Traffic-Obfuscation-Lab # 2. 环境 cp compose/.env.example compose/.env # 如需编辑 compose/.env(UDP2RAW_IMAGE,BRIDGE_IF) # 3. 验证检测堆栈 bash scripts/validate_ids.sh # 4. 运行首次实验 bash scripts/run_scenario.sh baseline ``` ## 流量模式 | 模式 | 描述 | 用途 | |---|---|---| | **burst**(默认) | 50 个顺序 HTTP 请求 | 连接性检查,快速告警生成 | | **streaming** | 持续 60 秒的 iperf3 TCP 流 | 吞吐量统计,流量分析(Zeek) | ``` bash scripts/run_scenario.sh baseline # burst (default) bash scripts/run_scenario.sh baseline streaming # streaming # 完整实验集 — 每个场景 1× 突发 + 2× 流式传输(总计 9 次运行) # 每个场景的两次流式传输运行提供平均 ± 95% 置信区间的吞吐量统计(t 分布)。 for scenario in baseline udp2raw obfs4; do bash scripts/run_scenario.sh "$scenario" burst bash scripts/run_scenario.sh "$scenario" streaming bash scripts/run_scenario.sh "$scenario" streaming done ``` ## 场景 ### 场景 1:基线 — 明文 WireGuard ``` bash scripts/run_scenario.sh baseline ``` 明文 WireGuard 隧道,UDP/51820。无混淆。作为检测参考:ndpi 识别 WireGuard,且自定义 Suricata 规则(SID 9000001/9000002)在 WireGuard 握手时触发。 ### 场景 2:UDP2RAW — WireGuard 封装在 TCP/443 ``` bash scripts/run_scenario.sh udp2raw ``` WireGuard UDP 被封装为伪 TCP 并通过端口 443 隧道传输。ndpi 将其归类为 TLS(基于端口匹配),但找不到 TLS Client Hello — 这是明显的 FakeTCP 指示。 ### 场景 3:OBFS4 — Shadowsocks + obfs4proxy ``` bash scripts/run_scenario.sh obfs4 ``` WireGuard 通过 Shadowsocks-rust(ChaCha20-Poly1305)加密,并经由 obfs4proxy 作为 SIP003 插件(`pt_adapter.py`)进行混淆。线上的流量为 **UDP**,端口 12345,载荷随机。ndpi 将其归类为 Unknown — 混淆有效。 ## IDS 验证 在得出结论前,请运行正向控制以确认检测堆栈功能正常: ``` bash scripts/validate_ids.sh ``` 发送明文 HTTP(无 VPN),并期望 Suricata ET 告警、Zeek 的 `service=http` 以及 nDPI HTTP 分类。**VPN 场景中无告警是真实发现,而非配置错误。** ## 分析(Jupyter 笔记本) ### 安装 ``` python3 -m venv .venv source .venv/bin/activate pip install -r analysis/requirements.txt ``` 在 VS Code 或 JupyterLab 中打开 `analysis/Analysis_Starter.ipynb`(选择 `.venv` 内核)。 ### 笔记本涵盖内容 1. **IDS 可见性(Suricata 与 Zeek)** — 每个运行的告警计数;ET 开源规则与自定义 WireGuard 规则命中情况(SID 9000001/9000002);Zeek 协议检测流程 2. **深度包检测(nDPI)** — 协议指纹识别结果及各场景分类 3. **流量指纹识别** — 分组大小与到达间隔分布;TCP 与 UDP 分解 4. **协议合理性检查** — TCP/443 流中 TLS Client Hello 的存在(UDP2RAW FakeTCP 指示) 5. **性能** — 各场景吞吐量的均值 ± 95% 置信区间(t 分布,`t.ppf(0.975, df=n−1)`) 6. **香农熵** — 原始 PCAP 载荷的随机性;越高表示混淆越有效 7. **描述性统计与 KS 检验** — 分组大小与到达间隔的描述统计;成对 Kolmogorov-Smirnov 检验 8. **汇总表** — 场景 × 指标矩阵,用于论文评估章节 ### 自定义 WireGuard 检测规则 `services/suricata/rules/local.rules` 包含两个随 ET Open 加载的行为规则: - **SID 9000001** — 握手发起者:UDP,148 字节载荷,前 4 字节为 `01 00 00 00` - **SID 9000002** — 握手响应:UDP,92 字节载荷,前 4 字节为 `02 00 00 00` 这些规则基于 **数据包结构** 检测 WireGuard,而非端口号。仅基线场景会触发它们。 ## 架构 ### 网络 | 网络 | 子网 | 用途 | |---|---|---| | `client_net` | 192.168.10.0/24 | VPN 客户端侧 — 所有检测工具的捕获点 | | `external_net` | 172.30.30.0/24 | 目标服务器侧 | | `internal_net` | 192.168.20.0/24 | 代理到网关链路(仅 UDP2RAW 与 OBFS4 使用) | ### 流量流程:基线 ``` traffic-client (192.168.10.10) ↓ HTTP requests wg-client [WireGuard tunnel established] ↓ WireGuard encrypted UDP/51820 [client_net bridge] ← Suricata / Zeek / nDPI capture ↓ WireGuard encrypted UDP/51820 vpn-gateway (192.168.10.2 ↔ 172.30.30.2) [decrypts] ↓ plain HTTP target-server (172.30.30.10) ``` ### 流量流程:UDP2RAW ``` traffic-client (192.168.10.10) ↓ HTTP requests wg-client [WireGuard → 127.0.0.1:51820] ↓ WireGuard UDP/51820 (loopback) proxy-udp2raw client [wraps UDP → fake TCP/443] ↓ fake TCP/443 [client_net bridge] ← Suricata / Zeek / nDPI capture ↓ fake TCP/443 proxy-udp2raw gateway [unwraps TCP → UDP/51820] ↓ WireGuard UDP/51820 vpn-gateway [decrypts] ↓ plain HTTP target-server (172.30.30.10) ``` ### 流量流程:OBFS4 ``` traffic-client (192.168.10.10) ↓ HTTP requests wg-client [WireGuard → 127.0.0.1:51820] ↓ WireGuard UDP/51820 (loopback) proxy-obfs4 client [sslocal -U + obfs4proxy via SIP003] ↓ Shadowsocks ChaCha20 + obfs4 randomisation, UDP/12345 [client_net bridge] ← Suricata / Zeek / nDPI capture ↓ obfuscated UDP/12345 proxy-obfs4 gateway [ssserver + obfs4proxy] ↓ WireGuard UDP/51820 vpn-gateway [decrypts] ↓ plain HTTP target-server (172.30.30.10) ``` ## 清理 ``` bash scripts/cleanup.sh # stop all containers, remove networks & volumes bash scripts/cleanup.sh --all # also remove built images sudo rm -rf results/* # delete all experiment results (optional) ``` ## 故障排除 **桥接接口未找到** ``` BRIDGE_IF=br-a1b2c3d4e5f6 bash scripts/run_scenario.sh baseline ``` **Suricata 未启动** ``` docker logs suricata-ids # check BRIDGE_IF is set correctly in .env ``` **UDP2RAW 连接失败** ``` docker logs proxy-udp2raw # verify UDP2RAW_GATEWAY_PORT=443 in .env ``` **OBFS4 连接失败** ``` docker logs obfs4-gateway docker logs obfs4-client # check pt_adapter.py started and certs match ``` ## 许可证 © 2026 Max Luckert。本项目根据 [GNU General Public License v3.0](LICENSE) 授权。 你可以自由使用、学习、修改和分发本项目,衍生作品也必须在 GPL-3.0 下发布。
标签:Docker, Metaprompt, nDPI, NSM, obfs4, PCAP, Rootkit, Suricata, UDP2RAW, VPN, VPN混淆, Windows内核驱动, WireGuard, Zeek, 可重现, 学士论文, 安全防御评估, 流量检测, 流量混淆检测, 测试床, 深度包检测, 深度学习, 现代安全运营, 系统分析, 网络分析, 网络安全, 网络安全分析, 网络流量, 请求拦截, 逆向工具, 隐私保护