使用Surge接入Public DNS+专业版

最近发现腾讯云的 Public DNS+专业版(传送门) 有提供dns级别的广告拦截,还提供了每个月300万次的免费请求数。

进去看了一下EasyList和AdGuard的规则都有带。考虑到自建AdGuard Home或者使用第三方屏蔽列表的麻烦程度,使用托管服务不乏是个方便的代替选项。

因为在试用的时候使用的是DoH,在8倍计费的状态下一个小时就记了20000次请求,因此决定要折腾一下UDP方式。

对于UDP方式,控制台有提供每个配置独立的IPv6地址,以及由多个用户共享、需要用户主动绑定自己当前地址的IPv4两种方式。
因此,在当前网络有IPv6时,使用IPv6地址解析能获得更加丝滑的体验;在当前网络只有IPv4时,需要在出口IP发生改变时通过接口更新当前的IP地址。

注意

以下方案在Surge Mac 版本5.0.1 (2162) 以及 Surge iOS 版本5.4.0 (2692) 下测试工作正常,其他版本兼容性请自行测试(理论上更高版本应该兼容)
多个设备使用时,请为每个设备创建独立的配置

部署

脚本1:在网络改变时,以及为防止局域网出口IP发生变化,每分钟调用自动绑定接口

let ip6addr = (typeof $network.v6 != 'undefined') && (typeof $network.v6.primaryAddress != 'undefined') ? $network.v6.primaryAddress : '';
if(ip6addr){ #如果当前网络有IPv6地址,跳过接口调用
    console.log('Skip as ipv6 network.')
    $done();
}else{
    $httpClient.get({url: "自动绑定接口URL", timeout: 3, headers: {Connection: "close"}},function(error){
        if(error){
            $notification.post('DNSPod','', 'Update Failed!');
        }else{
            console.log('Update Success.')
            if($persistentStore.read("DNSPod_IP") != $network.v4.primaryAddress){
                $persistentStore.write($network.v4.primaryAddress, "DNSPod_IP");
            }
        }
        $done();
    });
}

脚本2:在DNS解析时调用,返回应使用的IP地址

if($domain == 'link.dns.pub'){ #跳过自动绑定接口域名
    console.log('Fallback to default dns (link.dns.pub).');
    $done({});
}

let isIPv6 = (typeof $network.v6 != 'undefined') && (typeof $network.v6.primaryAddress != 'undefined') && $network.v6.primaryAddress
let dnsV4 = ["xx.xx.xx.xx", "yy.yy.yy.yy"]; #两个IPv4 DNS 服务器
let dnsV6 = ["2402:4e00:0::xxxx:xxxx", "2402:4e00:0::yyyy:yyyy"]; #两个IPv6 DNS 服务器

if(isIPv6){ #如果有IPv6,直接使用IPv6地址解析
    $done({servers: dnsV6});
}else{
    let v4AddrMatch = $persistentStore.read("DNSPod_IP") == $network.v4.primaryAddress;
    if(v4AddrMatch){
        $done({servers: dnsV4});
    }else{ #如果在两次DNS请求之间IPv4地址发生变化,调用自动绑定接口
        console.log('Update dns source addr.');
        $httpClient.get({url: "自动绑定接口URL", timeout: 3, headers: {Connection: "close"}},function(error, response, data){
            if (error){
                console.log('Fallback to default dns (UpdateFailed).');
                $done({}); #如果调用失败,回退到系统默认DNS
            }else{
                $persistentStore.write($network.v4.primaryAddress, "DNSPod_IP");
                $done({servers: dnsV4});
            }
        });
    }
}

在Surge配置文件中加入以下行:

[General]
...
dns-server = system
use-local-host-item-for-proxy=true

[Script]
...
DNSPodUpdate = type=cron,cronexp="* * * * *",script-path=脚本1所在URL
DNSPodChanged = type=event,event-name=network-changed,script-path=脚本1所在URL
DNSPod = type=dns,script-path=脚本2所在URL

[Host]
...
link.dns.pub = server:system
* = script:DNSPod

QA

Q1:为什么不使用DoH和DoT,不怕被DNS投毒吗?

A1:在当今多数APP都强制使用HTTPS的情况下,我认为已经可以保证访问到正确的目标服务器。因此我选择向成本妥协。

Q2:为什么不使用更加注重隐私的提供商,比如NextDNS?

A2:我相信如果运营商或其他中间人想监控你的网络访问,他们大可直接获取SNI来得到更加准确的数据,而不是通过DNS。且这些提供商在中国大陆大多处于无法访问,或多少有些不稳定的状态。与其通过技术手段去使用它们,不如直接退一步换用更加稳定的服务。

标签: dnspod, surge, easylist, adguard

添加新评论