Unboundを使ってお手軽内向きDNSサーバーを構築する

2018年6月5日Linux TipsLinux, Ubuntu, Unbound, DNS

DNSサーバーというと「bind」が思い浮かぶが、bindは設定が複雑で正直さわりたくないものの代表格。そんなめんどくさい内向きのDNSを簡単に立てる方法が、Unboundを使用する方法。
dnsmasqという手もある。だが、dnsmasqは/etc/hostsを使うことで簡便になっている代わりに、NetworkManagerやら何やらが入り乱れている最近のLinux環境ではあまりよろしくなく、最近はセキュリティの問題も騒がれている。
なので、ある程度自由度があって簡単に設定出来るUnboundを今回は選択する。

内向きのDNSを作るメリット

例えば自宅の中にNASを構築していて、DDNS等で特定のドメインと紐付いているとする。
iPhoneにはこのドメインを指定して、NASにログインしている。外出先であれば、別にこれで困ることはない。しかし自宅の中にいるときでも、一度外部のDNSサーバーに名前解決の問い合わせをして戻ってくる……こんなアホらしいことはない。
また、自宅の中であれば、Safariに「nas」と打ち込めば、nasの画面が出てきて欲しい。まあそんなことを実現しようというわけだ。
もちろん、「nas.example.com」(example.comはローカルネットのドメイン)にアクセスしても問題がないし、「example.com」だけでアクセスしたらサーバーに飛ぶようにする。

Unboundをインストールする

apt-getで一発おわり。

$ sudo apt-get install unbound

unbound.confを設定する

設定するといっても非常に簡単である。どれくらい簡単かというと、dnsmasqよりもよっぽど簡単。しかも高機能。良いことしかない。

まず最初に、お手本となるconfig.confをコピーしてくる。ただし、Ubuntuではunbound.conf.dのなかのconfファイルを読み取る設定となっているので、このなかに「base.conf」としてコピー。

$ sudo cp /usr/share/doc/unbound/examples/unbound.conf /etc/unbound/unbound.conf.d/

そして、このファイルを編集していく。いじくったのは下記だけ。

server:
    verbosity: 1
    interface: 0.0.0.0
    access-control: 127.0.0.0/24 allow
    access-control: 192.168.11.0/24 allow
    local-data: "hue.example.com. IN A 192.168.11.4"
    local-data: "hue. IN A 192.168.11.4"
    local-data: "nas.example.com. IN A 192.168.11.138"
    local-data: "nas. IN A 192.168.11.138"
python:
remote-control:
forward-zone:
    name: "."
    forward-addr: 8.8.8.8
    forward-addr: 8.8.4.4

簡単に解説をすると、まずinterfaceを用いてデフォルトポートで受付。access-controlを用いてローカルネット以外からのアクセスを受け付けないようにしている。
その後、local-dataを用いて、「hue.example.com」などのFQDNや、ホスト名のみの「hue」に関して名前解決出来るように設定。
最後に、「forward-zone」を用いて自ら名前解決が出来ない場合にはGoogle DNSに投げる設定としている。

Unboundを再起動&自動起動設定

これもいつものやつです。

$ sudo service unbound restart
$ sudo systemctl enable unbound

動作を確認する

/etc/resolv.confが127.0.0.1となっていることを確認したのち、nslookupをしてみる。

$ slookup nas
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   nas
Address: 192.168.11.138

問題なく名前解決がされている。

NetworkManagerやInterfaces、resolvconf等のめんどくさいところを一応

ネットワーク関係はUbuntuのバージョンが変わる度に動作がちょっとずつ変わっていて非常に面倒。とくにDNSまわりは、何がresolv.confを制御しているのかどんどん分からなくなっている。

もし上記の設定でだめな場合は、下記を見直す必要がある。

NetworkManagerを使用している場合、dnsmasqをコメントアウトする

ここでひとつ注意。Ubuntuを使用していて、NetworkManagerを使用している場合には、NetworkManagerの設定で「dns=dnsmasq」となっている部分をコメントアウトする必要がある。というのも、NetworkManagerはDNSリゾルバとしてdnsmasqを標準で使用しており、このオプションがオンとなっているとdnsmasqと競合してUnboundが意図しない動作を引き起こしてしまうのである。
サーバーを構築する場合にNetworkManagerを使っているひとはあまりいないのではないかと思うが、要注意。

/etc/network/interfacesを利用している場合のDNS設定方法

Ubuntu 16.04では、resolv.confはresolvconfによって自動的に生成されていて、このresolvconfは/etc/network/interfacesのdns-nameserversオプションを見て作られている。
そして、このオプションが与えられている場合、/etc/resolv.confには常に「127.0.0.1」が与えられる。
何が言いたいかというと、/etc/network/interfacesを編集し、外部ネットワークに繋がっているものに関しては、明示的にdns-nameserversを指定してあげる必要がある。念のためではあるが。

auto enp0s31f6
iface enp0s31f6 inet static
address 192.168.11.2
netmask 255.255.255.0
gateway 192.168.11.1
dns-nameservers 8.8.8.8 8.8.4.4

NetworkManagerを使用している場合の上位のDNSサーバーの指定方法

NetworkManagerはresolvconfにDNS情報を流し、/etc/resolv.conf等を自動的に生成する(もちろん、interfacesなどは見ない)。
この設定を明示的に変更してあげる必要がある。つまり、第一のDNSサーバーとして自ドメインを設定し、次のサーバーとして外部のDNSサーバーを指定する。

実際に生成する際には、「/etc/resolvconf/resolv.conf.d/base」に書かれている情報をもととしている(デフォルトでは何も書かれていない)。
ここに、同様に下記のように設定をする。

nameserver 127.0.0.1
nameserver 8.8.8.8

上記を実施したら、resolv.confを再生成する。

$ sudo resolvconf -u

ルーターでの指定

ルーターでは、そのままこのサーバーのアドレスをDNSとして設定してあげれば良い。
また、ルーターで操作するのが恐ろしければ、クライアント端末単位で設定してあげても構わない。

私の場合、ルーターでいったん設定をおこなってみた。きちんとMacから名前解決が出来ていることを確認。

$ nslookup nas
Server:     192.168.11.2
Address:    192.168.11.2#53

Name:   nas
Address: 192.168.11.138

何がうれしいんだよ、という感じもするが、実はこのUnboundは他にも様々な機能を持っていて、キャッシュをしてくれたりもするようだ。まずはこんな機能から紹介をしたが、追って便利な機能があれば紹介をしたい。