Ubuntu

Ubuntu22.04 BIND9 nxdomain-redirect

ホームラボで色々とサービスを構築していて、一部をインターネットに公開している。
外向きDNSサーバーはグローバルIPアドレスを回答してくれるようになっているが、宅内ではローカルのIPアドレスが欲しいので、内向きDNSサーバーがそれを回答している。

といった環境で、内向きDNSサーバーが解決できない問い合わせを受けたときに、外向きDNSサーバーに問い合わせることはできないか、と考えた。



広告


色々探してみて、nxdomain-redirectというオプションを発見したので、これを利用することにした。
今回やってみたところでは、

  • 内向きDNSサーバーが解決できない問い合わせを受けたときに、外向きDNSサーバーに問い合わせる。
    → できないことはないが、想定外の使い方のように思われる。
  • 内向きDNSサーバーが解決できない問い合わせを受けたときに、外向きDNSサーバーからゾーン転送してきた情報を参照する。
    → できる。

となった。

動作を試すにあたって、マニュアルを確認することはとても大事なので、メモ。
BIND 9 Configuration Reference

テストした環境

インターネットに都合よく使えるサーバーがないので、外向きDNSサーバー役を別ネットワークにあるexternalにやってもらう。
hogeserver.hogeddns.jpは架空のゾーンで、ホームラボでは名前解決ができるようになっている。

役割FQDN ※架空IPアドレス役割
外向きDNSサーバーexternal.hogeserver.hogeddns.jp172.31.1.254
※本来はグローバルIPアドレス
権威サーバー。
公開しているドメインについてだけ回答する。
内向きDNSサーバーaddc2.hogeserver.hogeddns.jp192.168.110.34権威サーバー、兼、キャッシュサーバー。
イントラネット内で展開するサービスについて、ローカルIPアドレスを回答する。

external.hogeserver.hogeddns.jp

Ubuntu 22.04 LTS serverをインストールして、BIND9をインストールした。
特筆すべき点なし。

addc2.hogeserver.hogeddns.jp

DockerでUbuntu 22.04をベースにしてSamba ad dcを立て、DNSバックエンドを内蔵のものからBIND9に変更したもの。
sudoコマンドもインストールしていないので、rootでコマンドを実行している。

# named -u bind         ← 起動
# named -v              ← バージョン確認
BIND 9.18.1-1ubuntu1.1-Ubuntu (Stable Release) <id:>
# rndc reload           ← 設定再読込
# rndc stop             ← 停止

これらはのコマンドは、普通にUbuntuとBIND9をインストールしたなら、以下に読み替える。

$ sudo systemctl start bind9
$ named -v
BIND 9.18.1-1ubuntu1.1-Ubuntu (Stable Release) <id:>
$ sudo systemctl reload bind9
$ sudo systemctl stop

テストするシナリオ

2つのDNSサーバーで、example.jpというゾーンを別々に管理して、以下の情報を返している、という設定。

URL ※架空外向きDNSサーバー内向きDNSサーバー備考
inter.example.jp172.31.1.10172.31.1.10クラウドサービスを利用している想定。
both.example.jp172.31.1.100192.168.110.100オンプレで公開サーバーを立てている想定。
intra.example.jpなし192.168.110.200オンプレで非公開サーバーを立てている想定。

この場合、内向きゾーン情報を変えるときには、外向きDNSとの整合性を考慮する必要がある。
この手間を減らす方法を探していく。

nxdomain-redirect

NXDOMAIN(登録なし)を回答しようとするとき、オプション指定される<suffix>を付けたゾーンを再検索する。
これで、

  • 内向きDNSのゾーンファイル(1)で、bothとintraだけを定義。
  • 外向きDNSのゾーンファイル(2)を、そのまま内向きDNSにコピーし、(1)に定義がないときに(2)を探すように設定。

ということができた。

内向きDNSサーバーで解決

内向きDNS

内向きDNSへの問い合わせが、例えば inter.example.jp だったとき、内向きのゾーン情報に見つからない。
このときNXDOMAINを返す前に、<suffix>を付与したinter.example.jp.redirectで、再度ゾーン情報を見に行くようにする。

/etc/bind/named.conf.options

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on-v6 { any; };
        allow-transfer { none; };
        nxdomain-redirect redirect;
};

