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