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包。