2024-06-26更新,看到有不少人关注进度,首先说明一下当前没有弃坑,主要功能代码已经完成了,但是还不完善。另外一个事情就是最近WARP的IPv4段被GFW全面封禁了,同时我本地也没有IPv6的网络所以调试有点麻烦。最后就是本人最近有点懒了。
起因是看到有人提起Cloudflare的WARP,并且可以把WARP转换成WireGuard配置,因此可以无需使用WARP客户端,而是通过WireGuard客户端进行连接,还可以把WireGuard的连接用作其它代理工具的分流节点使用。
自然而然地就了解到「优选IP」,Cloudflare CDN的优选我们可以使用开源工具CloudflareSpeedTest,但是WARP或者说WireGuard的优选解决方案全都指向一个闭源工具。
因此,抱着学习的态度,分析一下上面所说的WARP优选IP闭源工具,尝试实现一个开源版本。
闭源工具分析
先运行工具试试看。
输出很直接告诉我们「收到UDP响应」这一个信息了,下一步尝试抓UDP包看看。
从抓包结果来看是使用WireGuard的握手协议,并且通过多次握手响应的往返时间(RTT)来测算延迟。
为什么不直接使用ping测试呢?
本节中的IP162.159.193.1
为Cloudflare公开的WARP ingress IP,端口UDP 2408是WARP的默认端口。WARP with firewall
ICMP/ping测试延迟
WARP的节点是没有禁ping的,那么当知道目标为有效的节点时可以简单地使用ping测试延迟吗?答案是可以,但是ping使用的是ICMP协议,而WireGuard使用的是UDP,又因为QoS中对这两种协议的流量实行不同的处理策略的关系,导致ping的测试结果并不能准确地反映本地与节点的UDP延迟。
同样的原因,使用TCP测试也不准确。
那么我们可以向节点发送一个任意的UDP数据包,并通过其响应测算延迟吗?
WireGuard握手
我们构造一个空包或假的无效的握手包,并将其发送到一个WireGuard节点会得到响应吗?答案是不会,WireGuard节点不会响应所有未经授权的(unauthorized)数据包。
We require authentication in the first handshake message sent because it does not require allocating any state on the server for potentially unauthentic messages. In fact, the server does not even respond at all to an unauthorized client; it is silent and invisible. The handshake avoids a denial of service vulnerability created by allowing any state to be created in response to packets that have not yet been authenticated.
WireGuard DoS Mitigation
因此我们需要构造并发送一个真正有效的握手数据包,才能从WireGuard节点收到响应。这里的「有效」是指使用有效的WireGuard私钥和公钥,根据WireGuard协议构造的握手触发消息(Handshake Initiation Message)。
构造握手触发消息
去年本想尝试用Python实现Wireguard的握手协议,写一半因各种加密编码太复杂,同时也没有找到满意的库,所以中途放弃了。
使用Go编写测试程序
最近看了下wireguard-go的实现代码,看到ping_clieng.go的示例发现非常符合本文的需求。Cloudflare WARP的节点是允许ICMP的,首先与节点建立Wireguard隧道,然后通过隧道向节点发送ICMP请求,可以规避测试延迟的ICMP协议和真实传输数据的UDP协议之间的QoS影响。相较与使用握手消息而言,更加接近真实数据传输(尽管Wireguard的握手速度很快),同时还可以方便测试与其它服务的延迟(各大翻墙客户端的延迟测试功能估计也是这样实现的)。
因为wireguard-go是一个Go写的项目,为了复用其中的Wireguard实现,便用Go开始写。基本功能已经实现但是还未完成,感兴趣的可以先关注我在Github的空仓库wgping,会在完成后上传代码。
Wireguard Endpoint ICMP Diagram
+-----------------+ +-----------------+ +-----------------+
| Local Machine | | WireGuard TUN | | WireGuard Server|
| | | Interface | | (Endpoint) |
| | | | | 162.159.193.1 |
| | | | | |
| +----------+ | | +----------+ | | +----------+ |
| | ICMP | | | | ICMP | | | | ICMP | |
| | Request | | | | Encapsu- | | | | Decapsu- | |
| +----+-----+ | | | lated | | | | lated | |
| | | | +----+-----+ | | +----+-----+ |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| v | | v | | v |
| +----+-----+ | | +----+-----+ | | +----+-----+ |
| | ICMP | | | | WireGuard| | | | ICMP | |
| | Request | | | | Packet | | | | Reply | |
| +----------+ | | +----+-----+ | | +----+-----+ |
| | | | | | | |
| | | v | | v |
| | | +----+-----+ | | +----+-----+ |
| | | | Internet | | | | Internet | |
| | | +----------+ | | +----------+ |
+-----------------+ +-----------------+ +-----------------+
Wireguard Remote ICMP Diagram
+-------------+ +-------------+ +-------------+ +-------------+
| Local | | WireGuard | | WireGuard | | Remote |
| Machine | | TUN | | Server | | Server |
| | | Interface | | (Endpoint) | | (google.com)|
| +---------+ | | +---------+ | | +---------+ | | +---------+ |
| | ICMP | | | | ICMP | | | | ICMP | | | | ICMP | |
| | Request | | | | Encapsu-| | | | Decapsu-| | | | Reply | |
| +----+----+ | | | lated | | | | lated | | | +----+----+ |
| | | | +----+----+ | | +----+----+ | | | |
| v | | | | | | | | v |
| +----+----+ | | v | | v | | +----+----+ |
| | ICMP | | | +----+----+ | | +----+----+ | | | ICMP | |
| | Request | | | |WireGuard| | | |WireGuard| | | | Reply | |
| +---------+ | | |Packet | | | |Packet | | | +---------+ |
| | | +----+----+ | | +----+----+ | | |
| | | | | | | | | |
| | | v | | v | | |
| | | +----+----+ | | +----+----+ | | |
| | | |Inetrnet | | | |Internet | | | |
| | | +---------+ | | +---------+ | | |
+-------------+ +-------------+ +-------------+ +-------------+
发表回复