※<suffix>をredirectにしている。

ゾーンを定義する。

/etc/bind/named.conf.local

// コメント化されているrfc1918を有効化(ローカルのIPアドレスを逆引きされてもよそに聞きに行かない)
include "/etc/bind/zones.rfc1918";

// 内向きDNSで書き換えたいところだけを定義したゾーン情報。
zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

// nxdomain-redirectされたときに参照するゾーン情報。
zone "example.jp.redirect" {
        type master;
        file "/var/lib/bind/db.example.jp.redirect";
};

// redirectが必要ないゾーンをでnxdomainを返す。
// Samba ad dcでは管理用にいくつかのゾーンが作られるが、それらのゾーンでnxdomainを返すことができるようになる。
zone "redirect" {
        type master;
        file "/etc/bind/db.empty";
};

// 逆引きゾーン情報。
zone "110.168.192.in-addr.arpa" {
        type master;
        file "/var/lib/bind/db.110.168.192.in-addr.arpa";
};

内向きDNSのゾーン情報には、名前を解決したいbothとintraを定義する。

/var/lib/bind/db.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       192.168.110.34
                                NS      addc2.hogeserver.hogeddns.jp.
both                            A       192.168.110.100
intra                           A       192.168.110.200

外向きDNSから持ってきたゾーン情報は、/var/lib/bind/db.example.jp.redirect という名前で保管しておく。

/var/lib/bind/db.example.jp.redirect

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       192.168.110.34
                                NS      addc2.hogeserver.hogeddns.jp.
inter                           A       172.31.1.10
both                            A       172.31.1.100

/var/lib/bind/db.110.168.192.in-addr.arpa

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                NS      addc2.hogeserver.hogeddns.jp.
34                              PTR     addc2.hogeserver.hogeddns.jp.
100                             PTR     both.example.jp.
200                             PTR     intra.example.jp.

設定を確認して、設定を再読み込み。

# named-checkconf
# named-checkzone example.jp /var/lib/bind/db.example.jp
# named-checkzone example.jp.redirect /var/lib/bind/db.example.jp.redirect
# named-checkzone 110.168.192.in-addr.arpa /var/lib/bind/db.110.168.192.in-addr.arpa
# rndc reload

動作確認

動作を確認してみる。

# dig inter.example.jp +short
172.31.1.10
# dig both.example.jp +short
192.168.110.100
# dig intra.example.jp +short
192.168.110.200

これで、

  • 外向きDNSのゾーン情報を変更の都度そのまま持ってくる。
  • 内向きDNSのゾーンで必要分だけを定義する。

という運用ができるようになった。

内向きDNSサーバーで解決(ゾーン転送)

外向きDNSのゾーン情報を、内向きDNSに自動で転送することはできないかと考えた。
ゾーン転送で実現できた。

外向きDNS

内向きDNSに対して、example.jp.redirectの情報変更を通知し、ゾーン転送を許可する。

外向きDNSと内向きDNSは、ルーターを介した接続になっているため、許可する対象のIPアドレスとしてルーターのIPアドレスを設定。
通知先もルーターのIPアドレスとなるので、ルーターには「8053ポートにやってきたパケットを、内向きDNSの53ポートに転送する」設定を入れた上で、以下の設定とした。
この構成の場合、ルーター配下のネットワーク全部(今回だと192.168.110.0/24)がゾーン転送を許可する対象になるので、範囲が広すぎるように思われる。本番の環境に適用するときにはもう少し工夫が必要になりそうだ。

/etc/bind/named.conf.options

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on-v6 { any; };
        recursion no;
        allow-transfer { none; };
};

/etc/bind/named.conf.local

include "/etc/bind/zones.rfc1918";

zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

zone "example.jp.redirect" {
        type master;
        file "/var/lib/bind/db.example.jp"; // 同じゾーンファイルを指定
        allow-transfer {
                172.31.1.2; // ルーターのIPアドレス(内向きDNSはIPマスカレードされている)
        };
        notify explicit;
        also-notify {
                172.31.1.2 port 8053; // ルーターのIPアドレス(NATで内向きDNSに到達)
        };
};

/var/lib/bind/db.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       172.31.1.254
                                NS      external.hogeserver.hogeddns.jp.
inter                           A       172.31.1.10
both                            A       172.31.1.100

