应用程序级代理和DNS污染解决方案

Windows上的应用程序级代理

应用程序代理方案:Proxifier

目前没有一个应用程序级代理的解决方案优于Proxifier,恐怕在未来很长一段时间内也是如此。我建议购买Proxifier的标准版而不是便携版,因为标准版有一些独占功能,比如让虚拟机也走代理。
在为Proxifier创建代理规则时,普遍有两种模式:
  1. 1.
    默认通过直接连接,通过规则代理特定类型的连接。
  2. 2.
    默认通过代理连接,通过规则让特定类型的连接直连。
建议选择默认通过代理连接,通过规则直连的模式。因为在实际需求中,可以直连的连接往往是可以提前确定的,反之则不行。至此,问题已经被简化为如何创建“让特定类型的连接直接连接”的规则。

禁用浏览器的HTTP/3(HTTP over QUIC)支持

QUIC是一个基于UDP的协议,而Proxifier不支持代理UDP连接。越来越多的网站开始支持HTTP/3对于Proxifier来说意味着越来越多的网站无法被代理。
为解决这个问题,需要手动禁用浏览器的HTTP/3或QUIC支持。考虑到UDP协议还经常被ISP QoS,通过禁用HTTP/3回退到基于TCP的HTTP/2几乎只有优点。

直连代理规则注入器:ppx-inject

手动为Proxifier创建直连代理规则是一种非常低效的做法,因为需要创建的规则数量之多,很快就会超出人力的极限。ppx-inject是我编写的CLI程序,用于向Proxifier的规则文件批量注入地区相关的直连规则。
ppx-inject能够自动从区域互联注册管理机构(RIR)下载最新的IP数据,然后将指定地区的IP地址范围添加为Proxifier的直连规则。当你需要更新IP地址数据库时,只需要重新运行一次命令。需要注意的是,在使用基于IP的规则时,需要关闭Proxifier的“通过代理解析DNS服务器”的功能。
使用ppx-inject建立的规则会导致所有非直连地区的连接都走代理,这可能不是每个人想要的结果。

代理服务器硬切换:gost

Proxifier有一个缺点:缺少硬切换代理服务器的功能,在切换代理规则时不会切断之前建立的所有连接。我问过作者是否可以在未来加上这个功能,作者无法给出任何保证,好在还可以通过gost这样的程序实现。
gost的功能是为多个代理提供客户端侧的负载均衡。实际使用中,在客户端侧对代理服务器实现负载均衡意义不大,因为信道的品质不一致,而自动化评估信道品质可能会遭遇观察者效应,导致评估结果的可靠性减弱。
在此我们只是借助负载均衡器必然具有的转发功能来实现代理服务器的硬切换,原理很简单:编写对应的脚本,在执行脚本时,杀死现有gost进程(届时,所有已建立的连接都会断开),再按新的转发参数启动新的gost进程。
在使用gost的情况下,Proxifier只需连向gost的端口,实际使用的代理服务器由gost的启动参数决定。

解决DNS污染

当DNS遇上事实核查:fcdns

fcdns是一个DNS转发器,将DNS查询以一定的规则转发给下级DNS。fcdns与其他DNS污染解决方案的区别在于它通过我称为“投毒检测”的事实核查机制来判断域名是否被污染。通过搭配一份作为白名单使用的IP地址范围,fcdns可以决定一个DNS查询应该被转发给“缓慢但具有正确性的可信信道”还是“快速但可能被污染的不可信信道”。
fcdns的具体原理在项目主页有比较详细的描述,简单来说,它建立在当前“向非DNS服务器发出DNS查询也会收到DNS回答(来自投毒者的抢答)”这一事实上。即使这个污染策略改变,使用fcdns的用户也至少可以得到一份已被污染的域名清单,这总是比人工编写的黑名单更准确。
值得一提的是,通过在ppx-inject和fcdns上共用相同的IP地址范围,可以确保连接总是得到最佳的DNS查询结果。

建立可信信道:CoreDNS

CoreDNS被用于建立fcdns使用的本地可信信道,可信信道的根基是像DNS over HTTPS或DNS over TCP这样的协议。这些协议在现实世界中相当脆弱,因为公共DNS服务器很容易识别和屏蔽,但只要配合Proxifier,就可以绕过限制。
使用CoreDNS的原因在于它很简单,其配置文件在处理此类需求时很容易编写,并且具有基础的缓存功能。

代理Windows上的虚拟机

在实施完上述解决方案时,实际上已经做完了让虚拟机走Proxifier代理的大部分准备。虚拟机应该以NAT方式联网,这样它的网关就是物理机,使用的也是物理机的DNS。当你解决了物理机的DNS污染,虚拟机的DNS污染也就自动解决了。
虚拟机的NAT连接是由一个程序完成的(对于VMware,是vmnat.exe),为了让它走代理,Proxifier需要比相关程序更早启动。然而,即使Proxifier本身是一个开机启动项,它的启动时点也可能晚于其他启动项,错过代理注入的时机。为了解决这个问题,可以让Proxifier以服务的形式运行,服务的启动时点比启动项早。Proxifier提供了Service Mode以实现此需求,此模式的缺点是不能以GUI的形式配置Proxifier,在配置前需要先手动退出Service Mode。开启Service Mode有一些前提条件,这些在官方文档里都有说明。