Unbound - Arch Linux 中文维基

跳至內容

# Unbound

出自 Arch Linux 中文维基
翻譯狀態：

- 本文（或部分內容）譯自 Unbound，最近一次同步於 2019-03-24，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- Domain name resolution

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。

提示：實現這個目的的一個簡便方法是安裝openresolv，然後取消文件`/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默認啟用.[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

第一個命令應該返回`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劫持攻擊。為了達到這個目的，你可能需要允許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伺服器。它和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伺服器更安全。 （在 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`，四個核心設置`200`。`num-queries-per-thread`最好設置成`outgoing-range`的一半。

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

## 參閱

- Fedora change to Unbound
- Block hosts that contain advertisements

分類：​

- DNS
- 使用「模板:過時」標記的頁面或章節

隱藏分類：​

- 使用「模板:準確性」標記的頁面或章節

Unbound
新增話題