設定を確認して、設定を再読み込み。

# named-checkconf
# named-checkzone example.jp /var/lib/bind/db.example.jp
# named-checkzone example.jp.redirect /var/lib/bind/db.example.jp
# rndc reload

内向きDNS

example.jp.redirectをslaveに変更し、外向きDNSからゾーン情報をもらってくるようにする。

/etc/bind/named.conf.options

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on-v6 { any; };
        allow-transfer { none; };
        nxdomain-redirect redirect;
};

/etc/bind/named.conf.local

include "/etc/bind/zones.rfc1918";

zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

zone "example.jp.redirect" {
        type slave;
        file "/var/lib/bind/db.example.jp.redirect.transfer";
        masterfile-format text;
        masters {
                172.31.1.254;
        };
};

zone "redirect" {
        type master;
        file "/etc/bind/db.empty";
};

zone "110.168.192.in-addr.arpa" {
        type master;
        file "/var/lib/bind/db.110.168.192.in-addr.arpa";
};

内向きDNSのゾーン情報には、名前を解決したいbothとintraを定義する。

/var/lib/bind/db.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       192.168.110.34
                                NS      addc2.hogeserver.hogeddns.jp.
both                            A       192.168.110.100
intra                           A       192.168.110.200

/var/lib/bind/db.110.168.192.in-addr.arpa

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                NS      addc2.hogeserver.hogeddns.jp.
34                              PTR     addc2.hogeserver.hogeddns.jp.
100                             PTR     both.example.jp.
200                             PTR     intra.example.jp.

設定を確認して、設定を再読み込み。

# named-checkconf
# rndc reload

動作確認

内向きDNSの設定を再読込したところで、ゾーン情報が転送されてきた。
タブコード(8カラム)が使われている。

/var/lib/bind/db/nayu.mydns.jp.redirect

$ORIGIN .
$TTL 86400      ; 1 day
example.jp.redirect     IN SOA  external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300        ; 5 minutes
                        NS      external.hogeserver.hogeddns.jp.
                        A       172.31.1.254
$ORIGIN example.jp.redirect.
both                    A       172.31.1.100
inter                   A       172.31.1.10

狙ったとおりの結果が得られるか、試してみる。

# dig inter.example.jp +short
172.31.1.10
# dig both.example.jp +short
192.168.110.100
# dig intra.example.jp +short
192.168.110.200

OK。
これで、外向きDNSのゾーンをあまり考えずに、内向きDNSを管理できるようになった。

外向きDNSに問い合わせる(想定外と思われる)

内向きDNSがNXDOMAINを返す前に、外向きDNSに転送するように設定してみた。
できないことはなかったのだけれど、外向きDNSにちょっと変な設定が必要になるし、内向きDNSの管理にも神経を使うことになりそうで、この設定は使わないと思う。

外向きDNS

内向きDNSは、問い合わせを受けた結果がNXDOMAINになったとき、問い合わせの末尾にredirectを付けて再検索をする。
この時、外向きDNSにはexample.jp.redirectで問い合わせがあると想定し、example.jpと同じゾーン情報を見て回答するように設定する。

/etc/bind/named.conf.options

options {
        directory "/var/cache/bind";
        dnssec-validation auto;
        listen-on-v6 { any; };
        recursion no;
        allow-transfer { none; };
};

/etc/bind/named.conf.local

include "/etc/bind/zones.rfc1918";

zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

zone "example.jp.redirect" {
        type master;
        file "/var/lib/bind/db.example.jp"; // 同じゾーンファイルを指定
};

/var/lib/bind/db.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       172.31.1.254
                                NS      external.hogeserver.hogeddns.jp.
inter                           A       172.31.1.10
both                            A       172.31.1.100

設定を確認して、設定を再読み込み。

# named-checkconf
# named-checkzone example.jp /var/lib/bind/db.example.jp
# named-checkzone example.jp.redirect /var/lib/bind/db.example.jp
# rndc reload

外向きDNSで確認。

# dig inter.example.jp +short
172.31.1.10
# dig inter.example.jp.redirect +short
172.31.1.10

内向きDNSから確認。

# dig inter.example.jp @172.31.1.254 +short
172.31.1.10
# dig inter.example.jp.redirect @172.31.1.254 +short
172.31.1.10

