SIer、Developerから見た
BINDからの移行
DNS Summer Day 20182018年6月27日

発表者
名前

佐藤 匠（さとう たくみ）所属

三菱電機インフォメーションシステムズ株式会社（MDIS）
仕事内容

SIer
通信キャリア向けネットワークインフラシステム構築(RADIUS、DHCP、DNS)

発表者
名前

矢島 崇史（やじま たかし）
所属

株式会社XACK
仕事内容

通信キャリア向けのソフトウェア開発(RADIUS、DHCP、DNS)XACK DNS
・100%自社開発のDNSサーバー

・UNIX系OSで動作するソフトウェア、アプライアンス

・権威サーバー、フルリゾルバー、フォワーダー、etc...

・モジュール化による機能の足し引きが可能

BINDをXACK DNSにしてみよう！
お客様からDNSサーバ更新の提案機会をいただきました。
①自社ドメイン
権威DNS

Master

更新対象- 権威キャッシュ共用を現IPで継続したい- ①②③パターンができるDNSソフトウェア

Slave②セカンダリ用
権威DNS

キャッシュ共用
パターンもアリ！

Slave③フルリゾルバ- 現在はBINDだが、次回はOSS以外がよい

ユーザ運営Master・・・・
そうだ！
XACK DNSなら全部できる！

結果
BINDは懐が深くてやさしくて適当で学ぶことが多くありました！

事例1:ゾーン転送
よくあるシーケンス
スレーブ

マスター
Notify要求
Notify応答
SOA要求
SOA応答
IXFR要求IXFR応答事例1:ゾーン転送
ケース1: 色々応答してくれない
スレーブ

マスター
Notify要求
Notify応答
SOA要求

SOAだめ
UDPだめ
EDNS0だめ

SOA応答

タイムアウトAXFR要求AXFR応答

スレーブに対してもHidden Primary…?

事例1:ゾーン転送
ケース2: RR毎にDNSパケットを分割する。ID違いで
スレーブ

マスター
IXFR要求DNSパケットの最大サイズは64KB⇒64KB超のゾーンはパケット分割して送信する

IXFR応答(ID=aaaaa, ANCOUNT=1)IXFR応答(ID=bbbbb, ANCOUNT=1)IXFR応答(ID=ccccc, ANCOUNT=1)(中略)
IXFR応答(ID=zzzzz, ANCOUNT=1)

何も全部分割しな
くても……

事例1:ゾーン転送
ケース3: AXFR応答の最初と最後のSOAが違う
スレーブ

マスター
AXFR要求分割されたパケットの先頭、終端はSOAレ
コードで判別する⇒一度のゾーン転送に2つのSOAレコードがある

AXFR応答SOA(シリアル=2018062701)…
SOA(シリアル=2018062702)

シリアルは差分ゾーン転送時に重要な情報、値が異なると出来上がるゾーンが異なってしまうかも⇒どっちのシリアル使えばいいんです？

事例1:ゾーン転送
対処: 色々失敗してもフォールバック、応答のチェックを許容的に
スレーブ

マスター

SOA要求(UDP/EDNS0有り)
不正な応答または無応答
SOA要求(UDP/EDNS0無し)
不正な応答または無応答
SOA要求(TCP/EDNS0無し)
不正な応答または無応答
IXFR要求(TCP/EDNS0無し)
不正な応答または無応答
AXFR要求(TCP/EDNS0無し)
AXFR応答(TCP/EDNS0無し)

結果としてBINDよりもゾーン転送に対応できるようになりました。
(BINDはIXFRからAXFRにはフォールバックしないパターンあり)事例2:ゾーンファイル読み込み
ケース4: 委任先のグルーがない$ORIGIN example.com.
$TTL 300@IN
SOA(SOA RDATA略)
NSns1
ns1
A
192.0.2.1
subNS
no-glue;no-glueのAレコードはなし

・委任先内部名のグルーがないと委任先の権威サーバーのIPアドレスが分からずその先の問い合わせができない。

