- LICENSE: MIT © 2026 edgevoid - README: 三层架构/逐字段伪装对照/部署/验证/安全边界/看门狗自启 - 脱敏(filter-repo 全历史): 8.136.202.225→203.0.113.10, .zjipc.cn→.internal.example, 学校DNS→192.0.2.53 - hook.sh 更新为安全形态(FORWARD-only 绑 WAN, 去掉 OUTPUT 全挂断网形态) - router_deploy.sh: SSHPASS 改环境变量注入(明文密码清除) - watchdog.sh 纳入 deploy/(接口变量化) - 内部语境泛化(认证网关/学校DNS/寝室部署备注)
11 KiB
vpn-loopback-firewall(内网出口伪装系统)
内网多设备出口流量特征归一化系统:让网络侧检测设备看到的是一台 Windows 设备,而不是 NAT 后面一堆 Linux / Android / 路由器。
在需要账号认证、且检测共享接入的受限网络环境(校园网、酒店网、企业访客网)中,多设备通过一台网关 NAT 共享账号时,网关与接入设备的 TCP/IP 栈特征(TTL、TCP options、时间戳时钟)会暴露"NAT 后面有多个异构设备"。本系统把出口流量改写成单一 Windows 指纹,并对明文 HTTP 与 DNS 查询做加密通道套壳,使出口流量形态与"一台 Windows 设备直连"无法区分。
⚠️ 请合规使用:仅用于你有权接入的网络环境。绕过网络使用条款可能违反服务协议或当地法律,后果自负。
架构总览
┌─────────────────────────────────────────────┐
│ 检测设备(网络侧) │
│ 看到: 1 个 IP · 1 套 Windows SYN 指纹 │
│ 纯 HTTPS + 一条 8444 加密流(像普通网页) │
└─────────────────────────────────────────────┘
▲
HTTPS 直连 │ 8444 TLS(套壳通道)
(Windows 指纹) │ 内容加密, 无明文特征
┌───────────────────────────────┴───────────────┐
│ L1 伪装器(masquerader/) │
│ NFQUEUE 截 FORWARD SYN → 重写 Windows 布局 │
│ TTL 全协议统一; wscale 10→8; 剥 Timestamp │
└───────────────┬───────────────────────────────┘
│
┌───────────────▼───────────────────────────────┐
│ L2 分流器(channel/proxy_*) │
│ HTTPS → 直连(大头, 不动) │
│ HTTP 80 → 透明劫持 → 云通道(加密) │
│ DNS 53 → 按域分流: 内网域本地 / 公网域云递归 │
└───────────────┬───────────────────────────────┘
│ TLS 长连接(多路复用帧)
┌───────────────▼───────────────────────────────┐
│ L3 云端(channel/server.py) │
│ AUTH token 鉴权 → 解包: │
│ HTTP → 统一 Chrome UA 重新发起 HTTPS │
│ DNS → 上游递归(如 223.5.5.5) │
└───────────────────────────────────────────────┘
检测方视角的出口流量 = HTTPS 直连 + 一条到云服务器的加密连接,明文 HTTP 与 DNS 查询零暴露。
三层详解
L1 伪装器(masquerader/)
把 Linux/Android 的 SYN 布局改写为 Windows:
| 字段 | Linux/Android 原生 | 伪装后(Windows) |
|---|---|---|
| TTL | 64 | 128 |
| window scale | 10 | 8 |
| Timestamp option | 有(设备时钟!) | 剥除(协商级移除, 多设备时钟分离信号失效) |
| MSS / SACK | 1460 / 允许 | 同(一致) |
| checksum | — | 重算 |
rewrite.py— 纯函数核心:输入原始 IPv4 TCP SYN 字节,输出改写后的包;非 SYN/非 IPv4/畸形一律返回None(放行)worker.py— NFQUEUE worker,双后端:官方python3-netfilterqueue优先,无此包的环境(如 OpenWrt 官方源没有预编译包)自动回退 ctypes 直调 libnetfilter_queue;所有 lib 调用显式声明argtypes/restype(未声明时 64 位指针被 c_int 截断会段错误)- 实现铁律(断网事故复盘):改包后原包 ACCEPT,绝不 desync 重发;异常一律放行——宁可不伪装,不能断网
L2 分流器(channel/proxy_*.py)
proxy_http.py— 本地 HTTP 透明代理:iptables REDIRECT 进来的明文 80 请求,封装进云通道proxy_dns.py— DNS 分流代理:配置internal_suffixes(如.internal.example)走本地权威 DNS(内网记录只有本地有),其余公网域名走云通道递归client.py— 通道客户端:TLS 长连接 + 首帧 AUTH token + 断线重连,线程安全多路复用
L3 云端转发器(channel/server.py)
- TLS 监听 + AUTH token 校验(防公网滥用)
- HTTP 帧 → 以统一 Windows Chrome UA 重新发起 HTTPS 请求(明文变密文)
- DNS 帧 → 向公共递归 DNS(可配)查询
目录结构
├── masquerader/
│ ├── rewrite.py # SYN 改写纯函数核心(可单测)
│ ├── worker.py # NFQUEUE worker(official/ctypes 双后端)
│ └── config/… # 指纹配置(ttl/window/wscale/mss/…)
├── channel/
│ ├── proto.py # 帧协议 [type][req_id][len][payload]
│ ├── client.py # 通道客户端(L2)
│ ├── proxy_http.py # HTTP 透明代理(L2)
│ ├── proxy_dns.py # DNS 分流代理(L2)
│ └── server.py # 云端转发器(L3)
├── deploy/
│ ├── hook.sh # 防火墙规则(带 --queue-bypass, FORWARD-only)
│ ├── router_ctl.sh # OpenWrt 一键分层起停(all/l1/l2)
│ └── watchdog.sh # 看门狗(crond 自愈进程与规则)
├── scripts/
│ └── smoke_channel.py # 端到端冒烟(起真 server+client 自检)
├── tools/
│ └── analyze_capture.py # pcap 验收分析(伪装特征/明文泄漏)
└── config/
├── channel.json # 通道配置模板(占位, 部署必改)
└── masquerader.json # 伪装指纹配置
快速开始
依赖
Python 3.10+ 标准库(通道部分零第三方依赖)。伪装器 worker 需要:
# 方式 A:官方绑定(推荐, 需可编译环境)
pip install netfilterqueue
# 方式 B:ctypes 直调(OpenWrt 等无法 pip 编译的环境自动回退,
# 需要 libnetfilter_queue.so, OpenWrt 自带)
1. 云端(L3)
# 生成自签证书(生产建议换 CA 签发)
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout key.pem -out cert.pem -days 365
# 配置 config/channel.json 的 cloud_side 段(端口/token/证书路径)
python3 -m channel.server config/channel.json
2. 网关侧(L1 + L2)
# 指纹规则(NFQUEUE 截 FORWARD SYN)
iptables -t mangle -A FORWARD -o <wan_if> -p tcp --syn \
-j NFQUEUE --queue-num 100 --queue-bypass
# HTTP 明文劫持 + DNS 劫持(只劫 LAN 入站!)
iptables -t nat -A PREROUTING -i <lan_if> -p tcp --dport 80 \
-j REDIRECT --to-ports 8080
iptables -t nat -A PREROUTING -i <lan_if> -p udp --dport 53 \
-j REDIRECT --to-ports 8053
# 起进程
python3 -m masquerader.worker config/masquerader.json # L1
python3 -m channel.proxy_http config/channel.json # L2 HTTP
python3 -m channel.proxy_dns config/channel.json # L2 DNS
OpenWrt 提示:官方包全部被 sstrip 掉 ELF section headers,
pip无法链接netfilterqueue的 C 扩展。解法:ctypes 后端直接用运行时.so(dlopen 不需要 section headers);若必须用官方绑定,需用带 section 的完整版.so替换(从 Debian 源编译),且 musl 加载器不做传递依赖符号解析,启动需LD_PRELOAD=libnfnetlink.so.0。
OpenWrt 软路由部署(一键控制)
deploy/router_ctl.sh 提供分层起停,先撤规则再杀进程(杜绝断网窗口):
sh ctl.sh start # 起全套(L1+L2)
sh ctl.sh stop # 停全套(先撤规则 → bypass 放行 → 再杀进程)
sh ctl.sh start l2 # 只起套壳层
sh ctl.sh status # 查看进程与规则状态
看门狗(watchdog.sh,随 crond 每 3 分钟):进程不在拉起、规则缺失重挂,幂等且静默,异常写 /tmp/watchdog.log:
*/3 * * * * /opt/masquerader/watchdog.sh
开机自启(/etc/rc.local,延时等 WAN 起来):
(sleep 25 && sh /opt/masquerader/ctl.sh start >> /tmp/boot.log 2>&1) &
配置说明(config/channel.json)
| 字段 | 含义 |
|---|---|
cloud.host/port |
云服务器地址与端口(TLS) |
cloud.token |
通道鉴权 token,两端必须一致,部署前改掉占位值 |
http_proxy.listen_port |
本地 HTTP 劫持目标端口(对应 REDIRECT 8080) |
dns_proxy.listen_port |
本地 DNS 劫持目标端口(对应 REDIRECT 8053) |
dns_proxy.school_dns |
内网/权威 DNS(解析内网记录) |
dns_proxy.internal_suffixes |
内网域名后缀列表,匹配则本地解析不进通道 |
cloud_side.* |
云端配置段:监听端口、token、DNS 上游、转发 UA、TLS 证书 |
仓库内
config/channel.json为脱敏模板,IP/域名均为占位(RFC 5737 测试地址),真实部署值只在你的部署机上。
验证方法(验收口径)
# 1. WAN 侧抓 SYN: 应见 win=64240 wscale=8 无 Timestamp ttl=128
tcpdump -i <wan_if> -c 200 -w wan.pcap "tcp[tcpflags] & tcp-syn != 0"
python3 tools/analyze_capture.py wan.pcap
# 2. 明文泄漏检查: 出站 dport 80 与公网 53 应为 0
# (HTTP 全被套壳, DNS 全走通道/本地)
python3 tools/analyze_capture.py wan.pcap
# 3. 端到端冒烟(本机自测, 自签证书起真 server+client)
PYTHONPATH=. python3 scripts/smoke_channel.py
安全边界(血泪教训沉淀)
- NFQUEUE 必须带
--queue-bypass——worker 挂掉 = 不伪装,而不是断网 - 改包后原包 ACCEPT,绝无 zapret 式 desync 重发(重发包会与 AC 的乱序检测冲突)
- 劫持规则只挂 FORWARD/PREROUTING 入站,网关自身 OUTPUT 零规则——管理通道(ssh)永不碰劫持
- 按网卡/入接口收敛爆炸半径,不要全端口全链劫持;新规则先在隔离端口验证
- 先撤规则再杀进程(重启代理有 DNS 单点真空窗口 → 全机断解析的教训)
- 云端公网批量外连需注意厂商黑洞策略,
deny_suffixes可拉黑高风险目标
测试
python3 -m unittest discover -s tests -t . -v # 单元测试
PYTHONPATH=. python3 scripts/smoke_channel.py # 端到端冒烟
License
MIT © 2026 edgevoid