Unbound
関連記事
Unbound は検証をおこなったり再帰・キャッシュをする DNS リゾルバです。Wikipedia によると
- Unboundは、いくつかのオープンソースプロジェクトにおいて、Berkeley Internet Name Domain (BIND) をデフォルトのベースシステムのネームサーバーとして置き換えており、ほとんどのアプリケーションにおいて、より小さく、よりモダンで、より安全であると認識されています。
インストール
公式リポジトリ から unbound パッケージをインストールしてください。
さらに、DNSSEC 検証をするには expat パッケージが必要です。
設定
デフォルト設定は /etc/unbound/unbound.conf
に含まれています。さらに、他のオプションが使われているサンプル設定ファイルが /etc/unbound/unbound.conf.example
に存在します。以下のセクションでは様々な設定を説明します。詳しい設定は man unbound.conf
を見てください。
特に指定しない場合、以下のセクションで説明しているオプションは設定ファイルの server
セクションの下に記述してください:
/etc/unbound/unbound.conf
server: ... setting: value ...
ローカル DNS サーバー
ローカル DNS サーバーとして unbound を使いたい場合、resolv.conf でネームサーバーを ::1
と 127.0.0.1
に設定してください。
/etc/resolv.conf
nameserver ::1 nameserver 127.0.0.1 options trust-ad
ネームサーバーの設定が変更されないように設定する必要があります。
設定のテスト方法については Resolv.conf#Linux における DNS を読んでください。
resolv.conf に変更を加えた後に 127.0.0.1
が使用されていることを確認してください。
ルートヒント
アドレスがキャッシュされていないホストを問い合わせられた場合、リゾルバはサーバーツリーの一番上からルートサーバーに問い合わせて、アドレスを問い合わせることができるトップレベルドメインの場所を知る必要があります。Unbound にはデフォルトで hints が付属していますが、古くなっている可能性があるのでルートヒントファイルを使用することを推奨します。したがって、パッケージが定期的に更新されている場合、手動での介入は必要ありません。そうでない場合は、組み込みのヒントが古くなる可能性があるので、ルートヒントファイルを使用するのが良い方法です。
unbound に root.hints
ファイルを指定:
root-hints: root.hints
それからルートヒントファイルを unbound の設定ディレクトリに配置してください。以下のコマンドを実行するだけで配置できます:
# curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
ルートサーバーのリストを最新に保つために root.hints
は6ヶ月ごとに更新すると良いでしょう。手動で実行してもよいですし、Systemd/タイマーを使う方法もあります。タイマーを使う場合は#ルートヒント systemd タイマーを参照。
DNSSEC 検証
unbound は自動的にルートサーバーの信頼鍵アンカーファイルを /etc/trusted-key.key
から /etc/unbound/trusted-key.key
にコピーします。DNSSEC 検証を使用するには以下の文字列を追加して unbound にファイルを指定してください:
trust-anchor-file: trusted-key.key
DNS サーバーへの転送を設定した場合、上記をコメントアウトしてください。そうしないと、DNS クエリが失敗するようになります。DNS サーバーが対応している場合にのみ DNSSEC 検証が行われるようになります。
検証のテスト
DNSSEC が機能しているかどうかをテストするには、unbound.service
を起動後に次の手順を実行します。
$ unbound-host -C /etc/unbound/unbound.conf -v sigok.verteiltesysteme.net
応答は、IP アドレスの横に (secure)
という文字があるはずです。
$ unbound-host -C /etc/unbound/unbound.conf -v sigfail.verteiltesysteme.net
ここでは、(BOGUS (security failure))
を含む応答が必要です。
さらに、次のように drill を使ってリゾルバのテストをすることができます。
$ drill sigfail.verteiltesysteme.net $ drill sigok.verteiltesysteme.net
最初のコマンドの rcode
が SERVFAIL
に、2番目のコマンドの rcode
が NOERROR
になっていれば問題ありません。
クエリの転送
クエリを外部 DNS サーバーに転送するだけの場合は、#残りのリクエストをすべて転送する に進んでください。
ローカルネットワークに DNS の使用を許可する
openresolv の使用
ネットワーク管理者が openresolv をサポートしている場合は、設定 して、ローカル DNS サーバーと検索ドメインを Unbound に提供できます:
/etc/resolvconf.conf
... private_interfaces="*" # Write out unbound configuration file unbound_conf=/etc/unbound/resolvconf.conf
resolvconf -u
を実行してファイルを生成します。
openresolv の生成されたファイルを読み取り、プライベート IP アドレス範囲[1] での応答を許可するように Unbound を設定します。
/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 検証を無効にすることもできます (RFC 6762 Appendix G を参照)
/etc/unbound/unbound.conf
... server: ... domain-insecure: "intranet" domain-insecure: "internal" domain-insecure: "private" domain-insecure: "corp" domain-insecure: "home" domain-insecure: "lan" ...
ローカルサブネットを回答から除外する
DNS rebinding 攻撃から保護できるため、DNS 回答からローカルネットワークを除外すると便利です。デフォルトでは、この機能はアクティブではありませんが、設定ファイルに必要なサブネットを追加できます:
private-address: local_subnet/subnet_mask
次の文字列を使用して、すべての プライベートおよびリンクローカル サブネットを追加できます。
private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10
Unbound は、除外されたサブネットが private-domain
のドメインに属している場合、または local-data
で指定されている場合、回答に除外されたサブネットのアドレスを含む可能性があるため、private-domain
を定義する必要があることに注意してください。ローカルドメインアドレスをクエリできるようにする方法は #openresolv の使用 で説明されています。
ローカル DNS サーバーを含める
ローカル DNS サーバーを順方向ローカルアドレスと逆方向ローカルアドレスの両方に含めるには、順方向検索と逆方向検索で次のような一連の行が必要です (ローカルネットワークに DNS を提供するサーバーの IP アドレスを選択するには、ローカルネットワークの 10.0.0.1 を適宜変更してください) 以下の行):
local-zone: "10.in-addr.arpa." transparent
上のこの行は、逆引き参照を正しく機能させるために重要です。
forward-zone: name: "mynetwork.com." forward-addr: 10.0.0.1
forward-zone: name: "10.in-addr.arpa." forward-addr: 10.0.0.1
以下のようにすることでローカルホストの正引き・逆引きを設定できます:
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 に提供できます。
/etc/resolvconf.conf
... # Write out unbound configuration file unbound_conf=/etc/unbound/resolvconf.conf
resolvconf -u
を実行してファイルを生成します。
最後に、openresolv の生成されたファイル [2] を読み取るように Unbound を設定します。
include: "/etc/unbound/resolvconf.conf"
DNS サーバーを手動で指定する
ローカルマシンの外部およびローカルネットワークの外部にあるデフォルトの順方向ゾーンに特定のサーバーを使用するには、.
という名前の順方向ゾーンを設定ファイルに追加します。この例では、すべてのリクエストが Google の DNS サーバーに転送されます。
forward-zone: name: "." forward-addr: 8.8.8.8 forward-addr: 8.8.4.4
DNS over TLS を使用した転送
DNS over TLS を使用するには、tls-system-cert
オプションを有効にし、TLS リクエストの転送に unbound を許可し、DNS over TLS を許可するサーバーの数を指定する必要があります。
各サーバーについて、@
を使用して接続ポートを指定し、#
でそのドメイン名を指定する必要があります。ドメイン名は TLS 認証に必要であり、スタブゾーンを設定したり、ドメイン名を指定して unbound-control forward control
コマンドを使用したりすることもできます。 forward-addr
の仕様にはスペースを含めないでください。
/etc/unbound/unbound.conf
... server: ... tls-system-cert: yes ... forward-zone: name: "." forward-tls-upstream: yes forward-addr: 1.1.1.1@853#cloudflare-dns.com
アクセス制御
IP アドレスによってクエリに応答するインターフェイスを指定できます。localhost で listen するには、以下を使用:
interface: 127.0.0.1
全てのインターフェイスで listen するには、以下を使用:
interface: 0.0.0.0
access-control
オプションを使うことでさらに細かくアクセスを設定できます:
access-control: subnet action
例:
access-control: 192.168.1.0/24 allow
action に指定できるのは deny
(メッセージを破棄), refuse
(エラー応答), allow
(再帰を許可), allow_snoop
(再帰と非再帰を許可) です。デフォルトでは、ローカルホスト以外の全てが拒否されます。
使用方法
Unbound の起動
unbound.service
を起動・有効化してください。
Unbound の遠隔操作
unbound には unbound-control
ユーティリティが付いており、リモートの unbound サーバーを管理することができます。pdnsd の pdnsd-ctl コマンドに似ています。
unbound-control の設定
使用する前に、以下の設定が必要です:
1) まず、以下のコマンドを実行してください:
# unbound-control-setup
自己署名証明書とサーバーとクライアントの秘密鍵が生成されます。これらのファイルは /etc/unbound
ディレクトリに保存されます。
2) その後、/etc/unbound/unbound.conf
を編集して以下の内容を記述してください。control-enable: yes
オプションは必須ですが、他のオプションは必要に応じて変更できます。
remote-control: # Enable remote control with unbound-control(8) here. # set up the keys and certificates with unbound-control-setup. control-enable: yes # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. control-interface: 127.0.0.1 # port number for remote control operations. 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
- キャッシュを標準出力にダンプ
# unbound-control dump_cache
- キャッシュを消去して設定をリロード
# unbound-control reload
詳しくは man 8 unbound-control
を参照してください。
ヒントとテクニック
ブロック通知
adservers ファイルを作成して以下の設定を Unbound に追加してください:
/etc/unbound/unbound.conf
... include: /etc/unbound/adservers
権威 DNS サーバーの追加
検証・再帰・キャッシュ DNS サーバーと権威 DNS サーバーを同じマシンで動作させたい場合、NSD のページを参照してください。全ての機能を提供する DNS サーバーを動作させるより、権威サーバーとキャッシュサーバーを分けることでセキュリティを向上させることができます。NSD のページには BIND から移行する際に役立つ情報を載せています。
WAN と DNS
listen しているサーバーの設定ファイルやインターフェイスを変更することで、ローカルネットワーク外のマシンからのクエリから LAN 内の特定のマシンにアクセスできるように設定できます。どこからでもアクセスできるようにするウェブサーバーやメールサーバーなどで有用です。
ルートヒント systemd タイマー
以下は #ルートヒント に書かれている方法で root.hints
を1ヶ月ごとに更新する systemd サービスとタイマーの例です:
/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
roothints.timer
systemd タイマーを 起動・有効化してください。
DNS キャッシュを常に最新の状態に保つ
unbound は、キャッシュされた DNS エントリが期限切れになる前に自動的に更新され、キャッシュを常に最新の状態に保つプリフェッチをサポートしています。unbound.conf(5) のマニュアルページから引用、これをオンにすると、トラフィックとマシンの負荷が約 10% 増加しますが、需要のあるアイテムはキャッシュから期限切れになりません。これは、RTT が高いモバイルリンクで特に役立ちます。
プリフェッチを有効にするには、これを server
セクションの下に追加します:
prefetch: yes
トラブルシューティング
num-threads の問題
unbound.conf
の man ページより:
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 を起動したときにログにファイル記述子の数が多すぎるという警告が吐かれます。小規模なネットワークで Unbound を使っている場合、num-threads
を 1
より大きな値に設定して性能をあげようとしても無駄です。設定したい場合は 公式ドキュメント を参照してください。
outgoing-range
はできるだけ大きな値に設定してください。上記で参照しているウェブページのセクションには 1024
の制限を越える方法が書かれています。複数のクライアントを同時にさばくことが可能です。シングルコアなら 950
を、デュアルコアなら 450
を、クアッドコアなら 200
を試して下さい。num-queries-per-thread
は outgoing-range
の数字の半分に設定するのが最適です。
outgoing-range
の制限により num-queries-per-thread
も制限されるため、 outgoing-range
に {1024
制限がないように、 libevent でコンパイルすることをお薦めします。負荷の高い DNS サーバ用にこの方法でコンパイルする必要がある場合は、 unbound パッケージを使用する代わりに、ソースからプログラムをコンパイルする必要があります。