やりたいこと
- 自宅のLAN内ではサーバやルータ等の複数のノードが稼働している
- 各ノードにはプライベートIPアドレスが静的に割り当てられている
- しかし、IPアドレスを覚えるのは面倒なため、LAN内で名前解決できる仕組みを取り入れたい
- e.g.
foo.internal
のような独自に定義したドメインと192.168.0.1
のようなプライベートIPアドレスを変換する
- e.g.
使用技術
Unbound
- OSSのDNSキャッシュサーバ
- 動作が高速で設定が簡単という特徴を持つ
- GitHub: https://github.com/NLnetLabs/unbound
- オランダのNLnet Labsが開発している
- NLnet Labsは他にもNSDやOpenDNSSECの開発も行っている
- ちなみに自宅での利用用途の場合、dnsmasqという選択肢もありそう
- 今回は、単に検証してみたかったという理由や、設定の容易さ、DNSフォワーダや簡易的なDNSコンテンツサーバとしての利用もしたかったことから選定
local-data
- Unboundは通常、DNSキャッシュサーバとして利用することが一般的
- しかし、Unboundのlocal-dataという機能を使用することで、擬似的にDNSコンテンツサーバのような振る舞いをさせることができる
- 手動でレコードを設定し、それを永続的なキャッシュとして保存する
- 本格的にDNSコンテンツサーバとしての機能を利用したい場合はNSDはBIND等を別途構築することが推奨される
ネットワーク構成
LAN内の名前解決
- クライアント(例えばラップトップ等)はLAN内でのみ有効なドメイン(
foo.internal
等)をUnboundに問い合わせ(正引き) - Unboundが自身で持つレコードを参照し(local-data)、
192.168.0.1
のようなプライベートIPアドレスに名前解決して応答 - クライアントは得られたプライベートIPアドレスに接続する
インターネット上の名前解決
- クライアントはUnboundにインターネット上で有効なドメイン(
example.com
等)を問い合わせ(正引き) - Unboundは自身で再帰問い合わせをせず、デフォルトゲートウェイが提供するDNSキャッシュサーバにフォワーディング
- つまり、インターネット上の名前解決に関しては、UnboundはDNSフォワーダとして振る舞う
- ちなみにフォワーディング先はGoogle Public DNS(
8.8.8.8
)等のパブリックDNSでも良い
- デフォルトゲートウェイが再帰問い合わせを行い、名前解決
- クライアントは得られたグローバルIPアドレスに接続する
Unboundの構築
- UnboundはUbuntu Server 22.04.2 LTS上に構築する
Unboundの設定
- Unboundのインストール
$ sudo apt install unbound -y
- コンフィグの作成
$ sudo vim /etc/unbound/unbound.conf.d/unbound.conf
unbound.conf
server:
# ログを出力するファイルの指定
logfile: "/var/log/unbound.log"
# ログ出力先にsyslogを使用するのをやめる
use-syslog: no
# エラーと操作情報のサマリを出力
verbosity: 1
# リクエストを受け付けるインタフェース
interface: 0.0.0.0
interface: ::0
# アクセスを許可するネットワーク
access-control: 0.0.0.0/0 refuse
access-control: ::0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: ::1 allow
access-control: 192.168.0.0/24 allow
access-control: 2001:XXXX:XXXX:XXXX::0/64 allow
# 内部向けのDNSコンテンツサーバ
local-data: "foo.internal. IN A 192.168.0.1"
local-data: "bar.internal. IN A 192.168.0.2"
local-data: "baz.internal. IN A 192.168.0.3"
# Unboundでは再帰問い合わせを行わない
forward-zone:
name: "."
forward-addr: 192.168.0.1
- コンフィグに誤りがないかをチェック(主にシンタックス周り)
$ unbound-checkconf unbound.conf
unbound-checkconf: no errors in unbound.conf
- Unboundを再起動し、コンフィグを反映
- しかし再起動に失敗する
$ sudo systemctl restart unbound
Job for unbound.service failed because the control process exited with error code.
See "systemctl status unbound.service" and "journalctl -xeu unbound.service" for details.
- どうやら53番ポートでsystemd-resolved(DNSスタブリゾルバ)が稼働している模様
$ sudo ss -lntp | grep 53
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=837,fd=14))
- systemd-resolvedのDNSスタブリゾルバとしての機能をオフにする
$ sudo vim /etc/systemd/resolved.conf
resolved.conf
[Resolve]
DNSStubListener=no
- systemd-resolvedの再起動
$ sudo systemctl restart systemd-resolved
- systemd-resolvedが正常に起動していることを確認
$ systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-03-14 22:38:36 UTC; 11s ago
Docs: man:systemd-resolved.service(8)
man:org.freedesktop.resolve1(5)
https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
Main PID: 11823 (systemd-resolve)
Status: "Processing requests..."
Tasks: 1 (limit: 2233)
Memory: 4.3M
CPU: 62ms
CGroup: /system.slice/systemd-resolved.service
└─11823 /lib/systemd/systemd-resolved
Mar 14 22:38:36 ubuntu-server systemd[1]: Starting Network Name Resolution...
Mar 14 22:38:36 ubuntu-server systemd-resolved[11823]: Positive Trust Anchors:
Mar 14 22:38:36 ubuntu-server systemd-resolved[11823]: . IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d
Mar 14 22:38:36 ubuntu-server systemd-resolved[11823]: Negative trust anchors: home.arpa 10.in-addr.arpa 16.172.in-addr.arpa 17.172.in-addr.arpa >
Mar 14 22:38:36 ubuntu-server systemd-resolved[11823]: Using system hostname 'ubuntu-server'.
Mar 14 22:38:36 ubuntu-server systemd[1]: Started Network Name Resolution.
- 53番ポートで何も稼働していないことを確認
$ sudo ss -lntp | grep 53
- 再度、Unboundを再起動し、コンフィグを反映
$ systemctl restart unbound
- Unboundが正常に起動していることを確認
$ systemctl status unbound
● unbound.service - Unbound DNS server
Loaded: loaded (/lib/systemd/system/unbound.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-03-14 23:14:29 UTC; 9s ago
Docs: man:unbound(8)
Process: 15902 ExecStartPre=/usr/lib/unbound/package-helper chroot_setup (code=exited, status=0/SUCCESS)
Process: 15905 ExecStartPre=/usr/lib/unbound/package-helper root_trust_anchor_update (code=exited, status=0/SUCCESS)
Main PID: 15908 (unbound)
Tasks: 1 (limit: 2233)
Memory: 7.0M
CPU: 60ms
CGroup: /system.slice/unbound.service
└─15908 /usr/sbin/unbound -d -p
Mar 14 23:14:29 ubuntu-server systemd[1]: Starting Unbound DNS server...
Mar 14 23:14:29 ubuntu-server unbound[15908]: [1678835669] unbound[15908:0] error: Could not open logfile /var/log/unbound.log: Permission denied
Mar 14 23:14:29 ubuntu-server unbound[15908]: [1678835669] unbound[15908:0] notice: init module 0: subnet
Mar 14 23:14:29 ubuntu-server unbound[15908]: [1678835669] unbound[15908:0] notice: init module 1: validator
Mar 14 23:14:29 ubuntu-server unbound[15908]: [1678835669] unbound[15908:0] notice: init module 2: iterator
Mar 14 23:14:29 ubuntu-server unbound[15908]: [1678835669] unbound[15908:0] info: start of service (unbound 1.13.1).
Mar 14 23:14:29 ubuntu-server systemd[1]: Started Unbound DNS server.
- 53番ポートでUnboundが稼働していることを確認
$ sudo ss -lntp | grep 53
[sudo] password for kazukichi:
LISTEN 0 256 0.0.0.0:53 0.0.0.0:* users:(("unbound",pid=15908,fd=4))
LISTEN 0 256 127.0.0.1:8953 0.0.0.0:* users:(("unbound",pid=15908,fd=8))
LISTEN 0 256 [::]:53 [::]:* users:(("unbound",pid=15908,fd=6))
LISTEN 0 256 [::1]:8953 [::]:* users:(("unbound",pid=15908,fd=7))
Unboundの動作確認
-
192.168.0.5
は今回、Unboundを構築したUbuntu Serverに設定されているIPアドレス - LAN内の名前解決
$ dig foo.internal @192.168.0.5
; <<>> DiG 9.10.6 <<>> foo.internal @192.168.0.5
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23706
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;foo.internal. IN A
;; ANSWER SECTION:
foo.internal. 3600 IN A 192.168.0.1
;; Query time: 11 msec
;; SERVER: 192.168.0.5#53(192.168.0.5)
;; WHEN: Thu Mar 16 05:05:59 JST 2023
;; MSG SIZE rcvd: 57
- インターネット上の名前解決
$ dig example.com @192.168.0.5
; <<>> DiG 9.10.6 <<>> example.com @192.168.0.5
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35119
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 50569 IN A 93.184.216.34
;; Query time: 3194 msec
;; SERVER: 192.168.0.5#53(192.168.0.5)
;; WHEN: Thu Mar 16 04:56:47 JST 2023
;; MSG SIZE rcvd: 56
- どちらも正常に動作していることが確認できる