第386回では、Unboundを使って家庭内DNSサーバーを構築しました。ですがこの記事から9年が経ち、Ubuntuのネットワークまわりも変化しました。当時とは状況も変わってきていますので、改めて最新のLTSである24.
家庭内DNSサーバーが必要な理由
DNSサーバには大きく分けて、ゾーン情報を管理するコンテンツサーバーと、名前解決を代行するキャッシュサーバーの二種類に分けられます。コンテンツサーバーは、そのドメインの名前情報を管理するサーバーで、インターネット全体に対してサービスを提供しなければなりません。そのため基本的に、ご家庭内には不要なサーバーです。
対してキャッシュサーバーは、どのご家庭にも存在します。通常、クライアントが直接、DNSのルートサーバーと通信することはありません。クライアントはキャッシュサーバーにリクエストを投げ、実際の名前解決はキャッシュサーバーがクライアントの代理として行います。今時のご家庭であれば、Wi-Fi機能を持ったルーターを設置して、インターネットに接続しているケースが多いでしょう。通常はこのルーターがキャッシュサーバーを兼ねており、OSのネットワーク設定では、使用するDNSサーバーとして、ルーターのIPアドレスが指定されているのが一般的です。

$ resolvectl dns Global: Link 2 (eno1): 192.168.1.1 Link 3 (enp3s0): Link 4 (wlp2s0):
今回紹介するUnboundは、Ubuntu上に構築するDNSキャッシュサーバーです。つまり現在利用している、ルーターのキャッシュサーバー機能を置き換えられるものとなります。
「でも、ルーターの機能で間に合うなら、そんなのいらないのでは?」
そう考える人もいるでしょう。ですが自由にいじれるLinux上にサーバーを構築するのには、それなりに便利な理由というものがあるのです。
クエリログが確認できる
キャッシュサーバーは、クライアントに代わって名前を解決します。そしてリクエストされたDNSクエリとその結果は、クエリログというログに残ります。つまりクエリログを見れば、いつ、誰が、どのドメインにアクセスしたのかがわかるわけです。内部がブラックボックスなスマホアプリであっても、DNSクエリを見れば、どのサイトと通信しているかがわかります。DNSクエリによって、不審なドメインと通信しているアプリを発見した、などという例もあります。パケットキャプチャをしなくても、通信しているサイトがわかるというのは、意外と便利なものなのです。
もちろん、ルーターのキャッシュサーバーでも、クエリログを見られたり、場合によってはSyslog転送に対応している機種もあるでしょう。ですがフル機能のLinuxサーバーであれば、データの保全や加工、集計、監視といった面においてアドバンテージがあります。特に企業においては、クエリログを保全しておくと、セキュリティ的にも役立つ日が来るかもしれません。
普段使いのドメインを家庭内でも使える
コンテンツサーバーはご家庭内には不要と言いましたが、ご家庭内でも名前解決をしたくなることがあります。特に家庭内サーバーを運用していると、IPアドレスではなくドメイン名でアクセスしたいですよね。Unboundは、ローカルなゾーンを持つことができます。本来であれば正規のコンテンツサーバーへ名前解決しに行く所を、このローカルなゾーン情報を元に応答を返せます。つまりこのゾーンにプライベートIPアドレスを登録すれば、家庭内のPCやサーバーに、好きな名前をつけられるのです。
もちろん、単にIPアドレスのかわりに名前を使いたいだけであれば、DNSサーバーは必要ありません。UbuntuではAvahiがインストールされていますので、mDNSによってホスト名からIPアドレスを引くことができます。ですがこの場合、mDNSの仕様によって、ドメイン部分が
またインターネット経由と家庭内とで、同じドメインを違うIPアドレスで運用したいような場合にも役立ちます。例えば家庭内でWebサービスを動かし、インターネットに公開しているとします。するとそのサービスのドメイン
特定のドメインをDNSレベルでブロックできる
世の中には、接続したくないドメインというものが存在します。例えば犯罪にかかわるサイトであったり、マルウェアを配布しているサイトであったりなどです。Unboundは、前述のローカルなゾーンの機能を使い、指定されたドメインの名前解決要求を拒否したり、常にNXDOMAIN
最近では
Unboundのインストール
それでは実際に、Unboundサーバーを構築してみましょう。Unboundはunboundパッケージでインストールできます。
$ sudo apt install -U -y unbound
インストールすると、自動的にUnboundが起動します。
$ sudo ss -lutnp Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process udp UNCONN 0 0 127.0.0.1:53 0.0.0.0:* users:(("unbound",pid=1416,fd=5)) udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=543,fd=16)) udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=543,fd=14)) udp UNCONN 0 0 [::1]:53 [::]:* users:(("unbound",pid=1416,fd=3)) tcp LISTEN 0 4096 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=543,fd=17)) tcp LISTEN 0 256 127.0.0.1:53 0.0.0.0:* users:(("unbound",pid=1416,fd=6)) tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=543,fd=15)) tcp LISTEN 0 256 [::1]:53 [::]:* users:(("unbound",pid=1416,fd=4)) (...略...)
ですが待ち受けているアドレスが127.
Unboundの設定
Unboundの設定ファイルは/etc/
属性: 値
属性の後には、別の属性も指定できます。これを
server:
verbosity: 1
interface: 192.168.1.5
port: 53
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/24 allow
デフォルトのunbound.
# Unbound configuration file for Debian.
#
# See the unbound.conf(5) man page.
#
# See /usr/share/doc/unbound/examples/unbound.conf for a commented
# reference config file.
#
# The following line includes additional configuration files from the
# /etc/unbound/unbound.conf.d directory.
include-toplevel: "/etc/unbound/unbound.conf.d/*.conf"
実は以前のUnboundでは、ここは以下のように設定されていました。
include: "/etc/unbound/unbound.conf.d/*.conf"
includeはその名の通り、他のファイルから設定を読み込むために使われます。これにより、適度な粒度で設定ファイルを分割し、可読性やメンテナンス性を上げることができるわけです。include-toplevelはより構造的な設定を可能にするincludeオプションです。include-toplevelが指定されると、現在アクティブな句がすべて閉じられ、インクルードされたファイル内、もしくはinclude-toplevelの直後で、句の使用が強制されます。つまり設定ファイルは句単位の粒度で区切り、/etc/
Unbound全体の設定ファイルとして、/etc/
server:
interface: 自分自身のIPアドレス
port: 53
access-control: 127.0.0.0/8 allow
access-control: LANのネットワークアドレス/サブネットマスク allow
use-syslog: yes
log-queries: yes
hide-version: yes
hide-identity: yes
forward-zone:
name: "."
forward-addr: フォワード先の(プロバイダが提供している)プライマリDNS
forward-addr: フォワード先の(プロバイダが提供している)セカンダリDNS
interfaceはUnboundが待ち受けに利用するIPアドレスです。ここではサーバーに指定されているプライベートIPアドレスを指定しました。現在のUbuntuでは、systemd-resolvedがスタブリゾルバとして127.
access-controlは、文字通りアクセスのコントロールです。ここでは自分自身と、LAN内のIPアドレスのレンジからのアクセスを
use-syslogはSyslogを使ってログを出力する設定です。
log-queriesはクエリログを出力する設定です。
hide-versionとhide-identityは、version.
forward-zone句には、Unboundがクエリをフォワードする設定を記述します。nameにはフォワードするゾーンの名前を指定します。ここでは
設定が完了したら、Unboundを再起動してください。これで、通常のキャッシュサーバーとして動作するようになりました。
$ sudo systemctl restart unbound.service
ログの設定
上記の設定でuse-syslogを有効にしました。Unboundがsyslogに出力するログファシリティはdaemonです。ですがUbuntuのデフォルト設定では、daemon.*ログは個別のログファイルに書かれず/var/
if $syslogfacility-text == 'daemon' and $programname contains 'unbound' then
-/var/log/unbound/unbound.log
& ~
これはログファシリティが
$ sudo systemctl restart rsyslog.service
実際にクライアントが名前解決のリクエストを投げると、
Oct 9 00:00:12 canopus unbound: [989:0] info: 192.168.1.100 mail.google.com. AAAA IN Oct 9 00:01:10 canopus unbound: [989:0] info: 192.168.1.4 api.mackerelio.com. AAAA IN Oct 9 00:01:10 canopus unbound: [989:0] info: 192.168.1.4 api.mackerelio.com. A IN Oct 9 00:01:14 canopus unbound: [989:0] info: 192.168.1.100 play.google.com. AAAA IN Oct 9 00:01:28 canopus unbound: [989:0] info: 192.168.1.102 cl4.apple.com. TYPE65 IN Oct 9 00:01:28 canopus unbound: [989:0] info: 192.168.1.102 cl4.apple.com. AAAA IN Oct 9 00:01:28 canopus unbound: [989:0] info: 192.168.1.102 cl4.apple.com. A IN Oct 9 00:01:33 canopus unbound: [989:0] info: 192.168.1.4 motd.ubuntu.com. A IN Oct 9 00:01:33 canopus unbound: [989:0] info: 192.168.1.4 motd.ubuntu.com. AAAA IN
クエリログは出力され続けますから、ディスクが枯渇しないよう、ログのローテートも設定しておきましょう。
/var/log/unbound/unbound.log
{
rotate 30
daily
copytruncate
nocompress
su root syslog
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
ここでは日次ローテートで、30世代分のログを保存する設定としました。このあたりは環境にあわせて変更してください。またログファイルが大きくなりがちな環境では、ログファイルの圧縮も行ったほうがいいかもしれません。
ローカルゾーンの設定
家庭内サーバーの名前解決ができるよう、ローカルゾーンを設定しましょう。ここでは例として、
まずローカルゾーンを定義する設定ファイルとして、
server:
local-zone: "example.com." transparent
local-data: "host1.example.com. 300 IN A 192.168.1.20"
local-data: "host2.example.com. 300 IN A 192.168.1.21"
server句の中に、local-zoneとして
local-dataは文字通り、ローカルなデータの設定です。ここではhost1とhost2というサーバーのプライベートIPアドレスを設定しています。
ローカルゾーンの設定ができたら、Unboundを再起動してください。local-dataに設定した名前解決ができることと、
特定ドメインのブロック
先ほどはexample.
server:
local-zone: "zip." refuse
refuseは、そのゾーンの名前解決要求に対して
これに対して
server:
local-zone: "example.net." always_nxdomain
このように、DNSサーバーを自前で構築することで、ご家庭のネットワークをちょっと便利に改善できるかもしれません。DNSサーバーはそれほどパワーが必要なサーバーではありませんから、ご家庭にいくつか余っているRaspberry Piなどで運用してみてはいかがでしょうか。