わが家のネットワークには、スマートフォン、タブレット、クライアントPC、およびサーバマシンを含めて10台を超える端末が接続されています。

数が多いので、端末へのアクセスにIPアドレスを用いるのはめんどうです。覚えきれません。そこで、マシン名(ホスト名)とIPアドレスの対応づけを管理するために、家庭内ネットワーク専用のDNS (Domain Name System)サーバを、オープンソース・ソフトウェアであるBINDを用いて構築、運用しています。

これまでずっと、おもにホスト名とIPアドレスとの対応づけを管理する「権威DNSサーバ機能」と、主としてインターネット上のサービスにアクセスする際に、ホスト名からIPアドレスを解決するための「キャッシュDNSサーバ機能」を、単一のBINDサーバに同居させてきました。

しかしながら、権威DNSサーバとキャッシュDNSサーバの機能をひとつのサーバで兼ねることは、おもにセキュリティの観点から、よくないプラクティスであることが広く知られています。

家庭内LANでしか使わず、インターネットからはアクセスできないサーバなので、問題があることがわかっていながら放置していました。

ところで、先日の記事で、次期Android PからはDNS over TLSがサポートされること、およびセキュアなDNSサービスを提供するAndroidアプリであるIntraを紹介しました。

DNS over TLSではその名のとおり、ホスト名からIPアドレスの解決を行なう際、UDPあるいはTCPの代わりにTLS (Transport Layer Security)というセキュアなプロトコルをトランスポートとして使用します。TLSを用いることで、盗聴や改ざんといったセキュリティ上の脅威からDNS通信を守ることができます。

この機会に、家庭内LANのDNSサーバをDNS over TLSに対応させることにしました。ポイントは以下の三つです。

三つのポイントをまとめたブロック図を以下に示します。

Unbound - DNSSEC + DNS over TLS

あらたに構築するキャッシュサーバには、BINDの代わりにUnboundというオープンソース・ソフトウェアを用いることにしました。

以下、本記事ではFreeBSD上に、Unboundを用いたDNSSEC & DNS over TLS対応のキャッシュサーバを構築する手順について説明します。構築にあたっては、以下の二つの記事を参考にしました。

Unboundのインストール

まずは、必要なパッケージのインストールからです。

: FreeBSDのベースシステムには、すでにunboundが含まれています(FreeBSD 11.2-RELEASEにはunbound 1.5.10が同梱)。しかし、本バージョンはDNS over TLSに未対応のようですので、パッケージからunbound 1.7.3 (2018年7月23日現在)をインストールすることにします。

pkg install unbound ca_root_nss

unboundパッケージに加えて、ca_root_nssパッケージもインストールします。ca_root_nssパッケージはルート証明機関の証明書(ルート証明書)をひとまとめにしたもので、unboundがパブリックDNSサーバを認証するときに必要となります。

Unboundの設定

unboundパッケージをインストールすると、サンプルの設定ファイル(unbound.conf.sample)が/usr/local/etc/unbound以下に配置されます。本サンプルをコピーして、上に挙げた二つのサイトも参考にしながら、必要に応じて内容を変更していきます。

cp /usr/local/etc/unbound/unbound.conf.sample /usr/local/etc/unbound/unbound.conf

では、設定ファイルの主要な部分を見ていきましょう。(以下の例ではセクションごとに設定ファイルを分け、計四つのファイルを作成しています。ファイルの分割は任意ですので、お好みにあわせて単一の設定ファイルにまとめてもかまいません。この場合、設定ファイルはunbound.confにまとめます。)

完全な設定ファイルを以下のGitHubリポジトリに置いてありますので、必要に応じてご参照ください。

自動起動の設定

最後に、FreeBSDの起動時にunboundも自動的に起動されるよう設定しておきましょう。

sysrc unbound_enable=YES

設定ができたらFreeBSDマシンを再起動、あるいは以下のコマンドを実行してunboundを起動します。

service unbound start

動作確認

ようやくunboundサーバを起動できました。さっそく、正しく名前解決ができるかを確認してみましょう。以下の例では、www.nic.ad.jpというホスト名(ドメイン名)に対応するAレコード(IPアドレス)の解決を試みています。

確認ポイントは以下のとおりです。

: DNSSECに対応していないドメインについては、コマンドの実行結果についての後ろ二者(flagsおよびANSWER SECTIONのRRSIGに関する確認)は適用外となります。

$ drill -D www.nic.ad.jp. A @192.168.0.1
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 10041
;; flags: qr rd ra ad ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 
;; QUESTION SECTION:
;; www.nic.ad.jp.       IN      A

;; ANSWER SECTION:
www.nic.ad.jp.  269     IN      A       192.41.192.145
www.nic.ad.jp.  269     IN      RRSIG   A 8 4 300 20181018010414 20180720010414 34431 nic.ad.jp. qcrwMmDJb9mZjusNAZ8nQk4Oq6C/N7me9Skvmso1vhtW0YMObCa2+C+MD/6koAljbeHAGpA4u5BzvEPflPmzvqhSMP8jv+4dUYc5Gghkor5GPcgsBPyoz870oJ9De7BRJZke4vfpzDE4+bcbzAaQ998/XUDKVcUv3GPctIJlRdVCwkNoxKsksmAAuHM9sNTuPhr4Sd08wmtqxEFJViRlpbH4CDBP329TkQq4JEiw3eVvr4tpoMgjaDLgUF54CIS/M21FzWyn1xOeq4K0lyPl8qYDbqTaN9rycaTxnqd4XdhJDXIbP923oGrOZqO61yx3HTyk588MtvSEF3oUWBeDvA==

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 1 msec
;; EDNS: version 0; flags: do ; udp: 4096
;; SERVER: 192.168.0.1
;; WHEN: Sun Jul 22 19:16:12 2018
;; MSG SIZE  rcvd: 355

クライアントの設定

最後に、今回構築したキャッシュDNSサーバを使用するように、クライアント側の設定についても見直しておきましょう。DNSクライアントの設定ファイルは一般的に/etc/resolv.confです。nameserverのアドレスをキャッシュDNSサーバのアドレスに指定しておきましょう。