ValdikSS/GoodbyeDPI
GitHub: ValdikSS/GoodbyeDPI
Windows平台深度包检测规避工具,通过流量伪装和分片技术绕过ISP的网站访问限制。
Stars: 28001 | Forks: 2136
# GoodbyeDPI — 深度包检测规避工具
本软件旨在绕过许多互联网服务提供商 (ISP) 中用于屏蔽特定网站访问的深度包检测 (DPI) 系统。
它可以处理通过光分路器或端口镜像连接的 DPI(**被动 DPI**),这种 DPI 不阻止任何数据,只是比请求的目的地更快地做出响应;以及串联连接的**主动 DPI**。
需要 **Windows 7、8、8.1、10 或 11** 以及管理员权限。
# 快速入门
* **俄罗斯用户**:从 [Releases 页面下载最新版本](https://github.com/ValdikSS/GoodbyeDPI/releases),解压文件并运行 **1_russia_blacklist_dnsredir.cmd** 脚本。
* 其他国家用户:从 [Releases 页面下载最新版本](https://github.com/ValdikSS/GoodbyeDPI/releases),解压文件并运行 **2_any_country_dnsredir.cmd**。
这些脚本会以推荐模式启动 GoodbyeDPI,并将 DNS 解析器重定向到非标准端口的 Yandex DNS(以防止 DNS 污染)。
如果有效——恭喜!你可以直接使用或进行进一步配置。
# 如何使用
从 [Releases 页面下载最新版本](https://github.com/ValdikSS/GoodbyeDPI/releases) 并运行。
## 支持的参数
要获取关于当前程序版本的相关信息,请在启动时使用 -h (--help) 参数。
```
Usage: goodbyedpi.exe [OPTION...]
-p block passive DPI
-q block QUIC/HTTP3
-r replace Host with hoSt
-s remove space between host header and its value
-m mix Host header case (test.com -> tEsT.cOm)
-f set HTTP fragmentation to value
-k enable HTTP persistent (keep-alive) fragmentation and set it to value
-n do not wait for first segment ACK when -k is enabled
-e set HTTPS fragmentation to value
-a additional space between Method and Request-URI (enables -s, may break sites)
-w try to find and parse HTTP traffic on all processed ports (not only on port 80)
--port additional TCP port to perform fragmentation on (and HTTP tricks with -w)
--ip-id handle additional IP ID (decimal, drop redirects and TCP RSTs with this ID).
This option can be supplied multiple times.
--dns-addr redirect UDP DNS requests to the supplied IP address (experimental)
--dns-port redirect UDP DNS requests to the supplied port (53 by default)
--dnsv6-addr redirect UDPv6 DNS requests to the supplied IPv6 address (experimental)
--dnsv6-port redirect UDPv6 DNS requests to the supplied port (53 by default)
--dns-verb print verbose DNS redirection messages
--blacklist perform circumvention tricks only to host names and subdomains from
supplied text file (HTTP Host/TLS SNI).
This option can be supplied multiple times.
--allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.
--frag-by-sni if SNI is detected in TLS packet, fragment the packet right before SNI value.
--set-ttl activate Fake Request Mode and send it with supplied TTL value.
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
--auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease
it based on a distance. If the distance is shorter than a2, TTL is decreased
by a2. If it's longer, (a1; a2) scale is used with the distance as a weight.
If the resulting TTL is more than m(ax), set it to m.
Default (if set): --auto-ttl 1-4-10. Also sets --min-ttl 3.
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
--min-ttl minimum TTL distance (128/64 - TTL) for which to send Fake Request
in --set-ttl and --auto-ttl modes.
--wrong-chksum activate Fake Request Mode and send it with incorrect TCP checksum.
May not work in a VM or with some routers, but is safer than set-ttl.
--wrong-seq activate Fake Request Mode and send it with TCP SEQ/ACK in the past.
--native-frag fragment (split) the packets by sending them in smaller packets, without
shrinking the Window Size. Works faster (does not slow down the connection)
and better.
--reverse-frag fragment (split) the packets just as --native-frag, but send them in the
reversed order. Works with the websites which could not handle segmented
HTTPS TLS ClientHello (because they receive the TCP flow "combined").
--fake-from-hex Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).
This option can be supplied multiple times, in this case each fake packet
would be sent on every request in the command line argument order.
--fake-with-sni Generate fake packets for Fake Request Mode with given SNI domain name.
The packets mimic Mozilla Firefox 130 TLS ClientHello packet
(with random generated fake SessionID, key shares and ECH grease).
Can be supplied multiple times for multiple fake packets.
--fake-gen Generate random-filled fake packets for Fake Request Mode, value of them
(up to 30).
--fake-resend Send each fake packet value number of times.
Default: 1 (send each packet once).
--max-payload [value] packets with TCP payload data more than [value] won't be processed.
Use this option to reduce CPU usage by skipping huge amount of data
(like file transfers) in already established sessions.
May skip some huge HTTP requests from being processed.
Default (if set): --max-payload 1200.
LEGACY modesets:
-1 -p -r -s -f 2 -k 2 -n -e 2 (most compatible mode)
-2 -p -r -s -f 2 -k 2 -n -e 40 (better speed for HTTPS yet still compatible)
-3 -p -r -s -e 40 (better speed for HTTP and HTTPS)
-4 -p -r -s (best speed)
Modern modesets (more stable, more compatible, faster):
-5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload
-6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload
-7 -f 2 -e 2 --wrong-chksum --reverse-frag --max-payload
-8 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload
-9 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload -q (this is the default)
Note: combination of --wrong-seq and --wrong-chksum generates two different fake packets.
```
## 如何检测
要检查你的 ISP 的 DPI 是否可以被绕过,首先确保你的提供商没有通过在浏览器中启用“安全 DNS (DNS over HTTPS)”选项来污染 DNS 应答。
* **Chrome**:设置 → [隐私和安全](chrome://settings/security) → 使用安全 DNS → 选择:NextDNS
* **Firefox**:[设置](about:preferences) → 网络设置 → 启用 DNS over HTTPS → 选择提供商:NextDNS
然后运行 `goodbyedpi.exe` 可执行文件(不带任何选项)。如果有效——恭喜!你可以直接使用或进行进一步配置,例如,如果你所在国家/地区的被封锁网站列表已知且可用,可以使用 `--blacklist` 选项。
如果你的提供商拦截 DNS 请求,你可能需要使用 `--dns-addr` 选项指向运行在非标准端口上的公共 DNS 解析器(例如 Yandex DNS `77.88.8.8:1253`),或者使用第三方应用程序配置 DNS over HTTPS/TLS。
查看 .cmd 脚本并根据你的偏好和网络环境进行修改。
# 工作原理
### 被动 DPI
大多数被动 DPI 在你尝试通过 HTTP 访问被封锁的网站时会发送 HTTP 302 重定向,在 HTTPS 情况下则会发送 TCP 重置 (RST),且速度比目标网站更快。DPI 发送的数据包通常具有值为 `0x0000` 或 `0x0001` 的 IP Identification 字段,正如在俄罗斯提供商中见到的那样。如果这些数据包将你重定向到另一个网站(审查页面),它们将被 GoodbyeDPI 阻止。
### 主动 DPI
欺骗主动 DPI 比较棘手。目前,该软件使用 7 种方法来规避主动 DPI:
* 对第一个数据包进行 TCP 层分片
* 对持久 (keep-alive) HTTP 会话进行 TCP 层分片
* 将 `Host` 头替换为 `hoSt`
* 删除 `Host` 头中头名称与值之间的空格
* 在 HTTP 方法(GET、POST 等)与 URI 之间添加额外的空格
* 混合 Host 头值的大小写
* 发送具有低 TTL 值、错误校验和或错误 TCP 序列号/确认号的虚假 HTTP/HTTPS 数据包,以欺骗 DPI 并阻止其将数据传送到目的地
这些方法不应破坏任何网站,因为它们完全兼容 TCP 和 HTTP 标准,但这足以阻止 DPI 数据分类并规避审查。额外的空格可能会破坏某些网站,尽管根据 HTTP/1.1 规范(参见 19.3 Tolerant Applications),这是可接受的。
该程序会加载 WinDivert 驱动程序,该驱动程序使用 Windows Filtering Platform 设置过滤器并将数据包重定向到用户空间。只要控制台窗口可见,它就会一直运行,并在你关闭窗口时终止。
# 如何从源代码构建
该项目可以使用 **GNU Make** 和 [**mingw**](https://mingw-w64.org) 构建。唯一的依赖项是 [WinDivert](https://github.com/basil00/Divert)。
要构建 x86 exe,请运行:
`make CPREFIX=i686-w64-mingw32- WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/x86`
对于 x86_64:
`make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/amd64`
# 如何安装为 Windows 服务
请查看 `service_install_russia_blacklist.cmd`、`service_install_russia_blacklist_dnsredir.cmd` 和 `service_remove.cmd` 脚本中的示例。
根据你自己的需求修改它们。
# 已知问题
* 极度陈旧的 Windows 7 安装无法加载 WinDivert 驱动程序,因为缺少对 SHA256 数字签名的支持。请安装 KB3033929 [x86](https://www.microsoft.com/en-us/download/details.aspx?id=46078)/[x64](https://www.microsoft.com/en-us/download/details.aspx?id=46148),或者更好的做法是使用 Windows Update 更新整个系统。
* Intel/Qualcomm Killer 网卡:Killer Control Center 中的 `Advanced Stream Detect` 与 GoodbyeDPI 不兼容,请[禁用它](https://github.com/ValdikSS/GoodbyeDPI/issues/541#issuecomment-2296038239)。
* QUIK 交易软件[可能与 GoodbyeDPI 冲突](https://github.com/ValdikSS/GoodbyeDPI/issues/677#issuecomment-2390595606)。请先启动 QUIK,然后启动 GoodbyeDPI。
* ~~某些 SSL/TLS 协议栈无法处理分片的 ClientHello 数据包,导致 HTTPS 网站无法打开。Bug:[#4](https://github.com/ValdikSS/GoodbyeDPI/issues/4),[#64](https://github.com/ValdikSS/GoodbyeDPI/issues/64)。~~ 分片问题已在 v0.1.7 中修复。
* ~~ESET 杀毒软件与 WinDivert 驱动程序不兼容 [#91](https://github.com/ValdikSS/GoodbyeDPI/issues/91)。这很可能是杀毒软件的错误,而不是 WinDivert 的问题。~~
# 类似项目
- **[zapret](https://github.com/bol-van/zapret)** 由 @bol-van 开发(适用于 MacOS、Linux 和 Windows)
- **[Green Tunnel](https://github.com/SadeghHayeri/GreenTunnel)** 由 @SadeghHayeri 开发(适用于 MacOS、Linux 和 Windows)
- **[DPI Tunnel CLI](https://github.com/nomoresat/DPITunnel-cli)** 由 @zhenyolka 开发(适用于 Linux 和路由器)
- **[DPI Tunnel for Android](https://github.com/nomoresat/DPITunnel-android)** 由 @zhenyolka 开发(适用于 Android)
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** 由 @krlvm 开发(适用于 Windows、MacOS 和 Linux)
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** 由 @krlvm 开发(适用于 Android)
- **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** 由 @xvzc 开发(适用于 macOS 和 Linux)
- **[SpoofDPI-Platform](https://github.com/r3pr3ss10n/SpoofDPI-Platform)** 由 @r3pr3ss10n 开发(适用于 Android、macOS、Windows)
- **[GhosTCP](https://github.com/macronut/ghostcp)** 由 @macronut 开发(适用于 Windows)
- **[ByeDPI](https://github.com/hufrea/byedpi)** 适用于 Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** / **[ByeByeDPI](https://github.com/romanvht/ByeByeDPI/)** 适用于 Android(无需 root)
- **[youtubeUnblock](https://github.com/Waujito/youtubeUnblock/)** 由 @Waujito 开发(适用于 OpenWRT/Entware 路由器和 Linux)
# 致谢
感谢 @basil00 提供的 [WinDivert](https://github.com/basil00/Divert)。这是本程序的核心部分。
感谢每一位 [BlockCheck](https://github.com/ValdikSS/blockcheck) 的贡献者。如果没有这个工具,就不可能理解 DPI 的行为。
标签:AWS, DPI, HTTP分片, ISP限制绕过, 互联网自由, 反审查, 域名重定向, 客户端加密, 抗封锁, 流量混淆, 深度包检测绕过, 网络安全, 网络审查规避, 网络工具, 网络流量分析, 网络流量处理, 防火墙穿透, 隐私保护