工事現場備忘録

私の備忘録を私がどう書こうが私の自由であるとの信念に基づき自由に書いています

宅内向けにunbound使ってDoTで外部に問い合わせる良さげなDNSサーバを用意する

仮想マシンも増えてきて毎回IP手打ちは面倒くさいためbindで内部向けDNSサーバを立てていたけれどもunboundを使うともっといい感じになれると聞いた.
せっかくunboundへの移行をするのだからついでに外部にはDoT(DNS over TLS)を使って問い合わせるようにしてみたのでメモ.

環境

# cat /etc/redhat-release
Rocky Linux release 8.7 (Green Obsidian)

とりあえずインスコ

dnf update ca-certificates
dnf install unbound 
dnf info unbound --installed
インストール済みパッケージ
名前         : unbound
バージョン   : 1.16.2
リリース     : 2.el8
Arch         : x86_64
サイズ       : 5.9 M
ソース       : unbound-1.16.2-2.el8.src.rpm
リポジトリー : @System
repo から    : appstream
概要         : Validating, recursive, and caching DNS(SEC) resolver
URL          : https://www.unbound.net/
ライセンス   : BSD
説明         : Unbound is a validating, recursive, and caching DNS(SEC) resolver.
             :
             : The C implementation of Unbound is developed and maintained by NLnet
             : Labs. It is based on ideas and algorithms taken from a java prototype
             : developed by Verisign labs, Nominet, Kirei and ep.net.
             :
             : Unbound is designed as a set of modular components, so that also
             : DNSSEC (secure DNS) validation and stub-resolvers (that do not run
             : as a server, but are linked into an application) are easily possible.

ルート証明書更新するためにdnf update ca-certificatesをやっておく.unboundは2023/02/13に普通にdnfすると1.16.2を拾ってきた.別にこれで問題ないためこれで進める.(1.12以降でDoT・DoHに対応)

conf書く

/etc/unbound以下にunbound.confなんていかにもって感じのconfファイルがある.でもその中でconf.d以下の*.confをincludeするためそっちに書いたほうがいい.
なおconf.d以下は何もせずとも標準のunbound.confのままでincludeされる.そしてincludeするたびにincludeされるため自分でincludeを追加で書いたりすると設定が重複してエラーになる.

fatal error: interface: 0.0.0.0 present twice, cannot bind same ports twice.

とかはそれで出る.私はこれで2時間ほどハマった.ただのバカでは?
せっかくだし内容ごとに分離しておいて扱いやすいようにしておく.

main.conf
server:
    # 外部からアクセスできるように0.0.0.0を指定
    interface: 0.0.0.0
    #ipv4のみ
    do-ip4: yes
    do-ip6: no
    #tcpもudpも使う
    do-udp: yes
    do-tcp: yes

    # ローカルからの問い合わせを許可
    access-control: 0.0.0.0/0 refuse
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.1.0/24 allow

    # バージョンを知られないようにする?
    hide-version: yes
    hide-identity: yes

    # roothintを指定する
    #sudo curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
    root-hints: "/etc/unbound/root.hints"

    # ログファイルにログを出す
    logfile: "/var/log/unbound.log"
    use-syslog: no
    log-time-ascii: yes

メインのconfはこの程度で動くはず.
仮にこれを使うのであれば実行前にsudo curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cacheを実行してroot-hintsを用意する必要がある.あとcron.montlyとか使って定期的に更新するように.

ドメイン名.conf
server:
    local-zone: "kojigenba-srv.com." transparent

    # 末尾のドット忘れ注意
    local-data: "router.kojigenba-srv.com.      IN  A   192.168.1.1"

    # 逆引き
    local-data-ptr: "192.168.1.1    router.kojigenba-srv.com"

IP手打ちから逃れるためって意味ではメインのやつ.末尾のドット忘れに注意(2敗)

dns-over-tls.conf
server:
    tls-cert-bundle: "/etc/ssl/certs/ca-bundle.crt"
    tls-system-cert: yes

forward-zone:
    name: "."
    forward-tls-upstream: yes

    forward-addr: 1.1.1.1@853 # Cloudflare DoT
    forward-addr: 1.0.0.1@853 # Cloudflare DoT

    forward-addr: 8.8.8.8@853 # Google DoT
    forward-addr: 8.8.4.4@853 # Google DoT

    forward-addr: 103.2.57.5@853 # IIJ DoT
    forward-addr: 103.2.57.6@853 # IIJ DoT