内向きDNS

nxdomain-redirectを有効にしておく。

NXDOMAINを返す前に、ナゾのトップレベルドメインredirectを付けて、外向きDNSにForwardする設定を入れる。
外向きDNSがせっかく答えてくれても、DNSSECの検証をすると「信用できない」と判断するので、DNSSECの検証を無効にする。

/etc/bind/named.conf.options

options {
        directory "/var/cache/bind";
        dnssec-validation no;
        listen-on-v6 { any; };
        allow-transfer { none; };
        nxdomain-redirect redirect;
};

※auto → noへの変更。

example.jp.redirectを外向きDNSにForwardする。

/etc/bind/named.conf.local

zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

zone "example.jp.redirect" {
        type forward;
        forward only;
        forwarders {
                172.31.1.254;
        };
};

// この定義があるとexample.jp.redirectはForwardされない
zone "redirect" {
        type master;
        file "/etc/bind/db.empty";
};

zone "110.168.192.in-addr.arpa" {
        type master;
        file "/var/lib/bind/db.110.168.192.in-addr.arpa";
};

// 必要のない再検索を止める
zone "hogeddns.jp.redirect" { type master; file "/etc/bind/db.empty"; };
zone "in-addr.arpa.redirect" { type master; file "/etc/bind/db.empty"; };

設定を確認して、設定を再読み込み。

# named-checkconf
# rndc reload

動作確認

内向きDNSに色々聞いてみる。

# dig inter.example.jp +short
172.31.1.10
# dig both.example.jp +short
192.168.110.100
# dig intra.example.jp +short
192.168.110.200

一見上手くいくように見えているけれど…

  • 外向きDNSでは、example.jp.redirectというナゾのゾーンを管理する必要がある。
  • 外向きDNSのexample.jpとexample.jp.redirectは、常に同じ内容であって欲しいので、example.jpとゾーン定義ファイルを共有してみたけれども、こんな使い方をしているのはdb.emptyくらい?あまり例を見かけない。
    ゾーン定義ファイルでは記載を省略できる機能を活用して、複数のゾーンで使われても問題なく動くゾーン情報の書き方をしておく。
  • 内向きDNSでは、管理しているゾーンすべてについて、redirectを末尾に付与したゾーンを管理する必要がある。
    逆引きも同様。Samba ad dcだと管理用のゾーンがいくつか作られるが、これも同様。
    Forwardするためにredirectというゾーンを定義することができないので、これらをもれなく管理する。
  • DNSSECの検証を無効にする必要がある。
    無効にしないと、外向きDNSがexample.jp.redirectについて回答してくれても、それを受け入れられない。
    でも、無効にすると、example.jp.redirect同様のナゾのドメインを受け入れてしまう。
    ただ、これについては、DNSSECはやるだけ無駄と教えてもらったりもしたので、無効にしても良いのかもしれない。

ということで、自分で気が付いただけでもちょっと変だなーと思う箇所があり、BIND9はこのような使われ方を想定していないと思われた。

今は気付いていないけれど、他にも問題のあるパターンがあるかもしれないと考えると、DNSをよく分かっている人がやるならともかく、今の自分のレベルで「nxdomain-redirectの仕組みに、よそのサーバーを巻き込む」のは危険と考えた。

やったこと

nxdomain-redirectを見つけるまでの間、色々な方法に探りを入れていた。
後で使うこともあるかもしれないので、メモしておく。

Delegate

サブドメインを他のDNSに任せる。
e.g.) example.jp → sub.example.jp

example.jp

任せる側では、既にあるexample.jpのゾーン情報に、任せる内容を書いておく。

/etc/bind/named.conf.local

zone "example.jp" {
        type master;
        file "/var/lib/bind/db.example.jp";
};

/var/lib/bind/db.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       192.168.110.34
                                NS      addc2.hogeserver.hogeddns.jp.
both                            A       192.168.110.100
intra                           A       192.168.110.200

; delegate
sub                             NS      external
external                        A       172.31.1.254

設定を確認して、設定を再読み込み。

# named-checkconf
# named-checkzone example.jp /var/lib/bind/db.example.jp
# named-checkzone sub.example.jp /var/lib/bind/db.example.jp
# rndc reload

sub.example.jp

