【DNS】ローカルネット内のサーバへの接続でIPアドレスを打たなくて良いようにする【Dnsmasq】

自宅ネットワーク内のRaspberryPiやNASにアクセスするのに毎回IPアドレスを打つのは面倒なので、DNSサーバを立ててホスト名で接続できるようにする。

つまり今までコンソールやブラウザで

```
$ ssh user@192.168.1.5

http://192.168.1.5/index.html
```

と書いていたのを

```
$ ssh user@nas

http://nas/index.html
```
と書けるようにする。

# DNS以外の選択肢
今回はDNSを使うが、ローカルネット内で名前解決をする方法はDNS以外にも存在する。主にmulticast DNSとLLMNRがあるが、いずれも

- 名前のリストを集約管理できない
- ネットワーク上のデバイスが対応しているとは限らない

という理由によりDNSを使うことにする。DNSはサーバを立てる必要がある代わりに名前の集約管理ができるし、なによりDNSが使えないデバイスなど皆無である。

# Dnsmasq
Dnsmasqは比較的小規模なローカルネットワークで使うことを想定したDNSサーバ兼DHCPサーバである。DHCPでIPアドレスの固定割り当てをした上で、DNSでローカルな名前の解決もできるというという優れものである。

# インストール
大体パッケージマネージャのリポジトリに入っている。私の環境なら

```console
$ sudo apt install dnsmasq
```

だった。

# 全般設定
このローカルネットワークのドメイン名を決める必要がある。私は自分で持っているドメイン名を使ったが、持ってないなら`hogehoge.local`のようにインターネットに存在するドメイン名と被らないように好きに決めれば良い（`local`だけでもいけるのかな？要確認）。ここで決めたドメイン名は名前解決時には基本的に省略できるので、実際に使うことはあまりないといえばない。

また、DHCPサーバを設定するにあたってデフォルトゲートウェイとインターネットのドメイン名を解決する上位DNSサーバのアドレスを把握している必要がある。

設定ファイルを編集する。私の環境では`/etc/dnsmasq.conf`だった。差分のみを以下に掲載するが、最低限必要な設定項目はこれより少ないかもしれないし、他の構成方法もあり得るのであくまで一例である。設定ファイルにはコメントで詳しく説明が書かれているので、それも読みながら設定して欲しい。

```diff_ini:/etc/dnsmasq.conf
@@ -16,9 +16,9 @@
 # these requests from bringing up the link unnecessarily.
 
 # Never forward plain names (without a dot or domain part)
-#domain-needed
+domain-needed
 # Never forward addresses in the non-routed address spaces.
-#bogus-priv
+bogus-priv
 
 # Uncomment these to enable DNSSEC validation and caching:
 # (Requires dnsmasq to be built with DNSSEC option.)
@@ -55,7 +55,7 @@
 # If you don't want dnsmasq to read /etc/resolv.conf or any other
 # file, getting its servers from this file instead (see below), then
 # uncomment this.
-#no-resolv
+no-resolv
 
 # If you don't want dnsmasq to poll /etc/resolv.conf or other resolv
 # files for changes and re-read them then uncomment this.
@@ -64,6 +64,8 @@
 # Add other name servers here, with domain specs if they are for
 # non-public domains.
 #server=/localnet/192.168.0.1
+server=192.168.1.1 # 上位DNSサーバ
+server=1.1.1.1 # 予備の上位DNSサーバをいくつでも指定可能

 # Example of routing PTR queries to nameservers: this will send all
 # address->name queries for 192.168.3/24 to nameserver 10.1.2.3
@@ -71,7 +73,7 @@
 
 # Add local-only domains here, queries in these domains are answered
 # from /etc/hosts or DHCP only.
-#local=/localnet/
+local=/hogehoge.local/ # ローカルネットのドメイン名
 
 # Add domains which you want to force to an IP address here.
 # The example below send any host in double-click.net to a local
@@ -151,7 +143,7 @@
 # 2) Sets the "domain" DHCP option thereby potentially setting the
 #    domain of all systems configured by DHCP
 # 3) Provides the domain part for "expand-hosts"
-#domain=thekelleys.org.uk
+domain=hogehoge.local # ローカルネットのドメイン名
 
 # Set a different domain for a particular subnet
 #domain=wireless.thekelleys.org.uk,192.168.2.0/24
@@ -164,7 +156,7 @@
 # a lease time. If you have more than one network, you will need to
 # repeat this for each network on which you want to supply DHCP
 # service.
-#dhcp-range=192.168.0.50,192.168.0.150,12h
+dhcp-range=192.168.1.50,192.168.1.150,12h # DHCPの有効化＆IPアドレス貸し出し範囲指定
 
 # This is an example of a DHCP range where the netmask is given. This
 # is needed for networks we reach the dnsmasq DHCP server via a relay
@@ -341,7 +333,7 @@
 #dhcp-option=3,1.2.3.4
 
 # Do the same thing, but using the option name
-#dhcp-option=option:router,1.2.3.4
+dhcp-option=option:router,192.168.1.1 # デフォルトゲートウェイ
 
 # Override the default route supplied by dnsmasq and send no default
 # route at all. Note that this only works for the options sent by
```