・設定でそのようなゾーンファイルを許容できる機能を追加(推奨しません)事例2:ゾーンファイル読み込み
ケース5: TTLが10進数でない
RFC1035 5.1項では以下のように書かれています。
The RR begins with optional TTL and class fields, followed by a type andRDATA field appropriate to the type and class. Class and type use thestandard mnemonics, TTL is a decimal integer.

→TTLは10進数の整数である。
しかし色々なゾーンファイルを見てみると…
$TTL 1w3d12h59m1s$TTL 1m1m1m1m1m$TTL 39m421S899s981M1h4M9H187232131s

SOAのRDATAでこんなの見たことある！→TTLでも許容するようにしました。

事例3:この応答の違い、分かりますか？
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:21963;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY:0, ADDITIONAL: 0;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:21963;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY:0, ADDITIONAL: 0;; QUESTION SECTION:;example.com.

;; QUESTION SECTION:;example.com.

;; ANSWER SECTION:
example.com.
93.184.216.34

IN12715

IN;; Query time: 3 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Fri Jun 15 11:35:35 2018;; MSG SIZE rcvd: 45AA;; ANSWER SECTION:
example.com.
93.184.216.34

12715

IN

AIN

A;; Query time: 3 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Fri Jun 15 11:35:35 2018;; MSG SIZE rcvd: 56

事例3:メッセージサイズが違う！
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:21963;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY:0, ADDITIONAL: 0;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:21963;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY:
0, ADDITIONAL: 0;; QUESTION SECTION:;example.com.

;; QUESTION SECTION:;example.com.

;; ANSWER SECTION:
example.com.
93.184.216.34

IN12715

IN;; Query time: 3 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Fri Jun 15 11:35:35 2018;; MSG SIZE rcvd: 45AA;; ANSWER SECTION:
example.com.
93.184.216.3412715

INAINA;; Query time: 3 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Fri Jun 15 11:35:35 2018;; MSG SIZE rcvd: 56

事例3:メッセージ圧縮
同一の名前が存在する場合、他方を参照するポインターを設定することで圧縮することが出来ます。
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21963;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:;example.com.
;; ANSWER SECTION:example.com.

12715

INAINA;; Query time: 3 msec;; SERVER: 127.0.0.1#53(127.0.0.1);; WHEN: Fri Jun 15 11:35:35 2018;; MSG SIZE rcvd: 45

93.184.216.34

事例3:メッセージ圧縮
ケース6:後方参照圧縮$ORIGIN example.jp.
$TTL 3600@INSOA
ns1.test.jp. a.test.jp. (3147483648; serial3000; refresh3000; retry100; expire
3000; minimum)
PTR
foo.bar.
NSa.foo.bar.
NSb.foo.bar.

→ “example.jp.”のPTRレコードを問い合わせると…

事例3:メッセージ圧縮
ケース6:後方参照圧縮
drillの場合;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 44216;; flags: qr aa ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0;; QUESTION SECTION:;; example.jp. IN
PTR;; ANSWER SECTION:
example.jp.
3600

IN

PTR

foo.bar.

;; AUTHORITY SECTION:
example.jp.
3600
example.jp.
3600

IN
IN

NSNSa.foo.bar.
b.foo.bar.

;; ADDITIONAL SECTION:;; Query time: 0 msec;; SERVER: 127.0.0.1;; WHEN: Wed Dec 20 17:17:16 2017;; MSG SIZE rcvd: 81