任せられる側では、sub.example.jpゾーンを追加した。

/etc/bind/named.conf.local

zone "sub.example.jp" {
        type master;
        file "/var/lib/bind/db.sub.example.jp";
};

/var/lib/bind/db.sub.example.jp

$TTL 86400      ; 1 day
@                       IN SOA  external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090200 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       172.31.1.254
                                NS      external.example.jp.
external.example.jp.            A       172.31.1.254
a                               A       172.31.1.33
b                               A       172.31.1.44

設定を確認して、設定を再読み込み。

# named-checkconf
# named-checkzone sub.example.jp /var/lib/bind/db.sub.example.jp
# rndc reload

動作確認

example.jpを管理する側に聞いてみる。

# dig sub.example.jp -t any
…
;; ANSWER SECTION:
sub.example.jp.         300     IN      NS      external.example.jp.
sub.example.jp.         86400   IN      SOA     external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. 2022090200 3600 600 259200 86400
sub.example.jp.         300     IN      A       172.31.1.254
…
# dig a.sub.example.jp +short
172.31.1.33
# dig b.sub.example.jp +short
172.31.1.44

Forward

特定のドメインについて、他のサーバーに再帰的に問い合わせる。

設定はdelegateの節をベースとして、example.jpから転送するようにした。

/etc/bind/named.conf.local

zone "example.jp" {
        type forward;
        forward only;
        forwarders {
                172.31.1.254;
        };
};

設定を確認して、設定を再読み込み。

# named-checkconf
# rndc reload

forwardはfirstという設定も可能。172.31.1.254が落ちていたりした場合に、ルートサーバーから再帰的に探してきてくれる。
でも、ホームラボの中から問い合わせたとき、LANの中のIPアドレスが帰ってこないと意味がないので、落ちていたら失敗するようにonlyを設定。

聞いてみると、このような結果となった。

# dig example.jp -t any
…
;; ANSWER SECTION:
example.jp.             300     IN      NS      external.hogeserver.hogeddns.jp.
example.jp.             300     IN      A       172.31.1.254
example.jp.             86400   IN      SOA     external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. 2022090207 3600 600 259200 86400
…
# dig sub.example.jp +short
172.31.1.254
# dig a.sub.example.jp +short
172.31.1.33

# dig a.sub.example.jp ← Forward先を落としたとき
…
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 6715
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
…

# dig example.jp -t any @172.31.1.254
…
;; ANSWER SECTION:
example.jp.             86400   IN      SOA     external.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. 2022090207 3600 600 259200 86400
example.jp.             300     IN      A       172.31.1.254
example.jp.             300     IN      NS      external.hogeserver.hogeddns.jp.
…

redirect zones

NXDOMAIN(登録なし)を答えようとするとき、リダイレクト用のゾーン定義を見て、そこにあれば答えを差し替える。
ISC / BIND 9.9 redirect zones (for NXDOMAIN redirection)
ISC / NXDOMAIN Redirection Using DLZ in BIND 9.10 and later

これは、ゾーンに定義されているIPアドレスを、AレコードとかAAAAレコードとして答える。
どういうシーンで使うものなのか…間違った名前で問い合わせを受けたときに、削除されましたページを表示させるとか?

こちらも設定はdelegateの節をベースとして、ルートゾーンをredirectで定義した。

/etc/bind/named.conf.local

zone "." {
        type redirect;
        file "/var/lib/bind/db.redirect";
};

/etc/bind/db.redirect

$TTL 86400      ; 1 day
@                       IN SOA  addc2.hogeserver.hogeddns.jp. webmaster.hogeserver.hogeddns.jp. (
                                2022090201 ; serial
                                3600       ; refresh (1 hour)
                                600        ; retry (10 minutes)
                                259200     ; expire (3 days)
                                86400      ; minimum (1 day)
                                )
$TTL 300
                                A       192.168.110.34
                                NS      addc2.hogeserver.hogeddns.jp.
addc2.hogeserver.hogeddns.jp.   A       192.168.110.34
hoge.example.jp.                A       172.17.254.254
*.sub.example.jp.               A       172.18.254.254

設定を確認。

# named-checkconf
# named-checkzone . db.redirect
# rndc reload

聞いてみると、このような結果となった。

# dig hoge.example.jp +short
172.17.254.254
# dig aaaa.example.jp +short
→ 回答なし

