IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    使用 Unbound 搭建更好用的 DNS 服务器

    Phoenix Nemo发表于 2016-11-13 04:54:06
    love 0

    用了好久的 DNSMasq 方案终于在大半年前彻底炸掉了。

    原因不光是 DNSMasq 性能和安全性完全不足以撑起公网缓存/递归 DNS 的任务,也有想要做反污染和加速的时候确实太蛋疼的问题。

    现在使用的方案是 Unbound+DNSCrypt,外带一份加速列表。这段时间看来,不管在我本机还是在公网服务的两台,效果和反馈都很不错。

    准备工作

    需要的程序:

    • unbound
    • dnscrypt-proxy
    • makefile
    • git

    makefile 和 git 用于处理 dnsmasq-china-list。

    Unbound 配置

    修改文件 /etc/unbound/unbound.conf。没有这个文件的话,一般需要找一下软件包里提供的配置 example 文件复制过去。这里列出的仅包含需要修改的部分,其他的按照默认配置一般没有问题。

    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
    num-threads: 2 # 线程数可以修改为物理核心数
    interface: 0.0.0.0 # 侦听所有 IPv4 地址
    interface: ::0 # 侦听所有 IPv6 地址
    # 如果只需要本机使用,则一个 interface: 127.0.0.1 即可
    so-rcvbuf: 4m
    so-sndbuf: 4m # 本机使用的话,这俩 buf 可以取消注释
    so-reuseport: yes # 如果开了多线程,就写 yes
    msg-cache-size: 64m # 本机可以设置 4m 或者更小
    rrset-cache-size: 128m # 本机可以设置 4m 或者更小
    cache-max-ttl: 3600 # 建议设置一个不太大的值...专治各种运营商 DNS 缓存不服
    outgoing-num-tcp: 256 # 限制每个线程向上级查询的 TCP 并发数
    incoming-num-tcp: 1024 # 限制每个线程接受查询的 TCP 并发数
    # 下面这四个不需要解释了吧,不想用那个就写 no
    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    tcp-upstream: no # 默认是 no,隧道状态比较稳的话也不需要写 yes。一些情况下强制使用 tcp 连上游的话写 yes
    access-control: 0.0.0.0/0 allow # 本机用的话建议设置 127.0.0.0/8 allow,局域网用适当调整
    root-hints: "/etc/unbound/root.hints" # 没有的话在 ftp://FTP.INTERNIC.NET/domain/named.cache 下载一份
    hide-identity: yes # 不返回对 id.server 和 hostname.bind 的查询。
    hide-version: yes # 不返回对 version.server 和 version.bind 的查询。
    # 不过下面有 identity 和 version 的自定义选项,不隐藏这些的话,修改下选项还可以卖个萌(´・ω・`)
    harden-glue: yes # 建议打开
    module-config: "iterator" # 禁用 DNSSEC 检查,如果上游不支持 DNSSEC 就关掉。注意这个选项有可能在其他 include 的文件里
    unwanted-reply-threshold: 10000000 # 针对各种网络不服,数值为建议值,具体可以自己修改看看效果
    do-not-query-localhost: no # 一般是为了防止扯皮丢包开着,不过等下要用 DNSCrypt 所以关掉
    prefetch: yes # 蛮好用的,开着吧
    minimal-responses: yes # 省带宽,开着吧。本机用可以关掉
    # 关键部分来了,把默认查询全部丢给 DNSCrypt。使用 [地址]@[端口] 指定查询地址和端口,默认端口 53。
    # 然后把国内的地址丢给国内的缓存服务器。这两个选项的顺序不能错哟。
    # 如果使用隧道查询,把这个地址改为隧道对端的地址,或者一个国外的 DNS 服务器都可以,例如 8.8.8.8。
    # 具体看是在对端开 DNS 还是直接用国外的服务器。后者的话,前面 outgoing-interface 可以直接设置隧道本地端的地址,不过要配合 dnsmasq-china-list 的话,还是写路由表比较合适,否则不够灵活。
    include: "/etc/unbound/accelerated-domains.china.unbound.conf"
    forward-zone:
    name: "."
    forward-addr: 127.0.0.1@5353

    DNSCrypt 配置

    修改文件 /etc/default/dnscrypt-proxy。

    1
    2
    DNSCRYPT_PROXY_LOCAL_ADDRESS=127.0.0.1:5353 # 设置侦听在 127.0.0.1 端口 5353。
    DNSCRYPT_PROXY_RESOLVER_NAME=cisco # cisco 其实蛮快的,但是慢的话就去用个别的吧。d0wn 的那堆服务器真的不稳定,和名字一个样...

    如果使用 systemd 的话这个文件就没用辣,看这里看这里

    修改文件 /usr/lib/systemd/system/dnscrypt-proxy.socket。

    要修改的部分:

    1
    2
    ListenStream=127.0.0.1:5353
    ListenDatagram=127.0.0.1:5353

    127.0.0.1:5353 就是上面 unbound 配置里 DNSCrypt 的监听地址。

    dnsmasq-china-list 来加速

    首先 clone 这个仓库到本地。

    执行 make unbound 来生成一份 unbound 配置,然后放在上面 unbound 配置里写的地址,也就是 /etc/unbound/accelerated-domains.china.unbound.conf。默认的 DNS 是 114DNS,最不太近的一段时间都挺残的所以不建议用。如果要改为其他的,例如 DNSPod PublicDNS 的话使用 make SERVER=119.29.29.29 unbound 即可。

    如果还需要一些特定的缓存上游设置,要放在 include: "/etc/unbound/accelerated-domains.china.unbound.conf" 这句前面。来举一只栗子。

    举一只果子的栗子。

    AppStore 的加载和下载速度一直在国内饱受一些极客们的诟病,然而同时饱受诟病的运营商 DNS 解析 AppStore 的下载地址反而是国内的 CDN 地址,速度会非常快。

    需要使用 dig 工具,并且要在国内的网络环境下测试。Linux 发行版里都有包可以装,OS X 则自带。

    第一条命令:dig +trace a100.phobos.apple.com.

    递归追踪解析结果,这个记录被 CNAME 到了 a100.phobos-apple.com.akadns.net.。

    第二条命令:dig +trace a100.phobos-apple.com.akadns.net.,得到这条记录被 CNAME 到了 a1-a200.itunes-apple.com.akadns.net.。

    第三条命令:dig +trace a1-a200.itunes-apple.com.akadns.net.,看到了 CDN 的地址,a1-a200.phobos.apple.chinacache.net.。

    所以如果有国内的地址直接去跟踪解析 akadns.net 的 DNS 的话,一般是可以正确解析到国内 CDN 的。先找一个 akadns.net 的权威 NS 地址,比如 a1-128.akadns.net 对应的 IP 是 193.108.88.128。同时还得有国内的 CDN 地址也从国内地址去解析,那么配置里这样写:

    1
    2
    3
    4
    5
    6
    forward-zone:
    name: "akadns.net."
    forward-addr: 193.108.88.128
    forward-zone:
    name: "chinacache.net."
    forward-addr: 119.29.29.29 # DNSPod PublicDNS 的服务器地址

    多次尝试之后,发现还有一个 CDN 地址 0gq2p7eckbs26f.mwcname.com,那么也把这个地址交给 unbound 通过国内网络解析。

    1
    2
    3
    forward-zone:
    name: "mwcname.com."
    forward-addr: 119.29.29.29

    一并加到上面的配置里,然后来测试下。

    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
    Phoenix-X1-Carbon :: ~ » dig @127.0.0.1 a100.phobos.apple.com

    ; <<>> DiG 9.10.3-P4 <<>> @127.0.0.1 a100.phobos.apple.com
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24454
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 14, AUTHORITY: 0, ADDITIONAL: 1

    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 4096
    ;; QUESTION SECTION:
    ;a100.phobos.apple.com. IN A

    ;; ANSWER SECTION:
    a100.phobos.apple.com. 3596 IN CNAME a100.phobos-apple.com.akadns.net.
    a100.phobos-apple.com.akadns.net. 117 IN CNAME a1-a200.itunes-apple.com.akadns.net.
    a1-a200.itunes-apple.com.akadns.net. 297 IN CNAME a1-a200.phobos.apple.chinacache.net.
    a1-a200.phobos.apple.chinacache.net. 1799 IN CNAME a1-a200.phobos.apple.cncssr.chinacache.net.
    a1-a200.phobos.apple.cncssr.chinacache.net. 1799 IN CNAME cc00109.h.cncssr.chinacache.net.
    cc00109.h.cncssr.chinacache.net. 120 IN A 223.99.228.87
    cc00109.h.cncssr.chinacache.net. 120 IN A 113.207.33.15
    cc00109.h.cncssr.chinacache.net. 120 IN A 113.207.33.12
    cc00109.h.cncssr.chinacache.net. 120 IN A 202.110.80.14
    cc00109.h.cncssr.chinacache.net. 120 IN A 61.179.105.154
    cc00109.h.cncssr.chinacache.net. 120 IN A 61.179.105.7
    cc00109.h.cncssr.chinacache.net. 120 IN A 119.188.138.172
    cc00109.h.cncssr.chinacache.net. 120 IN A 120.192.248.195
    cc00109.h.cncssr.chinacache.net. 120 IN A 221.181.39.76

    ;; Query time: 233 msec
    ;; SERVER: 127.0.0.1#53(127.0.0.1)
    ;; WHEN: Thu Apr 28 00:34:02 CST 2016
    ;; MSG SIZE rcvd: 387

    走国内 CDN 了吧~

    重启相关服务,更改自己所用的 DNS 地址,完事儿收工(「・ω・)「

    === 2016-04-30 14:00 更新 ===

    如果需要 edns-client-subnet 支持的话,需要手动编译源码安装。命令

    1
    2
    3
    4
    # 克隆源码
    svn co http://unbound.nlnetlabs.nl/svn/branches/edns-subnet/
    # 编译安装
    ./configure --enable-subnet --with-libevent && make && sudo make install

    配置文件的格式

    1
    2
    # 默认向所有服务器发送 edns-client-subnet
    send-client-subnet: 0.0.0.0/0

    如果只对特定权威 DNS 发送 edns-client-subnet 请求,则按照此格式写多行 IP。



沪ICP备19023445号-2号
友情链接