解决电信 IPv6 访问部分网站异常

为什么折腾

广东电信已分配 IPv6 到宽带,拨号后可以拿到一段 /60 的 IPv6。在 NAS 上 yum 用外网源更新起来几乎能跑上百兆,真爽。

可是爽没多久就发现,国内网络出问题了。微信朋友圈图片经常刷不开,微信视频视频加载不出来。微博打开要等半天,IPv6 连接失败后回落 IPv4 才能打开,百度贴吧、腾讯、七牛 CDN 的部分节点 IPv6 也是有解析但 IP 不能连接。

例如 weibo.com 的连接情况如下:

> curl -v -k https://[2400:89c0:1053:3::18] --connect-timeout 5
*   Trying 2400:89c0:1053:3::18:443...
* Connected to 2400:89c0:1053:3::18 (2400:89c0:1053:3::18) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* Operation timed out after 5001 milliseconds with 0 out of 0 bytes received
* Closing connection 0
curl: (28) Operation timed out after 5001 milliseconds with 0 out of 0 bytes received

放着这么好的国际线路真的不想放弃 IPv6,试了很多方案,最终敲定 PowerDNS 用来屏蔽电信 IPv6 解析结果来解决。

开工

DNS 最好是有两台,家里有一台 NAS,还有个吃灰树莓派,赶紧开起来安装 PowerDNS 递归服务器版本。

使用 yum 或者 apt 安装最新版本的 PowerDNS 递归版,recursor.conf 配置文件写

local-address=0.0.0.0
allow-from=192.168.0.0/16
lua-dns-script=ipv6.lua

观察一圈有问题的域名,解析出来的电信 IPv6 基本是 240e:: 的段以及 2400:89c0:: 和 2400:5280:: 这三个。使用 lua hook 取出 AAAA 解析结果,匹配前缀是这几个就把结果清空返回即可。代码如下:

function postresolve(dq)
    if dq.qtype == pdns.AAAA then
        local records = dq:getRecords()
        for key, value in pairs(records) do
            local ipv6 = value:getContent()
            local prefix1 = string.sub(ipv6, 1, 4)
            if prefix1 == "240e" then
                dq.appliedPolicy.policyKind = pdns.policykinds.NODATA
                return true
            end
            local prefix2 = string.sub(ipv6, 1, 9)
            if prefix2 == "2400:89c0" or prefix2 == "2400:5280" then
                dq.appliedPolicy.policyKind = pdns.policykinds.NODATA
                return true
            end
        end
    end
    return false
end

上述代码需要在 PowerDNS 4.4 以上版本使用,搞定之后把 DHCP 的 DNS 设置到 NAS 和树莓派的内网 IP 上。现在开始享受超丝滑的 IPv4 + Ipv6 吧!

解决电信 IPv6 访问部分网站异常有 1 个评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据