事例3:メッセージ圧縮
ケース6:後方参照圧縮digの場合;; Got bad packet: bad compression pointer81 bytes
2a d4 84 80 00 0c 00 01 00 02 00 00 07 65 78 61
6d 70 6c 65 02 6a 70 00 00 01 00 01 c0 0c 00 0c00 01 00 00 0e 10 00 04 01 62 c0 3a c0 0c 00 02
00 01 00 00 0e 10 00 0b 01 61 03 66 6f 6f 03 62
61 72 00 c0 0c 00 02 00 01 00 00 0e 10 00 02 c028*............exa
mple.jp.........
.........b.:....
.........a.foo.bar..............
(事例3:メッセージ圧縮(2)PTRは後方にある1番
ケース6:後方参照圧縮
目のNSを参照;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 44216⇒後方参照;; flags: qr aa ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0;; QUESTION SECTION:;; example.jp. IN

PTR;; ANSWER SECTION:
example.jp.
3600

IN

PTR

foo.bar.

;; AUTHORITY SECTION:
example.jp.
3600
example.jp.
3600

IN
IN

NS
NS

a.foo.bar.
b.foo.bar.

;; ADDITIONAL SECTION:(1)2番目のNSは前方にある
PTRを参照→BINDは(2)の解釈に失敗しますが、Unboundは対応しているようです。

事例4:誰も守っていないRFC
ケース7: 応答のEDNS0のサイズ
RFC6891 6.1.2項では以下のように記載されています。
The fixed part of an OPT RR is structured as follows:+------------+--------------+------------------------------+| Field Name | Field Type | Description|+------------+--------------+------------------------------+| NAME| domain name | MUST be 0 (root domain)|| TYPE| u_int16_t| OPT (41)|
| CLASS| u_int16_t| requestor's UDP payload size || TTL| u_int32_t| extended RCODE and flags|| RDLEN| u_int16_t| length of all RDATA|| RDATA| octet stream | {attribute,value} pairs|+------------+--------------+------------------------------+OPT RRのCLASSフィールドには「要求者」、つまるところクエリを送信した側のUDPペイロードサイズを設定するように定められているようです(昔はsender's UDP payload sizeでした)。

事例4:誰も守っていないRFC
ケース7: 応答のEDNS0のサイズ
尚、実際の所誰も守っていません。皆さん自身のサーバーの設定を返すようです。

$ dig +norec @198.41.0.4 +bufsize=1024 a.root-servers.net. A; (1 server found);; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5940;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 26;; OPT PSEUDOSECTION:; EDNS: version: 0, flags:; udp: 1472…

これらの事例を受けてRFCに書かれていること、書かれていないこと含めて様々な想定外の動作、差分があることが判明→差分を洗い出したい！

どうやって？
→全通り試せばいい(白目)対象となる通信マスター
権威サーバー
Notify要求
ゾーン転送応答

リゾルバー

クエリー

XACK DNS

反復問い
合わせの応答Notify応答
ゾーン転送要求スレーブ
権威サーバー

権威サーバーやったことヘッダーについては概ね全通り試せる。
1 1 1 1 1 10 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|
ID|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|QR| Opcode |AA|TC|RD|RA| Z| RCODE |+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|QDCOUNT|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|ANCOUNT|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|
NSCOUNT|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|
ARCOUNT|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+*COUNTはRRの数に依存するので、気にしなければならな
いのは先頭32ビットだけ、しかもうち16ビットはIDやったこと質問部の数については0個、1個、2個で試す(2個以上の質問部をサポートしていないことを想定)。
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+||/QNAME///+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|
QTYPE|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+|QCLASS|+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

要求の場合、QTYPE、QCLASSは32ビットなので全通り試せる。
応答の場合、QNAME、QTYPE、QCLASSは要求との一致不一致の2通りに畳み込む。

やったこと資源レコード(回答部、権威部、追加部)はパターン分けする。
ポジティブ応答、ネガティブ応答、委任、etc…
これらから回答部、権威部、追加部のパターンを作成して組み合わせる。

→ざっくり10億通りくらい→現実的！！

やりたいこと
DNSパケットのビットレベルでの比較→思い付き+提供いただけたものについては実施

様々なゾーンファイルの読み込み→思い付き+提供いただけたものについては実施

資源レコード→個々のリソースレコードタイプ毎に深堀したいおわりに今回の経験を得てXACK DNSもよりやさしく、懐深くなりました。
今後も安心・安定してご使用いただけるソフトウェア、システムを目指して参ります。
(新設、更改のお声掛けお待ちしております！)

ご注意・本書の内容の一部又は全部を三菱電機インフォメーションシステムズ株式会社および株式会社ＸＡＣＫに断りなく、いかなる形でも転載又は複製することは、固くお断りします。
・本文記載の社名、製品名、ロゴは各社の商標または登録商標です。