使用 overture 获取干净的 DNS 解析

读本文需要基本的 linux 知识

Overture 安装与部署

由于某些奇怪的原因,运营商网络的默认 DNS 经常会出现问题。为了获取更干净的 DNS 解析结果,我决定在本地搭建 DNS 服务器。

我选择的是 Overture。这是一个由 Golang 编写的简单易用的 DNS。部署的方式也很简单,从 Github 下载编译好的 overture 即可。

下载完成后解压,获得 Overture 客户端和一些默认的配置文件。在我本地的网络环境下,默认配置文件可以正常使用。使用命令如下:

1
2
sudo systemctl stop systemd-resolved.service
sudo overture -c config.json -l access.log -v

如果希望开机运行,可以禁用 systemd-resolved 并将 overture 加入 crontab

1
2
sudo systemctl disable systemd-resolved.service
crontab -e

然后输入并保存:

1
@reboot nohup <path-to-overture>/overture -c <path-to-config>/config.json -l <path-to-access>/access.log -v > /dev/null 2>&1 &

重启树莓派,并将本机的 DNS 地址修改为树莓派的 IP 地址即可

到这里我们就基本完成了,目前已经达到运营商劫持之后的解析水平。测试命令:

1
dig @<rpi-ip-address> google.com

能正常解析出记录即可。

DNS 劫持应归措施

接下来我们来处理被运营商劫持的域名。为了解决 DNS 劫持问题,我们首先应该对被劫持的域名做出区分。适用如下命令即可得到常见的被劫持域名:

1
2
3
curl https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > /tmp/temp_gfwlist.txt
curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > /tmp/temp_koolshare.txt
cat /tmp/temp_gfwlist.txt /tmp/temp_koolshare.txt | sort -u > gfw_all_domain.txt

将得到的 gfw_all_domain.txt 填入配置文件(相关的配置文件详见文末):

1
2
3
4
"DomainFile": {
    "Alternative": "<path_to_gfwlist>/gfw_all_domain.txt",
    "Matcher": "suffix-tree"
}

并且,我们要知道那些域名是没有被污染的。这里 overture 给我们提供了一个 IP 列表的配置项,解析出的地址如果是在 IP 列表中则无需处理:

1
wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt

然后修改配置文件:

1
2
3
"IPNetworkFile": {
    "Primary": "<path_to_chnroute>/china_ip_list.txt"
}

此时重启树莓派,再次使用 dig 命令测试即可得到正确的解析结果:

overture-dig-test

最后附上我的配置文件,请自行替换其中的相关域:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
    "BindAddress": ":53",
    "DebugHTTPAddress": "127.0.0.1:5555",
    "PrimaryDNS": [
        {
            "Name": "alidns",
            "Address": "223.5.5.5:53",
            "Protocol": "udp",
            "SOCKS5Address": "",
            "Timeout": 3,
            "EDNSClientSubnet": {
                "Policy": "auto",
                "NoCookie": true
            }
        }
    ],
    "AlternativeDNS": [
        {
            "Name": "dns.mhtt1123.cn",
            "Address": "https://dns.mhtt1123.cn/dns-query",
            "Protocol": "https",
            "SOCKS5Address": "",
            "Timeout": 15,
            "EDNSClientSubnet": {
                "Policy": "disable"
            }
        }
    ],
    "OnlyPrimaryDNS": false,
    "IPv6UseAlternativeDNS": false,
    "AlternativeDNSConcurrent": false,
    "WhenPrimaryDNSAnswerNoneUse": "AlternativeDNS",
    "IPNetworkFile": {
        "Primary": "/usr/local/share/overture/chnroute"
    },
    "DomainFile": {
        "Alternative": "/usr/local/share/overture/gfw_all_domain",
        "Matcher": "suffix-tree"
    },
    "HostsFile": {
	    "HostsFile": "/usr/local/share/overture/hosts",
	    "Finder": "regex-list"
    },
    "MinimumTTL": 0,
    "CacheSize": 500,
    "RejectQType": [
        255
    ]
}

配置文件详解

  1. DNS 配置中的 “Protocol”,支持 tcpudptcp-tlshttps 四种方式,我们这里使用了普通的 udp 方式(被劫持但是无所谓)和 https 方式(不会被污染)
  2. 我们配置了两个上游 DNS,如何确定采信哪个呢?IPNetworkFile 对结果 IP 进行匹配,决定最终结果
  3. 能不能在匹配前就决定使用哪个上游 DNS 呢?可以,DomainFile
  4. 加入我想屏蔽某些域名(比如 netflix 的 IPv6 解析结果),怎么办呢?HostsFile,我的相关配置见文末
  5. 太慢了,怎么办?把结果加入缓存,修改 CacheSize 即可

更详细内容在项目的 Github 即可找到。

我的 hosts 配置:

::1 .*netflix.com
::1 .*nflxext.com
::1 .*nflximg.net
::1 .*nflximg.com
::1 .*nflxsearch.net
::1 .*nflxso.net
::1 .*nflxvideo.net
::1 .*fast.com

引用

shawn1m/overture [overture] 无污染的智能 DNS 折腾记 #4

updatedupdated2020-05-292020-05-29
加载评论