Unbound

出自 Arch Linux 中文维基

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)設置到迴環地址::1127.0.0.1。你可能想要讓你的配置Domain name resolution#覆蓋 /etc/resolv.conf

提示:實現這個目的的一個簡便方法是安裝openresolv,然後取消文件/etc/resolvconf.conf中包含name_servers="::1 127.0.0.1"的那一行的註釋。然後運行resolvconf -u來重新生成/etc/resolv.conf

要了解如何測試設置項,參見Domain name resolution#Lookup utilities

在把resolv.conf中的設置更改為持久化設置後,請特別注意檢查正在使用的伺服器是::1127.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默認啟用.[1]. (在Talk:Unbound討論)

為了使用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,在地址被緩存之前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

第一個命令應該返回NOERRORrcode;而第二個命令應該返回SERVFAILrcode

轉發查詢[編輯 | 編輯原始碼]

如果你只想轉發請求到外部的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劫持攻擊。為了達到這個目的,你可能需要允許RFC1918網絡(10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 fd00::/8 fe80::/10)。 Unbound的未來版本可能會默認啟用這個功能。
包含本地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."
注意: 轉發空間和根空間之間的區別是,根空間只有在直接連接到一個authoritative DNS伺服器的時候才能正常工作。如果一個BINDDNS伺服器提供authoritative DNS,那麼這個特性對於來自於它的請求有用——但是如果你在把請求指向一個unbound伺服器(內部查詢都被轉發到另一個DNS伺服器),那麼把這個指向定義為該機器上的根空間是不會起作用的。在這種情況下,你必須把它定義為上面所說的轉發空間,因為轉發空間可以通過鏈式查詢去到別的DNS伺服器上,亦即轉發空間可以把請求指向遞歸DNS伺服器。這個區別是很重要的,因為如果你不恰當地使用根空間,你不會得到能夠說明問題的錯誤信息。

你可以通過下面的配置來設定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伺服器。它和pdnsdpdnsd-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伺服器更安全。 (在 Talk:Unbound 中討論)


對於想要在一台機器上同時兩個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,四個核心設置200num-queries-per-thread最好設置成outgoing-range的一半。

因為outgoing-range是有限制的,同時num-queries-per-thread也因此受到了限制,所以最好在編譯的時候帶上libevent,這樣就不會有1024限制了。如果你有一個高負荷DNS伺服器使得你不得不這樣編譯,你需要從源碼編譯unbound而不是直接安裝unbound

參閱[編輯 | 編輯原始碼]