# dig hoge.sub.example.jp +short
172.18.254.254
# dig aaaa.sub.example.jp +short
172.18.254.254

# dig hogehoge.rohhie.net
→ 回答なし

ログを出すには

マニュアルはこちらにあるが、思ったようなログを出すことができていない。とりあえず見えたレベル。
BIND 9 Configuration Reference

コンソールで見る

とりあえず、標準出力にログを出すなら、起動時に-gオプションを付ける。
起動後、すぐに落ちてしまうような状態(設定ファイルのミスなど)のときに使えるかもしれない。

# /usr/sbin/named -u bind -g

ファイルで見る

ログをファイルを出力するには、loggingというブロックでログ出力について指定する。

/etc/bind/named.conf

…
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/named.conf.logging";

※赤文字部分を追加。

/etc/bind/named.conf.logging ※新規作成

logging {
        channel query_log {
                file "/var/log/named/query.log" versions 10 size 10M;
                severity info;
                print-time yes;
        };
        category queries { "query_log"; };

        channel default_log {
                file "/var/log/named/bind.log" versions 10 size 10M;
                severity warning;
                print-time yes;
                print-category yes;
        };
        category default { default_log; };
};

ログファイルを保管するディレクトリを作っておく。

# mkdir /var/log/named
# chown bind:bind /var/log/named

設定を確認して、設定を再読み込み。

# named-checkconf
# rndc reload

query.logは設定の再読み込みでは出力がされなかった。
再起動するか、以下のコマンドで、ログ出力する・しないを切り替えられる。

# rndc querylog

権威サーバーとキャッシュサーバー

ゾーンを管理しているということは権威サーバーな訳で、キャッシュサーバーと兼用することも別に問題はない。
けれどそれは本来どのように動くのか、それをどのように実装するのか、というところを改めて整理したいと思った。

探してみると、それをきっちりと教えてくれるサイトに出会えた。
シナプス技術者ブログ / BINDの大切な設定の話

理屈を分かっていることは大事だけれども、実装からも追いかけて、両面から整理できるのはありがたい。

今回、権威サーバーでは、再帰検索を止めて、ゾーン転送を拒否するようにしている。

起きたこと

色々起きたことは起きたのだが、多くは本文中に反映した。
解決に特に時間が掛かったことをメモしておく。

Forwardで名前が解決できない

内向きDNSでnxdomain-redirectを設定し、外向きDNSにForwardしてみたら、どうにも名前が解決できなかった。
内向きDNSは、外向きDNSに聞きに行っているけれども、答えを無視しているようだ。

どうして無視するのだろうと思って探してみると、DNSSECが有効になっているかどうかを確認する方法が見つかった。
ICANN / 最新のトラストアンカーによるDNS検証リゾルバの更新

# dig example.jp.redirect a +dnssec

; <<>> DiG 9.18.1-1ubuntu1.1-Ubuntu <<>> example.jp.redirect a +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 33459
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: 8eb5126558afda2d0100000063129a5b006573bea8ccc4ad (good)
;; QUESTION SECTION:
;example.jp.redirect.           IN      A

;; Query time: 196 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sat Sep 03 09:05:47 JST 2022
;; MSG SIZE  rcvd: 76

なるほど、外向きDNSの回答がおかしいと判断して、無視しているのか。

さらに、もう一度聞いてみたら、このような答えが返ってくる。
応答時間から考えて、外向きDNSに問い合わせたときには、既にトップレベルドメインに質問しにいっていて、キャッシュされた回答が見えているのではないかと。

# dig example.jp.redirect a +dnssec

; <<>> DiG 9.18.1-1ubuntu1.1-Ubuntu <<>> example.jp.redirect a +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 4969
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: a28109fea7263230010000006312a56e50ada62b4bd71f16 (good)
;; QUESTION SECTION:
;example.jp.redirect.           IN      A