# 名前のリストの設定
先ほどの`/etc/dnsmasq.conf`に書いても良いのだが、私の環境では`/etc/dnsmasq.d/`ディレクトリ以下のファイルも設定ファイルとして読み込んでくれたので、名前の設定はそちらに書くことにする。

```ini:/etc/dnsmasq.d/hosts.conf
# MACアドレスが00:11:22:33:44:55のデバイスにDHCPでIPアドレス192.168.1.5を固定で割り当て、DNSでは名前nasで名前解決できるようにする
# DHCPのリース期限は24時間
dhcp-host=00:11:22:33:44:55,192.168.1.5,nas,24h
# 複数行書くことで複数のエントリを追加できる
dhcp-host=AA:BB:CC:DD:EE:FF,192.168.1.6,raspberrypi,24h
# DHCPを使わずに固定IPになっているホストに対してDNSでの名前を追加する
host-record=gateway.hogehoge.local,192.168.1.1
# DNSで名前の別名を作る
cname=www.hogehoge.local,raspberrypi.hogehoge.local
```

以上により以下の名前が設定される。
- nas -> 192.168.1.5
- raspberrypi -> 192.168.1.6
- gateway -> 192.168.1.1
- www -> raspberrypi -> 192.168.1.6

ちなみに上の例でもそうだが、`dhcp-host=`で固定割り当てするIPアドレスは前節で設定したDHCPのIPアドレス貸し出し範囲の外でも良い。

# 既存のDHCPサーバを止める
競合しないようにルータ等についている既存のDHCPサーバ機能を停止する。

# 起動
起動。

```console
$ sudo systemctl start dnsmasq
```

ブート時に自動起動するように設定。

```console
$ sudo systemctl enable dnsmasq
```

# 名前解決してみる
ローカルネット上のクライアントから名前解決を試す。DHCPで配信しているのでリース期限が切れるまで待つか再起動するなどして更新する必要がある。成功すれば以下のような名前で接続できる。

```console
$ ping nas
$ ping raspberrypi
$ ping gateway
$ ping www
```

ちなみにドメイン名をつけても動く。

```console
$ ping nas.hogehoge.local
$ ping raspberrypi.hogehoge.local
$ ping gateway.hogehoge.local
$ ping www.hogehoge.local
```

Linuxのsystemd-resolvedを使った環境のデフォルトではドメインをつけないと名前解決できない。その場合、ネットワークアダプタの`.network`ファイル（例：`/etc/systemd/network/20-wired.network`）に以下を追記する。

```ini
[DHCP]
UseDomains=yes
```