Unbound
Unbound 是一个具有验证,递归和缓存等功能的 DNS 解析器。根据Wikipedia:
- Unbound has supplanted the Berkeley Internet Name Domain (BIND) as the default, base-system name server in several open source projects, where it is perceived as smaller, more modern, and more secure for most applications.
安装[编辑 | 编辑源代码]
安装 unbound包 软件包。 此外, expat包 是使用DNSSEC验证请求所必须的。
配置[编辑 | 编辑源代码]
默认配置已经位于/etc/unbound/unbound.conf
文件中。此外,/etc/unbound/unbound.conf.example
文件包含了其他的可配置设置项,并以注释的形式给出了示范设置。以下章节重点解释和默认配置文件不同的设置项。如需了解更多细节,参见unbound.conf(5)。
除非特别声明,这一节列出的选项都是放置在配置文件的server
节中,类似这样:
/etc/unbound/unbound.conf
server: ... setting: value ...
do-daemonize: no
,否则unbound.service
会无法启动.本地DNS服务器[编辑 | 编辑源代码]
如果你想要使用unbound作为本地DNS服务器,请把resolv.conf中的域名服务器(nameserver)设置到回环地址::1
和127.0.0.1
。你可能想要让你的配置Domain name resolution#覆盖 /etc/resolv.conf。
/etc/resolvconf.conf
中包含name_servers="::1 127.0.0.1"
的那一行的注释。然后运行resolvconf -u
来重新生成/etc/resolv.conf
。要了解如何测试设置项,参见Domain name resolution#Lookup utilities。
在把resolv.conf中的设置更改为持久化设置后,请特别注意检查正在使用的服务器是::1
或127.0.0.1
。
你还需要对“unbound”进行设置,以使它#转发查询到你所选择的DNS服务器。
访问控制[编辑 | 编辑源代码]
你可以通过IP地址来指定响应请求的端口。默认监听的是localhost。
为了在所有端口上监听,使用以下配置:
interface: 0.0.0.0
为了通过IP地址来控制可以访问服务器的系统,使用access-control
选项:
access-control: subnet action
例如:
access-control: 192.168.1.0/24 allow
action可以是deny
(drop message), refuse
(polite error reply), allow
(recursive ok), or allow_snoop
(recursive and nonrecursive ok)中的任意一个。默认除了localhost之外的所有东西都会被拒绝。
使用DNS over TLS进行转发[编辑 | 编辑源代码]
为了使用这个功能,你需要设置tls-cert-bundle
选项来指定本地系统的根证书认证包,以使得unbound可以转发TLS请求并指定允许DNS over TLS的服务器数量。
对每个服务器你都需要用 @ 来指定连接的端口,同时你也要用 # 来指明它的域名是什么。虽然它看起来像注释,the hashtag name allows for the TLS authentication name to be set for stub-zones and with unbound-control forward control
command。在 @ 和 # 之间不应该有空格。
/etc/unbound/unbound.conf
... server: ... tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt ... forward-zone: name: "." forward-tls-upstream: yes forward-addr: 1.1.1.1@853#cloudflare-dns.com
根域名服务器[编辑 | 编辑源代码]
为了查询一个没有被缓存成地址的主机,解释器需要从服务器树的根开始、对根服务器进行请求来知道去哪里找到目标地址的顶级域名。Unbound内置了一些根节点,但是推荐你提供一个根节点文件给它以免内置的过于老旧。
首先,告诉unbound使用root.hints
文件:
root-hints: root.hints
然后把你的root hints文件放进unbound的配置文件夹。实现这个目标最简单的方法是运行下面的命令:
# curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
建议每六个月更新一次root.hints
来保持根服务器列表是最新的。你可以手动完成这个任务,也可以使用Systemd/Timers。详情参见#根域名服务器与systemd timer。
DNSSEC验证[编辑 | 编辑源代码]
为了使用DNSSEC验证,你需要在server:
节中添加以下设置来告诉unbound服务器根证书文件的位置:
/etc/unbound/unbound.conf
trust-anchor-file: trusted-key.key
/etc/unbound/trusted-key.key
是从依赖项dnssec-anchors包所提供的的/etc/trusted-key.key
复制而来的,它的PKGBUILD按照unbound-anchor(8)生成了/etc/trusted-key.key
。
如果总的#转发查询设置到了不支持DNSSEC的DNS服务器,那么请确保已经把这些DNS服务器注释掉,否则DNS请求会失败。DNSSEC验证只会在被请求的DNS服务器支持它的时候成功完成。
测试DNSSEC[编辑 | 编辑源代码]
为了测试DNSSEC是否工作,在starting unbound.service
之后:
$ unbound-host -C /etc/unbound/unbound.conf -v sigok.verteiltesysteme.net
得到的回应应该是附带(secure)
字样的ip地址。
$ unbound-host -C /etc/unbound/unbound.conf -v sigfail.verteiltesysteme.net
这次的回应应该包含(BOGUS (security failure))
字样。
另外你也可以使用“drill”来测试:
$ drill sigok.verteiltesysteme.net $ drill sigfail.verteiltesysteme.net
第一个命令应该返回NOERROR
的rcode
;而第二个命令应该返回SERVFAIL
的rcode
。
转发查询[编辑 | 编辑源代码]
如果你只想转发请求到外部的DNS服务器,请跳到#转发所有其余的请求。
允许本地网络使用DNS[编辑 | 编辑源代码]
使用openresolv[编辑 | 编辑源代码]
如果你的网络管理器支持openresolv,你可以通过设置来使它提供本地DNS服务器、使用unbound来查询域名。 [2]
/etc/resolvconf.conf
... private_interfaces="*" # Write out unbound configuration file unbound_conf=/etc/unbound/resolvconf.conf
运行resolvconf -u
来生成文件。
配置unbound读取openresolv生成的文件并允许回应private IP address ranges:
/etc/unbound/unbound.conf
include: "/etc/unbound/resolvconf.conf" ... server: ... private-domain: "intranet" private-domain: "internal" private-domain: "private" private-domain: "corp" private-domain: "home" private-domain: "lan" unblock-lan-zones: yes insecure-lan-zones: yes ...
另外你可能想要对私有DNS域名空间禁用DNSSEC[3]:
/etc/unbound/unbound.conf
... server: ... domain-insecure: "intranet" domain-insecure: "internal" domain-insecure: "private" domain-insecure: "corp" domain-insecure: "home" domain-insecure: "lan" ...
手动指定DNS服务器[编辑 | 编辑源代码]
如果你有一个需要DNS请求的本地网络,同时你想要把请求都转发给一个本地的DNS服务器,那么你需要添加这一行:
private-address: 本地子网/子网掩码
例如:
private-address: 10.0.0.0/24
包含本地DNS服务器[编辑 | 编辑源代码]
为了包含一个本地DNS服务器,以用于转发和反代本地地址,类似下面的一组配置是必要的(请把下面的10.0.0.1替换为本地网络中提供DNS服务的服务器的地址):
local-zone: "10.in-addr.arpa." transparent
上面这一行对于让反向查询正常工作是非常重要的。
forward-zone: name: "mynetwork.com." forward-addr: 10.0.0.1 forward-zone: local-data: "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost."
你可以通过下面的配置来设定localhost的前向和反向查询:
local-zone: "localhost." static local-data: "localhost. 10800 IN NS localhost." local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" local-data: "localhost. 10800 IN A 127.0.0.1" local-zone: "127.in-addr.arpa." static local-data: "127.in-addr.arpa. 10800 IN NS localhost." local-data: "127.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 2 3600 1200 604800 10800" local-data: "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost."
转发所有其余的请求[编辑 | 编辑源代码]
使用openresolv[编辑 | 编辑源代码]
如果你的网络管理器支持openresolv,你可以通过配置使它提供上游DNS服务器给unbound。 [4]
/etc/resolvconf.conf
... # Write out unbound configuration file unbound_conf=/etc/unbound/resolvconf.conf
运行resolvconf -u
来生成文件。
最后配置unound读取openresolv生成的文件:
include: "/etc/unbound/resolvconf.conf"
手动指定DNS服务器[编辑 | 编辑源代码]
为了使本地机器之外的、本地网络外部的默认转发区域使用指定的服务器,请在配置文件中添加一个名字是.
的转发区域。在这个例子里,所有的请求都被转发到谷歌的DNS服务器:
forward-zone: name: "." forward-addr: 8.8.8.8 forward-addr: 8.8.4.4
使用[编辑 | 编辑源代码]
启动unbound[编辑 | 编辑源代码]
Start/enable unbound.service
systemd服务。
远程控制unbound[编辑 | 编辑源代码]
unbound安装的时候自带了unbound-control
工具,利用这个工具我们可以远程控制unbound服务器。它和pdnsd包的pdnsd-ctl命令很类似。
配置unbound-control[编辑 | 编辑源代码]
在能够使用它之前你需要做下面的事情:
1) 首先,运行:
# unbound-control-setup
来为你的服务器和客户端生成一个self-signed的证书和private key。生成的文件位于/etc/unbound
文件夹。
2) 然后,把下面的内容放进/etc/unbound/unbound.conf
文件。control-enable: yes
是一定要有的,其余的内容可以按照所需进行调整。
remote-control: # Enable remote control with unbound-control(8) here. # 用unbound-control-setup生成的keys and certificates进行配置。 control-enable: yes # 设定监听哪个地址. # give 0.0.0.0 and ::0 to listen to all interfaces. control-interface: 127.0.0.1 # 远程控制用的端口. control-port: 8953 # unbound server key file. server-key-file: "/etc/unbound/unbound_server.key" # unbound server certificate file. server-cert-file: "/etc/unbound/unbound_server.pem" # unbound-control key file. control-key-file: "/etc/unbound/unbound_control.key" # unbound-control certificate file. control-cert-file: "/etc/unbound/unbound_control.pem"
使用unbound-control[编辑 | 编辑源代码]
下面是unbound-control可以使用的一部分命令:
- 不重置数据的情况下查看统计数据
# unbound-control stats_noreset
- 把cache dump到stdout
# unbound-control dump_cache
- 清空cache并且重新加载配置
# unbound-control reload
请参考unbound-control(8)来了解unbound-control支持的操作。
提示与技巧[编辑 | 编辑源代码]
域名黑名单[编辑 | 编辑源代码]
你可以打开这个网页adservers,把它的内容保存到/etc/unbound/adservers
,然后把下面的配置直接添加到unbound配置文件里就可以了:
/etc/unbound/unbound.conf
server: ... include: /etc/unbound/adservers
- 为了在查询这些hosts的时候返回OK状态指示,你可以更改默认的127.0.0.1重定向,改成重定向到你所控制的服务器并让那台服务器返回空的204回应,参考[5]
- 如果需要把其他格式的hosts文件转换成unbound的格式的,请运行这个命令:
$ grep '^0\.0\.0\.0' hostsfile | awk '{print "local-zone: \""$2"\" always_nxdomain"}' > /etc/unbound/adservers
添加一个authoritative DNS服务器[编辑 | 编辑源代码]
对于想要在一台机器上同时两个DNS服务器(一个是提供验证、递归、缓存功能的DNS服务器,另一个是authoritative DNS服务器)的用户来说,参考NSD的维基页面可能会有所帮助。那个页面提供了一个示范配置。一个服务器专门响应authoritative DNS请求,另一个服务器提供验证、递归、缓存等DNS功能,这样会比一个服务器提供所有功能会更安全。很多用户已经在使用Bind作为DNS服务器,而针对从Bind变成Bind和NSD协同工作的过程的帮助在NSD页面有提供。
WAN facing DNS[编辑 | 编辑源代码]
通过更改配置文件和服务器所监听的接口(地址)来允许来自本地网络之外的机器的DNS请求进入本地网络(LAN)内的某台特定机器,这个想法是可行的。这个功能对于公开的网站服务器和邮件服务器是非常有用的。这个在bind上已经实现了多年的技术,通过正确配置防火墙机器上的端口转发——转发这些请求到正确的机器上——也可以在unbound上实现。
根域名服务器与systemd timer[编辑 | 编辑源代码]
下面是一个systemd服务和timer的示例文件,它用来每隔一个月更新一次root.hints
,所用的方法与#根域名服务器中的相同:
/etc/systemd/system/roothints.service
[Unit] Description=Update root hints for unbound After=network.target [Service] ExecStart=/usr/bin/curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
/etc/systemd/system/roothints.timer
[Unit] Description=Run root.hints monthly [Timer] OnCalendar=monthly Persistent=true [Install] WantedBy=timers.target
最后Start/enable roothints.timer
systemd timer就可以了。
疑难解答[编辑 | 编辑源代码]
有关num-threads的问题[编辑 | 编辑源代码]
unbound.conf
的man page提到:
outgoing-range: <number> Number of ports to open. This number of file descriptors can be opened per thread.
网上的一些人建议num-threads
这个参数应该设置成你的CPU的核心数量。示范配置文件unbound.conf.example
里关于这个选项只有下面这两行:
# number of threads to create. 1 disables threading. # num-threads: 1
但是人为地把num-threads
提高到比1
就一定会造成unbound在启动的时候在log里写一个warning提示说exceeding the number of file descriptors。实际上对于大多数在小型网络或是单机上运行unbound的用户来说,通过让num-threads
超过1
来得到性能提升是徒劳的。如果你一定要这么做,那么请参考official documentation。下面这条经验法则应该对你有所帮助:
- Set
num-threads
equal to the number of CPU cores on the system. E.g. for 4 CPUs with 2 cores each, use 8.
把outgoing-range
设置得尽可能大,参考上面的链接来突破总数是1024
这个限制。这样就会使得unbound可以同时为更多客户端提供服务。1个核心设置950
,2个核心设置450
,四个核心设置200
。num-queries-per-thread
最好设置成outgoing-range
的一半。
因为outgoing-range
是有限制的,同时num-queries-per-thread
也因此受到了限制,所以最好在编译的时候带上libevent包,这样就不会有1024
限制了。如果你有一个高负荷DNS服务器使得你不得不这样编译,你需要从源码编译unbound而不是直接安装unbound包。