;; AUTHORITY SECTION:
.                       83565   IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2022090201 1800 900 604800 86400
.                       83565   IN      RRSIG   SOA 8 0 86400 20220915160000 20220902150000 20826 . k/bk5uvlCpIRJgYidQd2WF9jMkrpKvD3hz0oOOgLykI5L/nC7OfJFfuI LIK0ytQND9hJWhyJM/caLYN3jxFiZuq4YfbJNEddkXMJsQQmoIob/8mp sRQrFUh6sVYdGCZDbv6vCAcTaMafV7oUoXuf9Ugn1GY7MjgQOmKcQP3/ c+D/4x9ITA3iW+Wm8ASkebeQqqM9Oy52UKljbYGOHnwroNM6aGxmhrHf IGE/WLqW1PThOrONncYGp1tiNaynMoBq/zDyCKn3OUJceHOVPIWxYIbo B/Y/z1TzG2qUc5U/7csKWWItdDNBvYwOCXfMx7syN9y7PkMkQ7+ebVQ1 4mBvtw==
.                       83565   IN      NSEC    aaa. NS SOA RRSIG NSEC DNSKEY
.                       83565   IN      RRSIG   NSEC 8 0 86400 20220915160000 20220902150000 20826 . hmwCRBP7wXad0cwIiWyISVKd2Jie/uPl5HFLivjBygTNJoHk0HzQ+pLd auodPErU4b9MD6lppBliATw6AYQUx0coK7tMv4DVJfZ0hn95PAyjK09q G1m3EwjXeKFpC+MNvENP1EL2k4ZtBylGB0z67PzeY12x060G/N7Yamx8 TXO4db5FUCqvOuecrmPMw1vx1vywmDCi00E8tpxWpOldaIa3oMePxjfJ W1R7xowTDWsEWerRUs5uW/fUMWXMJxd2E9YrJyiJKIwIWAT9dZPgmcRC pBdFgE7NqiZy+p1pDii4Fn/HyjMSWmWtmdIMvKSQnRko41pZkRHR3C6O H7MBHg==
red.                    83565   IN      NSEC    redstone. NS DS RRSIG NSEC
red.                    83565   IN      RRSIG   NSEC 8 1 86400 20220915160000 20220902150000 20826 . oH38owN8sH/X/eYopoNjZh41xhOejxyCXAD6FhDFv4586IOgxwLZni6I 8vT3ipihnUbi9IS+d5ycHoLSxroQ46F9AEtRTW/TV99AFO0MYCMURRW9 +gvEE3A8wH0LTKmhoiU0xSCC23yERvX6V2KF20R/R9o8M4njrxKzbLpU SVyP4TuehV093nxb6iVuGrmQzmFVb/PDnkDTd7vTrQVjUlPDhEYK/eVK rI7s2i7DckhTnGESh07Qw5yLoSYCwgIS4JMgvNSJ87fzqbXWHSP62HLR ALUN78yE2+pKAr07glGzp+Eu4KlNSKj+djfKwSfXq2qUivhcxvxyCZzj GeABTA==

;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sat Sep 03 09:53:02 JST 2022
;; MSG SIZE  rcvd: 1068

これは、「ルートゾーンが持っていることを否定している」のに「トップレベルドメインの子を主張するドメイン」と見なされているようだ。
Intended usage of dnssec-must-be-secure?

そうすると、内向きDNSはDNSSECが有効だから、トップレベルドメインに「このredirectというドメインは、あなたの子供ですか?」と聞きに行き、「No!」と答えてもらっているのか。

DNSSECを理解できていないのでこの解釈も若干怪しいが、名前解決ができない理由に気付くのに何日もかかってしまった。
それに、digの1回目と2回目で回答が違う理由が分からない、多分1回目にこの情報は持っているだろうに表示されない、何故なのか分からない。

んー、これはアカン。

DNSはユーザーに直接影響するし、ミスるとインターネットにも迷惑を掛けるので、これは止めておこう。となった。

さいごに

今の時点で分かったことを整理した。

元々は、Samba ad dcのバックエンドDNSを、内蔵のものからBINDに変更することをテーマにしていて、ちょっとした脇道のつもりだったけれど、その割にはだいぶ時間を掛けてしまった。

過去にいくつかのBINDに関するメモを残していたけれど、その時々でまぁまぁ頑張っていて、見直してみると割と役に立ったりもする。
恥ずかしいのもあるけれど、それはそれで仕方がない。知識もページもアップデートだー。

こうやって整理しておけば、未来の自分の役に立つかもしれない…よね。

コメントはこちらから お気軽にどうぞ ~ 投稿に関するご意見・感想・他