forward-tls-upstream:yesにしておけばDoT使ってくれるっぽい.@以下はポート番号.DoHも同じように443で書けば使えるっぽい雰囲気を醸し出している.
IIJのを書いているけどIIJ Public DNSは2024/3/31までの提供のため注意.でもDoTとかDoHとかでの問い合わせにしか返してくれないらしいからテスト用にはちょうどいい.

大したリクエスト数ないだろうからパフォーマンスチューニングはサボりました.

動かす

conf一通り書いたら

# unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf

ってなることを確認.ならなかったら頑張って修正.
もしfatal error: server-key-file: "/etc/unbound/unbound_server.key" does not existみたいに~~.keyが無いって感じのエラーであれば

systemctl start unbound-keygen

で解決するかもしれない.unbound-keygenはunboundを起動すると勝手に起動するから途中で起動していれば出ない.
あとは普通に

systemctl enable unbound
systemctl start unbound

とかして動かす. ドメイン名.confに書いたとおりに接続できるか一応確認する.
DNSSECも標準で有効になってるはず.dig . SOA +dnssecでadフラグ立ってればおk.

# dig +dnssec whitehouse.gov

; <<>> DiG 9.11.36-RedHat-9.11.36-5.el8_7.2 <<>> +dnssec whitehouse.gov
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50176
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;whitehouse.gov.                        IN      A

;; ANSWER SECTION:
whitehouse.gov.         30      IN      A       192.0.66.168
whitehouse.gov.         30      IN      RRSIG   A 13 2 300 20230216100158 20230213090158 35095 whitehouse.gov. 09Zpl6ScSrwOwZ5vgC29UWWIMBFhHoIuc+z+I2SZE9UOqkoJyNFf/YBv MNWUbQdmudHXqSHPR0QZCacuLmDaRA==

;; Query time: 0 msec
;; SERVER: 192.168.1.4#53(192.168.1.4)
;; WHEN: 火  2月 14 00:08:46 JST 2023
;; MSG SIZE  rcvd: 169

flags: qr rd ra ad;でadが含まれているしRRSIGで署名も得られた.

# dig +dnssec dnssec-failed.org

; <<>> DiG 9.11.36-RedHat-9.11.36-5.el8_7.2 <<>> +dnssec dnssec-failed.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 18710
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;dnssec-failed.org.             IN      A

;; Query time: 0 msec
;; SERVER: 192.168.1.4#53(192.168.1.4)
;; WHEN: 火  2月 14 00:10:14 JST 2023
;; MSG SIZE  rcvd: 46

flagsにadがないしstatusがSERVFAILになっている.検証失敗はこうなる.
検証成功したり失敗したりしてるってことはDNSSECが仕事してるってことだろう,たぶん.

外への問い合わせについては前述のようにIIJ Public DNSはDoTとかDoHでの問い合わせにしか返してくれないらしいからここで確認しとけば大丈夫(かもしれない)
暗号化されてるか不安であれば

tcpdump -i enp1s0 port 853 and src host 192.168.1.4 -w test.pcap -v

とかしてパケットキャプチャしてwiresharkに突っ込んで中身を覗けばいい.ProtocolがDNSではなくTCPとかTLSとかになっていて内容が分からないようになっているはず.

その他どうでもいいこと

DoTとDoHだと何となくDoTはシステムとかが使ってDoHはブラウザとかが使う印象があったから今回はDoTで設定した.firefoxなんかはcloudflareのDoHを使う設定が存在してワンクリックでセットアップできてしまうけど自宅鯖にホスト名でアクセスできなくなるからダメだなぁになってしまう. 本来は途中で盗み見されるのこわいぴえん🥺であればISP提供のDNSを使っておけばいい.だからDoTとかDoHが必要なのはpublicDNSを使うとき.私はアパート付属回線で実態は光ファイバ一本を複数部屋で共有してるやつだしISP調べてもDNS鯖アドレス分からないし提供されてるのかもわからないし自動設定にするとアパート内で回線分割する装置に問い合わせしてて結局どこに問い合わせてるのかよく分からないしで悲しくなったからDoHとかDoTで遊ぶことにした.ただDoHとかDoTとかはpublicDNS側から見ると通常のDNSよりも多くの情報が手に入るはずだから一概にプライバシーが向上するとは言えない.そのへんはpublicDNS側の情報収集ポリシーを信じるしかないっぽい.私は気にしないことで解決しました.気にしないならDoTも必要ないのでは?