DNSクエリパケットを生成する際にはIDは任意でよく、通常のクエリであるから、ヘッダは以下のようにすればよい。名前解決を要求する場合は、RDビットを1にする。そのため、以下のようなHeaderセクションとなる。
www.jprs.co.jp のA を問い合わせたい場合は、ドメイン名、タイプ、クラスを順に連結するだけなので、以下のようなQuestionセクションとなる。
これを組み合わせたものがDNSクエリパケットとなる。
00 00 01 00 00 01 00 00 00 00 00 00
03 77 77 77 04 6a 70 72 73 02 63 6f 02 6a 70 00 00 01 00 01
POSIX準拠のOSのprintfコマンドでは“\”で8進データを扱える(注1)ため、netcat(nc)コマンドと組み合わせ、以下のようなコマンドラインでクエリと応答を見ることができる。/etc/resolv.confを参照してフルサービスリゾルバを確認しておくこと。
printf "\0\0\1\0\0\1\0\0\0\0\0\0\3www\4jprs\2co\2jp\0\0\1\0\1" | nc -u -w 1 フルサービスリゾルバーのIPアドレス 53 | hexdump -C
上記コマンドラインは、“dig @フルサービスリゾルバアドレス www.jprs.co.jp A”に相当する。BIND 9フルサービスリゾルバの標準設定では、以下のような結果が得られた。
00000000 00 00 81 80 00 01 00 01 00 03 00 05 03 77 77 77 |.............www|
00000010 04 6a 70 72 73 02 63 6f 02 6a 70 00 00 01 00 01 |.jprs.co.jp.....|
00000020 c0 0c 00 01 00 01 00 00 01 2c 00 04 75 68 85 a7 |............uh..|
00000030 c0 10 00 02 00 01 00 01 21 51 00 06 03 6e 73 32 |........!Q...ns2|
00000040 c0 10 c0 10 00 02 00 01 00 01 21 51 00 06 03 6e |..........!Q...n|
00000050 73 31 c0 10 c0 10 00 02 00 01 00 01 21 51 00 06 |s1..........!Q..|
00000060 03 6e 73 33 c0 10 c0 4e 00 01 00 01 00 01 49 a3 |.ns3...N......I.|
00000070 00 04 ca 0b 10 31 c0 4e 00 1c 00 01 00 01 49 a3 |.....1.N......I.|
00000080 00 10 20 01 0d f0 00 08 00 00 00 00 00 00 00 00 |.. .............|
00000090 a1 53 c0 3c 00 01 00 01 00 01 21 51 00 04 ca 0b |.S.<......!Q....|
000000a0 10 3b c0 3c 00 1c 00 01 00 01 21 51 00 10 20 01 |.;.<......!Q.. .|
000000b0 0d f0 00 08 00 00 00 00 00 00 00 00 a2 53 c0 60 |.............S.`|
000000c0 00 01 00 01 00 01 21 51 00 04 3d c8 53 cc |......!Q..=.S.|
000000ce
この情報を解読するには、ヘッダとリソースレコードを分離する必要がある。
フラグ 81 80……応答で、エラーがなかったことと、名前解決が可能である(RDビットは問い合わせた内容が保存されている)ことが示されている。
続く情報はQuestionセクションで、クエリの内容が保存されている。
次に、Answerセクションが続く。
c0 0cで始まっているためメッセージ圧縮が行われており、オフセット12からの名前という意味である。オフセット12にはQuestionセクションのドメイン名部が格納されており、www.jprs.co.jpである。それ以外はリソースレコードの例と同じである。
さらに、同様の形でAuthorityセクションが続く。
このように、DNS応答を解読するには、全ての情報を先頭から正しく読み解く必要がある(本応答は、フルサービスリゾルバからの応答であるため、TTL値はオリジナルのTTL値(86400)よりも減算されている点に注意すること。以降同様)。
Authorityセクションの残る2リソースレコードも同様で、
となる。
そのあとAdditionalセクションが5リソースレコード分続く。
オフセット78(0x4e)からは以下のバイト列であるため
"ns1" +さらにjprs.co.jpへのポインタ → ns1.jprs.co.jp
と解読できる。
これまでの説明の通り、各セクションに含まれるドメイン名とRDATAが可変長であるため、DNSパケットは先頭から順に解釈する必要がある点に注意してほしい。今回紹介したDNSパケットフォーマットはRFC 1035で定義されており、その後発行された数多くのRFCで拡張されている。DNSを理解するためには、まずRFC 1035を読むとよい。
注1:printfコマンドの実装によっては、“\x”で16進表記可能な場合がある。
所属:株式会社日本レジストリサービス(JPRS) 技術研究部
1992年より早稲田大学情報科学研究教育センターにて、助手として早稲田大学の研究教育系ネットワーク構築・運用にたずさわる。2002年にJPRS入社。DNS及び関連する技術の調査・研究、IETFでの標準化活動に従事。
著書・執筆:「ツールとしてのUNIX」(サイエンス社、深澤良彰編著、梅沢功、小野康一、落合大、藤原和典共著、1993年4月、ISBN4-7819-0700-8)、RFC 5483、RFC 5504、RFC 5825、RFC 6116、RFC 6856、RFC 6857、RFC 7719。
Copyright © ITmedia, Inc. All Rights Reserved.