macOSローカルにUnboundでDNSキャッシュサーバを構築する

割と特殊な内容かなと思うので、やるなら自己責任でお願いします…。

LAN内部にUnboundサーバを構築する記事は書いたが、クライアント内部にも同様にUnboundサーバを抱えさせれば、より高速に名前解決できるかなと思い、macOS上にUnboundを構築してみた。(つまるところ、UnboundによるDNSスタブリゾルバの構築)

とはいえ、対応自体は以下記事に沿って進めれば良い。個人的なメモとして、本記事を残しておく。

Unbound DNS server on macOS
Below is a small tutorial on how you can create your own recursive DNS server using Unbound, adding custom records to block ads (plus fakenews, porn and/or social websites), on Apple macOS.

まずは、Homebrewでunboundパッケージを入れる。

$ brew install unbound

次に、Unboundを稼働させるグループ・ユーザを作成する。以下コマンドで、あらかじめGroupIDに重複がないよう配慮する。指定する数値は任意。

$ dscl . -list /Groups PrimaryGroupID | grep 444
$ dscl . -list /Users PrimaryGroupID | grep 444

重複していないことを確認できたら、以下を順に実行し、ユーザとグループを作成する。

# dscl . -create /Groups/_unbound
# dscl . -create /Groups/_unbound PrimaryGroupID 444
# dscl . -create /Users/_unbound
# dscl . -create /Users/_unbound RecordName _unbound unbound
# dscl . -create /Users/_unbound RealName  "Unbound DNS server"
# dscl . -create /Users/_unbound UniqueID 444
# dscl . -create /Users/_unbound PrimaryGroupID 444
# dscl . -create /Users/_unbound UserShell /usr/bin/false
# dscl . -create /Users/_unbound Password '*'
# dscl . -create /Groups/_unbound GroupMembership _unbound

DNSSEC検証に用いるroot keyを得る。ただ、DNSフォワーダとかDNSスタブリゾルバとして、自身で反復問い合わせしないのであれば、多分要らない…。

# unbound-anchor -a /usr/local/etc/unbound/root.key

Unbound controlで必要となる証明書を作る。

# unbound-control-setup -d /usr/local/etc/unbound

/usr/local/etc/unbound/unbound.conf を自分好みに編集して、Unboundを設定する。僕の環境では、LAN内部に別のUnboundサーバを構築したので、キャッシュにヒットしなかったらそちらにフォワードさせる形にした。

server:
	verbosity: 0 # エラー以外はログに出さない
	chroot: ""
	username: "_unbound"
    # フルサービスリゾルバとして構築しないので、DNSSEC検証用のroot keyは導入しない
	#auto-trust-anchor-file: "/usr/local/etc/unbound/root.key"
	port: 53
	num-threads: 2 # CPUコア数と同数にする
	interface: 127.0.0.1 # 自身からのみ接続を受け付ける
	outgoing-range: 462 # 1024/cores - 50
	num-queries-per-thread: 231 # outgoing-range / 2
	so-reuseport: yes
	msg-cache-size: 512m # キャッシュサイズはお好みで
	msg-cache-slabs: 2 # slabs系は、num-threadsに近しい2の累乗にする
	rrset-cache-size: 1g # msg-cache-sizeの2倍にする
	rrset-cache-slabs: 2 # slabs系は、num-threadsに近しい2の累乗にする
	infra-cache-slabs: 2 # slabs系は、num-threadsに近しい2の累乗にする
	do-ip4: yes
	do-ip6: no # 契約しているISPがIPv6アドレスも払い出しているなら、yesにする
	do-udp: yes
	do-tcp: yes
	access-control: 0.0.0.0/0 refuse # Allow Listにしたいので、まずは全て拒否
	access-control: 127.0.0.0/8 allow # 自分自身からのアクセスを許可する
    # フルサービスリゾルバとしてUnboundを構築したいなら、ArchWiki等を参考にInterNICからnamed.cacheを取得し、Root hintsとして設定する
	#root-hints: "/usr/local/etc/unbound/root.hints"
	hide-identity: yes
	hide-version: yes
	cache-min-ttl: 3600
	prefetch: yes
	key-cache-size: 512m # キャッシュサイズはお好みで
	key-cache-slabs: 2 # slabs系は、num-threadsに近しい2の累乗にする
	neg-cache-size: 512m # キャッシュサイズはお好みで
	minimal-responses: yes
	rrset-roundrobin: yes
remote-control:
	control-enable: yes
	control-interface: 127.0.0.1
	server-key-file: "/usr/local/etc/unbound/unbound_server.key"
	server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
	control-key-file: "/usr/local/etc/unbound/unbound_control.key"
	control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
forward-zone:
    # LANにUnboundを建てているので、キャッシュヒットしなければ、そっちにフォワードさせる
	name:  "."
	forward-addr: 192.168.1.3

Unboundディレクトリのユーザ・グループを指定し、設定ファイル等を読めるようにする。

# chown -R _unbound:staff /usr/local/etc/unbound
# chmod 640 /usr/local/etc/unbound/*

macOSの起動時にUnboundも開始させたいので、LaunchDaemonsのplistを /Library/LaunchDaemons/net.unbound.plist で作成する。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>net.unbound</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/sbin/unbound</string>
            <string>-d</string>
            <string>-c</string>
            <string>/usr/local/etc/unbound/unbound.conf</string>
        </array>
        <key>KeepAlive</key>
        <true/>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>

以上でUnboundを用いるための準備ができた。念のため、設定ファイルを適切に作成できているかを以下で確認する。

$ unbound-checkconf /usr/local/etc/unbound/unbound.conf

no errors in ... のように返されたらOK。エラーが返されたなら、その内容を読んで、typoしてないか等を確認する。

問題無さそうなら、以下でUnboundを起動する。

# launchctl load /Library/LaunchDaemons/net.unbound.plist

もしUnboundを停止させたいなら、以下を実行する。

# launchctl unload /Library/LaunchDaemons/net.unbound.plist

稼働しているかは、実際に問い合わせてみれば良い。

$ dig www.google.com @127.0.0.1

動作問題無さそうなら、 macOSのシステム環境設定 / ネットワークにて、DNSサーバに127.0.0.1を指定する。

参考

Unbound DNS server on macOS
Below is a small tutorial on how you can create your own recursive DNS server using Unbound, adding custom records to block ads (plus fakenews, porn and/or social websites), on Apple macOS.
Unbound - ArchWiki
Performance Tuning — Unbound 1.14.0 documentation
DNSキャッシュサーバ チューニングの勘所
BIND9部分を公開しました。いくつか加筆修正しVer1.1になりました。