ParsaKSH/spoof-tunnel
GitHub: ParsaKSH/spoof-tunnel
一個基於 IP 模擬的雙向隧道工具,解決傳統狀態防火牆對源地址與連線狀態的過度信任問題。
Stars: 324 | Forks: 100
# Spoof 隧道
[波斯语-فارسی](README-fa.md)
Spoof Tunnel 是一个三层/四层隧道代理,旨在通过**双向相互 IP 欺骗**来绕过深度包检测 (DPI) 和严格的有状态防火墙。
与在固定客户端 IP 和固定服务器 IP 之间建立有状态连接的传统隧道协议不同,Spoof Tunnel 通过在两端伪造 IP 头部中的 `Source IP` 字段,将逻辑会话与物理网络地址完全解耦。
### 项目诞生的背景:Spoof Tunnel 的起源
双向欺骗隧道的概念,是为了应对 2026 年 1 月 8 日至 9 日(波斯历 1404 年 18-19 日)发生流血起义后伊朗严重的互联网封锁而提出的。在与全球互联网完全断开期间,我们的首要目标是逆向工程推断出所施加限制的确切范围和网络层级。
在调查伊朗 IP 前缀的 BGP 路由时,我们观察到一个令人惊讶的细节:与阿富汗互联网断网时 BGP 路由直接消失不同,伊朗的 IP 范围仍在全球范围内被积极广播。这有力地表明国际物理基础设施仍然完好无损。
随后情况变得明朗,某些隶属于政府的伊朗实体能够将其特定的 IP 地址加入白名单,成功恢复了它们的国际连接。这一观察引出了这样一种假设:限制是在三层强制执行的,特别是基于 srcIP 和 dstIP 的过滤。
当我们发现极少数特定的外国 IP 地址(例如 Hetzner 的特定 IP 段)仍然可以建立到伊朗的入站连接时,这一假设得到了明确的证实。证据清楚地表明,“封锁”并不是物理切断,而是一项严格的、基于白名单的三层防火墙策略。
在这种严格受限的环境中,欺骗隧道的想法诞生了。通过篡改 IP 头部,我们可以模拟白名单流量。然而,正如 IP 欺骗固有的特性一样,如果将一个伪造的数据包发送到服务器,服务器本质上会将其回复路由回那个伪造的 IP 地址,而不是真实的源主机。
因此,标准的单向欺骗是不够的。我们需要一种健壮的双向相互欺骗机制,即客户端和服务器都伪造它们的 IP 头部,并且是预先确定的、完全知晓彼此实际物理 IP 的实例,从而使它们能够在这种非对称的、伪造路由的情况下依然建立并维持逻辑连接。
## 快速安装 (隧道核心 + GUI 面板):
```
bash <(curl -Ls https://raw.githubusercontent.com/ParsaKSH/spoof-tunnel/main/panel/install.sh)
```
## 1. 核心架构:相互 IP 欺骗
### 1.1 非对称数据流
在典型场景中,客户端和服务器会商定特定的 IP 地址进行欺骗:
* **客户端 → 服务器 (上传):** 客户端传输带有伪造源 IP(例如 `Client_Spoof_IP`)的数据包,发往服务器实际监听的 IP。
* **服务器 → 客户端 (下载):** 服务器作为响应,传输带有伪造源 IP(例如 `Server_Spoof_IP`)的数据包,发往客户端的实际 IP。
这就造成了一种情况:中间防火墙看到的单向流在逻辑上与任何活动的状态映射都不匹配,从而有效绕过了连接跟踪表和流量指纹识别。
### 1.2 Raw Socket 实现
为了注入被随意修改的三层数据包头部,Spoof Tunnel 使用了 Raw Socket(`AF_INET`, `SOCK_RAW`)。它手动构建整个 IPv4/IPv6 头部,并在软件中计算相应的 IP 校验和。
* 大量使用 `gopacket` 和 `pcap` 来绕过主机内核的网络栈。
* **BPF 过滤器:** 为了防止主机操作系统丢弃入站的伪造数据包或响应 `ICMP Destination Unreachable` / `TCP RST`,一个激进的伯克利数据包过滤器 (BPF) 将捕获范围严格限制在隧道预期的数据流上,绕过了本地路由限制。
## 2. 支持的传输协议
### 2.1 ICMP (Echo 模式)
隧道将加密的数据块封装在标准的 `ICMP Echo Request (Type 8)` 和 `ICMP Echo Reply (Type 0)` 数据包内。对于网络中间件来说,这些流量看起来就像无害的 ping 扫描或监控流量。
### 2.2 ICMPv6 模式
除了 ICMP,还支持 ICMPv6。由于完全封锁 IPv6 基础设施的防火墙往往对 ICMPv6 协议本身的限制较少,您可以通过 IPv4 上的 ICMPv6 协议号来携带您的 payload。
### 2.3 UDP 模式
使用标准的 UDP 数据报,并带有可动态切换的源端口。该协议模仿无连接的 DNS 或自定义的 UDP 应用模式。
### 2.4 TCP (SYN 标志) 模式
除了其他三种协议外,还支持纯 TCP。在严厉的审查事件中,伊朗防火墙往往首先封锁 UDP 和大多数其他协议——而 TCP 通常是最后一个被完全关闭的协议。
## 支持与捐赠
如果您觉得这个项目有用,并希望支持它的持续开发,您可以使用下面的链接进行加密货币捐赠:
在 2026 年 1 月 8 日至 9 日(波斯历 18 日至 19 日)流血起义后伊朗互联网完全中断期间开发并测试。
📌 v1.0.3 功能特性 (已废弃)
## 3. 可靠性层 由于 ICMP 和 UDP 不提供交付保证,Spoof Tunnel 在用户空间实现了一个类似 TCP 的自定义可靠性层。这对于维持稳定的 TLS 握手和按序流交付是必不可少的。 * **数据包排序与 ACK:** 每个 payload 数据包都被包装在一个包含单调递增序列号(4 字节)的 `SeqDataPacket` 格式中。接收方通过 `AckPacket` 进行数据确认,利用 64 位的确认位图来高效处理数据块。 * **流控与缓冲区:** `RecvBuffer` 维护着一个内部序列映射。乱序到达的数据包会被缓冲,并严格*按序*交付给目标 socket。 * **重传引擎:** 一个活跃的后台 goroutine 每 100ms 扫描一次 `SendBuffer`。超过 `retransmit_timeout` 的未确认数据包会使用指数退避算法进行重传,直到达到定义的 `max_retries` 限制。 ## 4. 会话多路复用 建立一个新的隧道会话会带来显著的延迟。为了缓解这一问题,Spoof Tunnel 实现了一个内部多路复用器。 在不可靠的链路上建立单个“主会话”。所有传入的本地 TCP SOCKS5 连接都会被分配一个虚拟的 4 字节 `StreamID`,并在这个单一的主会话内进行多路复用。 * `0x01 MuxStreamOpen:` 后跟 [StreamID:4][TargetLen:2][目标字符串] * `0x02 MuxStreamData:` 后跟 [StreamID:4][原始 Payload] * `0x03 MuxStreamClose:` 后跟 [StreamID:4] * `0x04 MuxStreamAck:` 服务器确认成功创建代理流。 ## 5. 密码学 安全性和混淆是通过 **ChaCha20-Poly1305 AEAD** 强制执行的。AEAD 确保了 IP payload 或隧道头部结构中没有任何一个字节是可见的或可被活跃的中间人 (MITM) 攻击者修改的,否则将立即断开连接。 每个会话都会初始化一个随机 nonce 机制以防止重放攻击,而静态预共享的 Base64 密钥则作为主密码学密钥。📌 v3+ 功能特性
## 6. 非对称传输协议 每个客户端或服务器都可以独立地为每个方向选择不同的传输协议。例如,客户端通过 TCP 发送数据,而服务器通过 ICMPv6 进行响应。请根据您特定服务器的审查限制进行选择。 ## 7. 简单的 UDP-Pipe 从 v2 开始,为了提高性能并减少处理开销,核心被重构为一个简单的 UDP 管道。它监听一个 UDP 端口;您将任何 UDP 流量发送到该端口,核心就会将数据包通过隧道传输到服务器,并在服务器端将其转发到您配置的任何 endpoint。 因此,诸如 FEC、ChaCha20 加密、SOCKS、ACK/类 TCP 系统等功能已从核心中移除。 推荐的方法是使用 WireGuard 创建本地的 IPv4/IPv6 隧道。 您可以参考这个 WireGuard 本地 IPv6 设置脚本: `https://github.com/ParsaKSH/TAQ-BOSTAN/blob/main/wireguard.sh` 在客户端,将 `/etc/wireguard/TAQBOSTANwg.conf` 中的 `endpoint` 设置为 `127.0.0.1` 以及客户端核心正在监听的端口。建议 MTU 设置为 1280。 ## 8. Spoof IP 列表支持 从 v3 开始,您可以提供一个 IP 列表,而不是单一的欺骗 IP。核心将以轮询 的方式循环遍历它们,为每个发出的数据包使用列表中的一个新 IP。 增加此功能的原因是:基础架构防火墙可能会对白名单 IP 强制执行带宽或流量限制。使用单个 IP 意味着其限制将直接降低您的隧道质量。 要了解如何找到有效的欺骗 IP,请参阅下面的 Spoof 测试工具部分。 ## 9. 底层模块使用 Rust 重写 从 v2 开始,负责数据包级处理和 IP 头部操作的核心高负载部分已使用 Rust 重写,以实现最低的 CPU 开销和最大的性能。 ## 10. 内置 Spoof 数据包测试工具 & IP 发现工具 ### 10.1 支持的传输协议:ICMP & TCP 测试模块目前支持两种协议——TCP 和 ICMP——您可以根据需要进行选择。 ### 10.2 IP 范围输入支持 您可以提供单个 IP 或 IP 范围,以测试哪些可以用于欺骗。该模块会展开范围,并分别从每个 IP 发送伪造的数据包。 接收端等待数据包,并记录任何成功到达的数据包。 **支持的输入格式:** - 单个 IP → `192.168.1.1` - IP 范围 → `192.168.1.1-192.168.1.255` - CIDR 范围 → `192.168.1.0/24` ### 10.3 可配置的丢包阈值 您可以指定每一端每个欺骗 IP 可接受的最大丢包率百分比。 ### 10.4 发送方与接收方模式 此模块需要两台服务器(节点)——一台充当**发送方**,另一台充当**接收方**。 **使用方法:** 1. 将客户端(伊朗服务器)设置为**发送方**模式。配置:协议、IP 范围文件、目标 IP(外部服务器)、每个 IP 的尝试次数、允许的最大丢包率以及超时时间。 2. 将服务器(外部服务器)设置为**接收方**模式,配置使用相同的设置。 3. 首先启动**接收方**,然后立即启动**发送方**。 4. 超时后,接收方将获得一份伪造数据包已到达的 IP 列表,以及每个 IP 的丢包率。 5. **反向**重复该过程——客户端变为接收方,服务器变为发送方。 6. 如果两台服务器都支持欺骗,您将获得每个方向有效的欺骗 IP 列表。📌 Web GUI 面板
从 v2 开始,为了易于使用,包含了一个 Web 管理面板。使用安装脚本进行安装: `https://github.com/ParsaKSH/spoof-tunnel/blob/main/panel/install.sh` 在位于伊朗的服务器上,您可能需要手动运行脚本步骤。 所有核心功能——包括隧道实例和测试工具模块——都可以通过该面板完全访问。
📌 v1.0.3 (已废弃) — 使用指南
## 使用说明 ### 1. 编译二进制文件 Spoof Tunnel 是使用 Go 语言编写的。您可以使用标准的 Go 工具链来构建它: ``` CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o spoof ./cmd/spoof/ ``` ### 2. 生成加密密钥 在启动隧道之前,请为服务器和客户端生成一对 Base64 格式的私钥/公钥。 ``` ./spoof keygen ``` *请记下私钥和公钥。* 服务器的公钥必须放置在客户端的 `peer_public_key` 字段中,反之亦然。 ### 3. 运行服务 **在服务器上:** ``` sudo ./spoof -c server-config.json ``` **在客户端上:** ``` sudo ./spoof -c client-config.json ``` 一旦连接成功,客户端将会在 `127.0.0.1:1080`(默认)上开启一个 SOCKS5 代理,通过欺骗隧道路由所有流量。 ## 客户端配置 (v1) | 部分 | 键 | 类型 | 描述 | |---|---|---|---| | mode | mode | string | 必须为 "client" | | transport | type | string | "udp" 或 "icmp" | | transport | icmp_mode | string | "echo" 或 "reply" (仅限 ICMP) | | transport | protocol_number | int | 0 (默认,用于 ICMP/UDP 时未使用) | | listen | address | string | SOCKS5 监听地址 (例如 127.0.0.1) | | listen | port | int | SOCKS5 监听端口 (例如 1080) | | server | address | string | 远程服务器实际 IP | | server | port | int | 远程服务器端口 (用于 UDP) | | spoof | source_ip | string | 此客户端在发送出站包时声称的 IP | | spoof | peer_spoof_ip | string | 预期的入站服务器数据包的伪造源 IP | | crypto | private_key | string | 客户端的 Base64 私钥 | | crypto | peer_public_key | string | 服务器的 Base64 公钥 | | performance | buffer_size | int | 主要数据包缓冲区大小 | | performance | mtu | int | 封装前的最大 payload (例如 1400) | | performance | session_timeout | int | 主会话超时时间 (秒) | | performance | workers | int | 处理数据包的 goroutine 数量 | | performance | read_buffer | int | 内核 socket 读取缓冲区大小 | | performance | write_buffer | int | 内核 socket 写入缓冲区大小 | | fec | enabled | bool | 启用 Reed-Solomon 前向纠错 | | fec | data_shards | int | 数据分片数量 | | fec | parity_shards | int | 校验分片数量 | | logging | level | string | "info", "debug", "warn", 或 "error" | | logging | file | string | 日志文件路径 (空 = stdout) | ## 服务器配置 (v1) | 部分 | 键 | 类型 | 描述 | |---|---|---|---| | mode | mode | string | 必须为 "server" | | transport | type | string | "udp" 或 "icmp" | | transport | icmp_mode | string | "echo" 或 "reply" (仅限 ICMP) | | transport | protocol_number | int | 0 (默认) | | listen | address | string | 隧道监听 IP (例如 0.0.0.0) | | listen | port | int | UDP 监听端口 (ICMP 时忽略) | | spoof | source_ip | string | 此服务器在发送出站数据包时声称的 IP | | spoof | source_ipv6 | string | source_ip 的 IPv6 版本 | | spoof | peer_spoof_ip | string | 预期的入站客户端数据包的伪造源 IP | | spoof | peer_spoof_ipv6 | string | peer_spoof_ip 的 IPv6 版本 | | spoof | client_real_ip | string | 客户端真实的实际 IP | | spoof | client_real_ipv6 | string | client_real_ip 的 IPv6 版本 | | crypto | private_key | string | 服务器的 Base64 私钥 | | crypto | peer_public_key | string | 客户端的 Base64 公钥 | | performance | buffer_size | int | 主要数据包缓冲区大小 | | performance | mtu | int | 封装前的最大 payload | | performance | session_timeout | int | 主会话超时时间 (秒) | | performance | workers | int | 处理数据包的 goroutine 数量 | | performance | read_buffer | int | 内核 socket 读取缓冲区大小 | | performance | write_buffer | int | 内核 socket 写入缓冲区大小 | | reliability | enabled | bool | 启用自定义的类 TCP 可靠性层 | | reliability | window_size | int | 传输中未确认数据包的最大数量 | | reliability | retransmit_timeout_ms | int | 基础重传超时时间 | | reliability | max_retries | int | 每个数据包的最大重传尝试次数 | | reliability | ack_interval_ms | int | 发送 ACK 的频率 | | fec | enabled | bool | 启用 Reed-Solomon 前向纠错 | | fec | data_shards | int | 数据分片数量 | | fec | parity_shards | int | 校验分片数量 | | keepalive | enabled | bool | 启用定期 keepalive ping | | keepalive | interval_seconds | int | keepalive 数据包之间的间隔秒数 | | keepalive | timeout_seconds | int | 无活动时丢弃会话的超时时间 | | logging | level | string | "info", "debug", "warn", 或 "error" | | logging | file | string | 日志文件路径 (空 = stdout) |📌 v3+ 使用指南
## 使用说明 Spoof Tunnel 同时使用 Go 和 Rust 开发。要从源码自行构建(而不是使用 GitHub Actions 发布版本),您需要安装这两种编译器。 克隆代码库: ``` git clone --depth=1 https://github.com/ParsaKSH/spoof-tunnel.git ``` 进入项目目录: ``` cd spoof-tunnel ``` 使用 make 构建: ``` make core ``` 要同时构建面板和核心(需要 Node.js 和 npm): ``` make all ``` ## 客户端 (本地) 配置 | 键 | 类型 | 描述 | |---|---|---| | mode | string | 核心的角色:client 或 server (`local`) | | listen | string | 本地核心监听的 UDP endpoint (例如 `127.0.0.1:5000`) —— 将您的流量发送到这里 | | remote | string | 服务器 IP (外部服务器) | | remote_port | int | 服务器监听的端口 (用于 UDP/TCP) | | recv_port | int | 客户端监听的端口 (用于 TCP/UDP) | | spoof-ip | string | 单个欺骗 IP (如果不使用列表则使用此项) | | spoof-ip-file | string | 欺骗 IP 列表文件的路径 (用来代替单个 IP) | | spoof-port | int | 放在传出数据包中的源端口 (用于 TCP/UDP) | | send-transport | string | 客户端用来发送数据包的传输协议 (ICMP/ICMPv6/TCP/UDP) | | recv-transport | string | 服务器用来发回数据包的传输协议 (ICMP/ICMPv6/TCP/UDP) | ## 服务器 (远程) 配置 | 键 | 类型 | 描述 | |---|---|---| | mode | string | 核心的角色:client 或 server (`remote`) | | forward | string | 将接收到的流量转发到的 endpoint (例如 `127.0.0.1:51820`) | | client_ip | string | 客户端 IP (伊朗服务器) | | client_port | int | 客户端监听的端口 (用于 UDP/TCP) | | listen_port | int | 服务器监听以接收客户端数据包的端口 (用于 TCP/UDP) | | spoof-ip | string | 单个欺骗 IP (如果不使用列表则使用此项) | | spoof-ip-file | string | 欺骗 IP 列表文件的路径 (用来代替单个 IP) | | spoof-port | int | 放在传出数据包中的源端口 (用于 TCP/UDP) | | send-transport | string | 服务器用来发送数据包的传输协议 (ICMP/ICMPv6/TCP/UDP) | | recv-transport | string | 客户端用来向服务器发送数据包的传输协议 (ICMP/ICMPv6/TCP/UDP) | 所有配置参数既可以在 JSON 文件中提供,并使用 `./spoof run -c config.json` 运行,也可以作为命令行参数传递: ``` ./spoof remote --forward 127.0.0.1:51820 --spoof-ip-file /path/to/src.txt ... ```标签:DPI绕过, EVTX分析, IP伪造, 流量伪装, 网络层, 网络通信, 防火墙绕过, 隧道代理