- DNSは1980年代から35年以上使われており、構造も安定しているが、多くのプログラマが基本的な問題を自信を持ってデバッグできるようになるまでには長い時間がかかる
- 難しさはDNS自体の複雑さよりも、リゾルバキャッシュ、ローカルDNSライブラリ、権威ネームサーバーとのやり取りのような見えない構成要素が多いことにある
digは強力だが、出力構造や用語がなじみにくく、+norecurseのような機能は便利でも、結果の解釈が直感的ではない
- negative caching、
muslのTCP DNS未対応だった経緯、TTLを無視するリゾルバ、nginxの永続キャッシュ、Kubernetes ndotsのようなよくある落とし穴は、誰かに教わるまで学びにくい
- DNSをめったに扱わない人にはチートシートが役立ち、実験のハードルが高い問題はMess With DNSのような安全な実験環境で和らげられる
古い技術なのに難しいDNS
- DNSはRFC 1034の時代から35年以上使われており、インターネット上のあらゆるWebサイトで使われ、多くの面で30年前と似たように動作している
- それにもかかわらず、「ドメインを正しく設定したのに名前解決されない」や「
digとブラウザのDNS結果が違う」といった基本的な問題のデバッグに時間がかかることがある
- DNSを難しく感じる人は、たいてい次のような点でつまずく
- Webサイトの簡単なDNS変更でさえ気軽にできない
- DNSレコードはプッシュされるのではなくプル (pull) される、という事実を混同する
- 基本概念は分かっていても、negative cachingや
digとブラウザのDNSクエリの違いといった細かな挙動で混乱する
見えないリゾルバとネームサーバー
- コンピュータからDNSリクエストを送るときの基本的な流れは単純に見える
- コンピュータがresolverというサーバーに問い合わせる
- resolverがキャッシュを確認し、必要であればauthoritative nameserverに再度問い合わせる
- 実際のデバッグで重要な多くの要素は、通常は表に出てこない
- resolverのキャッシュに何が入っているのか分かりにくい
- ローカルでどのDNSライブラリがリクエストを処理しているのか明確でない
- libc
getaddrinfo、glibc、musl、Apple実装、ブラウザ自身のDNSコード、別個のカスタム実装などがありうる
- それぞれの実装で設定、キャッシュ方式、機能サポートが少しずつ異なる
musl DNSは2023年初頭までTCPをサポートしていなかった
- resolverとauthoritative nameserverの間のやり取りが見えない
- どのauthoritative nameserverに問い合わせたか、その応答を追跡できれば、多くのDNS問題をもっと簡単に理解できる
隠れたシステムを見えるようにするアプローチ
- 隠れた構成要素が何かを知るだけでも、学習の大きな助けになる
- 1台のコンピュータの中でも状況によって複数のDNSライブラリが使われることを知らなければ、長く混乱し続ける可能性がある
- Mess With DNSは、通常は見えない部分を見せるfishbowl方式の実験を試みている
- resolverとauthoritative nameserverの間のやり取りを一部見られるようにする
- DNS応答にデバッグ情報を入れる方法もある
Extended DNS Errorsが与える手がかり
- Extended DNS Errorsは、DNSサーバーが応答に追加のデバッグ情報を提供する新しい方式である
- 存在しないドメイン
xjwudh.comをdig @8.8.8.8 xjwudh.comで問い合わせると、次のような追加エラーが出ることがある
; EDE: 12 (NSEC Missing): (Invalid denial of existence of xjwudh.com/a)
- この例はDNSSEC関連の項目に見えるが、重要なのは応答の中に追加のデバッグメッセージが入ってくる点である
- この例を見るには、より新しいバージョンの
digが必要だった
強力だが読みにくいdig
- DNSの内部状態を確認するのに
digは有用である
dig +norecurseを使うと、特定のDNS resolverがどのレコードをキャッシュしているか確認できる
8.8.8.8は、応答がキャッシュにない場合はSERVFAILを返すように見える
google.comはキャッシュにあるため、NOERRORとAレコードを返す
homestarrunner.comはキャッシュになくSERVFAILを返すが、これはDNSレコードが存在しないことを意味しない
digの出力は、慣れていないと読みにくい
->>HEADER<<-、flags:、OPT PSEUDOSECTION:、QUESTION SECTION:、ANSWER SECTION:といった見出しがなじみにくい
- セクション間の改行や空白が一貫しているように感じられない
MSG SIZE rcvd: 47では、rcvd以外にどんなフィールドがあるのか分かりにくい
ADDITIONALセクションにレコードが1件あると言いながら、実際にはOPT PSEUDOSECTIONがその役割を果たしていることを知っている必要がある
digの出力は、最初から意図して設計された形式というより、時とともに有機的に大きくなったスクリプトのように見える
DNSツールをもっと読みやすくする方法
digの出力自体を説明する文書が役に立つ
- もっと親切なツールを作ることもできる
digの出力に+humanのようなオプションを追加して、同じ情報をより構造的に見せる方法も考えられる
- ヘッダー、問い合わせ、応答、追加セクション、時間、サーバー、プロトコル、応答サイズを明確に分けられる
- 情報量を減らすのではなく、同じ情報をより読みやすく表現するアプローチである
- 最新の
digには+yaml出力形式がある
- より明確に感じられるかもしれないが、簡単なDNS応答でも画面に収まらないほど冗長になることがある
よく遭遇するが学びにくいDNSの落とし穴
- DNSには比較的よく遭遇する一方で、誰かに教わるまでは知りにくい落とし穴がある
-
negative caching
- まだDNSレコードのないドメインを訪れると、そのレコードの「存在しない」状態がキャッシュされることがある
- この状態が数時間キャッシュされると非常に厄介になる
-
getaddrinfo実装の違い
-
TTLを無視するresolver
- DNSレコードのTTLを5分に設定しても、一部のresolverはそれを無視して24時間のように長くキャッシュすることがある
-
nginx設定の問題
- nginxを誤って設定すると、DNSレコードを永遠にキャッシュしてしまうことがある
-
Kubernetes ndots
- ndotsはKubernetes DNSを遅くする可能性がある
落とし穴を共有し文書化する方法
- 奇妙な落とし穴に関する知識は得にくく、人々が同じ問題を何度も再発見しなければならない状況は非効率である
- あるテーマを説明するとき、よくある落とし穴も一緒に触れてくれると非常に助かる
- コミュニティがよくある落とし穴を集めておく方法も有用である
- DNSの落とし穴を文書化するのは、ユーザーごとに遭遇する問題が異なるため難しい面もある
- 3年に1回だけ個人ドメインのDNSを設定する人と、トラフィックの多いドメインのDNSを運用する人では、遭遇する落とし穴が異なることがある
まれな利用と実験の難しさ
- 多くの人はDNSを非常にまれにしか扱わない
- 3年に1回しかDNSに触れないなら、学びにくいのも自然である
- 「ネームサーバー変更手順」のようなチートシートが役立つことがある
- DNSは、自分のドメインを壊してしまうかもしれないという負担から、実験するのが怖い技術でもある
1件のコメント
Hacker News の意見
この記事には同意しない。DNSは時間をかけて学ぶ人が少ないだけで、実際に学ぶのが難しいものではないと思う
DNSの良いところは、問い合わせに対してシステムが自分の内部状態を教えてくれる点にある。既知のゾーンについてDNSサーバーを調べれば動作を理解しやすく、
digのような無料ツールも広く利用できるこれまでのキャリアで一緒に働いた人たちが、いつも私のDNS知識をいちばん覚えているのには驚かされる。自分では神秘的なことや特別なことを知っているとは思っていないからだ。DNSは非常によく標準化されており、一般的なサーバーやクライアント実装も標準に厳密に従っていて、無料ツールで観察するのも簡単だ。努力と時間が必要なだけで、本当に難しいわけではない
以前は「いや、実は簡単ですよ!」という言葉は、「学ぶのが難しい」という話に対する励ましだと思っていた。DNSは好きだし、多くの面で驚くほど単純だとも思っている。たとえば https://implement-dns.wizardzines.com では、簡単なPythonコードでおもちゃのDNSリゾルバーをゼロから実装する方法を示している
しかし時間がたつにつれ、「いや、学ぶのは簡単ですよ!」は「あなたにもできます!」という励ましというより、「難しいのではなく、あなたが頭が悪いだけです」のように受け取られることが多いのだと学んだ。何年も混乱していたテーマについて「実は簡単なんですけどね?」と言われても、あまり助けにはならない
だから今はそう言わず、人々がなぜ特定のものを難しく感じるのかを理解し、その障壁を下げることに多くの努力を注いでいる
BINDは役割は見事に果たすが、設定ファイルはいまひとつで、マニュアルは長くて堅苦しく、ときに不要に複雑だ。
digは強力だが、80カラム端末を使っていた時代のようにあらゆるものを省略する。DNSの問題をデバッグするとき、digよりWiresharkのほうが良いツールだったこともあるPowerDNSやほかのモダンなDNSサーバーを使わせれば、動作するDNSサーバーをずっと楽に設定できると思う。良いモダンなDNSクライアントはよく知らないので、結局
digに慣れてしまった。ipコマンドの--colorフラグを使う立場としては、digのようなツールももっと現代的な出力をしてくれるといい。コマンドラインフラグはエイリアスにまとめておくので、機能だけ入れてほしい本気で言うが、
MSG SIZE rcvd: 71は省略する必要がなかった。flags: qr rd raも展開して書けたはずだ。行頭のセミコロンが何を伝えようとしているのかも分からないし、むしろ混乱を招くだけだ用意された資料でDNSを学ぶ人が混乱するのは不思議ではない
「少しの努力と時間が必要なだけ」なら、どれほどの努力と時間が必要なのか。このスレッドの何人もがサーバーを実装しながら学んだと言い、理解するのに数か月かかったと言ったうえで、「いったん理解すればかなり簡単だ」と繰り返している。ならば、これほど普遍的で概念的には単純なものにしては、実際には学ぶのが難しいという点で合意できるのではないか
たとえば、ブラウザがDNSエントリをキャッシュし、期限切れにするルールは何か。そのルールはブラウザ間で一貫しているのか?
この記事は核心をよく突いていると思う。DNS自体は難しくないが、現実世界のDNSを学ぶのは難しい。問い合わせを行い、意図して期待した結果を得るまでの途中の多くが隠されているからだ
かつての基本的なインターネット接続方式は、インターフェースが1つ、ゲートウェイが1つ、DNSサーバープロバイダーが1つだった。今ではLTEとWi-Fiのように複数のWANへ同時に接続されることもあり、ユーザーには実際にどの名前解決経路が使われたのか分かりにくい。ブラウザだったのか、システムCライブラリの標準インターフェースだったのか、途中のローカルリゾルバーや再帰リゾルバーだったのか、ローカルキャッシュがあるのか、デフォルトで特殊なオプションを付けるのかまで不明確だ
すべてが動作していても、あるアプリケーションの問い合わせと応答が別のアプリケーションと同じ経路を使ったと盲目的に信じることはできない。3つのブラウザがそれぞれ別の方式を使い、OSもまた違った動作をし、そこにmDNSが5つ目の選択肢を追加することもある
コンピューターサイエンスで難しい問題は、キャッシュの無効化と名前付けの3つだけだ、というジョークがある
そしてDNSは、物の名前のためのキャッシュシステムだ
https://reddit.com/comments/15c2ul2/comment/jtty9dy
世界規模で管理されており(IANA)、階層的で、連合型で、変更もしやすい
DNSは、簡単そうに見える度合いと、実際に露呈する難しさの間に不一致があるタイプの技術です。
私たちは毎日DNSを使っていて、とても簡単に見えます。日常的なDNSの言葉は、ドメイン名、ルックアップ、IPアドレスです。この言葉がブラウザにそのまま露出しており、その露出を通じて動作のメンタルモデルを作ることになります。
しかし内部には、ゾーン、リゾルバ、委任された権限、トップレベルドメインの後ろに付く奇妙なドットのような、まったく別の言葉があります。
たとえば
host.example.co.ukが何を意味するかは私たちのどちらにも分かりますが、末尾にドットがないと、リゾルバがhost.example.co.uk.example.co.ukを検索しようとすることがあります。Windowsのデフォルト設定では、この場合
host.example.co.uk.example.co、host.example.co.uk.example、再びhost.example.co.uk.example、そしてhost.example.co.uk.を試して結果を得ることもあります。ただし実際に最初の試行をするWindowsは見たことがなく、この挙動は、DNSが連合した怪物のようなActive Directoryを持つ大企業環境に対応しようとして設計されたもののように思えます。最近のブラウザは、ユーザーの同意なしに**DNS over HTTPS(DoH)**サーバへこっそり向かい、いろいろ怪しい相手と付き合う可能性が高いです。DNSルックアップは基本的なデータなので、ISPはユーザーがどこへ行くのかを見るのを好んでいました。OSベンダーも当然「テレメトリ」を送れます。Googleはデスクトップを所有してはいませんがブラウザを所有しているので、ユーザーが設定したDNSの代わりに「安全な」DNSサーバを使わせることができれば、自分たちにとって都合がよいのです。こうした小細工のおかげで、ITのトラブルシューティングは以前よりずっと刺激的になりました。
末尾のドットについては、あまり心配しなくても構いません。どうせ、自分が使っていると思っているDNSサーバを使っていない可能性がほぼ確実だからです。DoHがなぜ作られたのかは理解していますし、一部の一般ユーザーには使う理由もあります。たとえばIT専門家ではない人が悪意あるWiFiホットスポットを使う場合、ブラウザが安全に本拠地へ戻ってDNSルックアップを行えば、ある程度は保護されます。しかし、ブラウザベンダーがユーザーのエンドポイントセキュリティの選択を踏みにじってよいかどうかは別問題です。
DNSは単にアドレスを引くことよりはるかに複雑です。今ではお金の問題であり、実際には2000年ごろからずっとそうでした。今では、ユーザーを通じて誰が利益を得るかを決めたがる、非常に頑固な巨大企業がたくさんあります。
DNS自体は簡単です。組織に従属しない情報分散は本当に厄介です。
数年前、自分がDNSを断片的にしか理解していないことに気づきました。
dig(1)、BIND、再帰DNS解決がどう動くかというCS101レベルの概念は知っていましたが、些細ではないシステムを設計・実装したり、動かないシステムをデバッグしたりするのに必要な実務知識が足りませんでした。そこで『DNS and BIND』をほぼ最初から最後まで読み、あまり重要でない個人Webサイトをいくつか運用するために、実際にBINDサーバも設定しました。難しくはありませんでしたが、かなりの時間投資は必要でした。BINDが多くのユースケースにとって正解というわけではありませんが、DNSの多くの概念や用語はいまだにBINDに由来しているため、非常に価値がありました。
こういうことを学ぶうえで、本は過小評価されていると思います。Webで見つかる資料はたいてい、再帰問い合わせのブロック図のような高レベルの理論か、
digで再帰問い合わせを行う方法のようなタスク中心の資料か、ローカルDNSクライアントの再試行ポリシーを理解するためにソースを読むような低レベルの資料です。各ピースとそれらがどう噛み合うのか、何を達成しようとしているのかから、キャッシュがどこにあるのかといった実装まで理解するには、本でよく見られる全体的なアプローチに代わるものはほとんどありません。Webにもまったくないわけではありませんが、まれです。すべてのIT担当者は、DNS問題のデバッグに関する実務知識を持っておくとよいです。
DNSは歴史的に重要なセキュリティ脆弱性の経路であり、今後もそうであり続ける可能性が高いです。こうした脆弱性は、SMTPのようなほぼすべての他のプロトコルへの攻撃経路につながります。HTTPSで使われる認証局システムでさえ、基本的には安全でないプロトコルに大きく依存しています。銀行がOVではなくDV証明書を買っていたら、気づけるでしょうか。おそらく無理でしょう。
だから、興味の足りない人にとってDNSが学びにくく見えることは、必ずしも悪いことではありません。今でも、ポートランダム化、キャッシュ汚染、AXFRのようなものの歴史をきちんと理解する時間をかけずに、DNS関連機能を作っている人たちを見かけるからです。
恥ずかしいサイドプロジェクト宣伝をすると、記事ではDNS解決に「デバッグ」モードがあるとよいと言っていましたが、ComfyDNSのWeb UIにはその機能があります :3
https://comfydns.com/
上のほうに
TRACE google.com A INと書かれた図がその機能です。ComfyDNSは、個人的なかゆいところに手が届くようにするプロジェクトでもあります。bind9のゾーンファイルを手で直すのに疲れていましたし、DNSがどう動くのかも気になっていました。表面的なことは知っていましたが、細部は分かっていなかったので、RFCを「最初から」実装しました。nettyは使いましたが、DNSライブラリは使いませんでした。かなり楽しかったです。
サイトがトラフィックに耐えられず落ちたらご容赦ください。Oracle Cloudの無料枠で動いているRailsアプリです。
よく聞くジョークは、DNSはコンピュータサイエンスで最も難しい2つの問題、つまり名前付けとキャッシュ無効化を組み合わせたものだ、というものです。
難しい種類のキャッシュ無効化ではありません。実際、「無効化」する必要はほとんどありません。
サーバ側でも、しばらくの間、古いバージョンと新しいバージョンを混ぜて返すことは完全に許容されます。
またこういう記事が出てきた、という感じ。1990年代はインターネットがもっと小さく、コンピュータはずっと遅く性能も低かったが、私たちはごく簡単に学んでいた。
当時のISPにとって DNS, LDAP, SMTP, IMAP のようなものは基本中の基本で、人々は実際にRFCのような公式文書を読んでいた。インターネット上でサーバーを運用するには学ぶ必要があり、少し時間を投資すれば、つまり職場で支払われる有給の時間を使えば学べた。
最近の開発者やDevOps世代には忍耐力や主体性がなく、口移しで教えてもらうことを期待し、StackOverflowや価値の低いブログから何でもコピーして貼り付ける。インターネットを支えている基盤を学ぶ代わりに、その週の最新流行のラッパーツールを手に取り、ひどいブログの指示に従って、全部崩れて会社に大金を失わせると不公平だと言う。インターネットで実際にどう動いているのかという基礎を学ぶ時間をかけていないからだ。
こういうことをずっと見てきた。実際、それほど難しくない。宿題をすればいい。
難しくない。DNSはあまり変わっていない数少ない技術の一つで、動作もかなり直感的。
digは少し紛らわしいことがある。古いnslookupより機能は多いが、直感的ではない。ちなみにnslookupは今でもちゃんと動く。若い業界人がDNSや中核プロトコルに戸惑う理由の一つは、今ではあまりにも多くのものが「ただ動く」ようになっているからだと思う。
例えば最近のWiFiルーターは箱から出せばすぐに「ただ動く」。2000年代初頭には、そういうものを設定するにはDNS、IP、Ethernet、RFC1918、実際のルーティングプロトコルやその他多くのことを知るネットワークエンジニアが必要で、なぜそう設定したのかもよく分かっていたはずだ。
クライアント視点のDNSが分かりにくいと思うなら、BINDの設定をしてみるといい ;-)
/老いた首ひげのぼやき
WRT54GのDHCPサーバーが、正しい名前解決のためにドメインコントローラーの固定IPをDNSサーバーとして配るようにすべきだったのに、単にIPアドレスとhostsファイルの項目で全部動くようにしていた。ドメインのMXレコードもルーターのWAN IPに設定していて、PTRレコードはなかった。振り返ると、メール配送があれほど円滑だったのは奇跡だ。
数年後、DNSが実際にどう動くのかを知り、20代前半には、すべての外部向け企業ドメインゾーンのネームサーバーとしてBINDを使う社内イントラネットを引き継いだ。信頼性を高めるためにこの構成をVPSへ移しながら、ゾーン転送やSOAなどを本当にたくさん学んだ。その経験には感謝しているが、今ではほとんどすべてが代わりに処理されるので、価値の低い作業になっている。良くも悪くも「IT」は「ソフトウェアエンジニアリング」と同じようには評価されない。
FirefoxがDNS-over-HTTPSをデフォルトで有効にするアップデートを出したときのことは忘れられない。私たちはDHCPでワークステーションに内部DNSサーバーを配っていたのに、突然「メールが消えました!全部壊れました!」という声が殺到した。内部WebメールとイントラネットWebサーバーが、まるで消えたように見えた。
何が起きたのか把握するのに、必要以上に長くかかった。理由の一部は「DNSなのに、なぜ突然壊れる?」という思い込みだった。しかしMozillaがこの簡単に予測できる問題を想定していなかったのは、かなり明らかだ。
例えば
thing.behind.cdn.itを問い合わせると、私はある答えを受け取り、別の人は同じ名前に対して別の答えを受け取る。それ自体はかなり明白だが、誰かが「thing.behind.cdn.itについてファイアウォールに穴を開けてもらえますか?」と合理的に尋ねると、複雑になる。あるサーバーはリクエストを転送し、あるサーバーは委任し、あるサーバーは代わりに問い合わせ、あるサーバーはそうしない。クライアントの検索ドメインの魔法もあり、クライアントや内部リゾルバーライブラリがTTLを守るかどうかも不確実だ。
レコードの種類も無数にあり、ときにはサーバーがUDPではなくTCPで接続し直すよう求めることもある。
だからDNSはかなり複雑だ。非常によく動作し、厄介な部分の大半が「だいたいただ動く」ものへ抽象化されているため、単純に見えるという錯覚がある。
DNSと、その下にある
ethtoolやEthernetフレームのようなものまで含め、ネットワーキングを高いレベルで理解する自信がずっと増したのは驚きだった。低いレイヤーから理解するのが好きで、大学ではコンピュータサイエンスではなく電気工学を選んだので、もしかすると驚くことではないのかもしれない。
DNSの原理は、再帰的だと理解すればそれほど難しくない。ただしセキュリティを考慮して設定し、適切なインフラを整え、最後の細部まで合わせようとすると、学ぶべきことは多い。BINDを除いて言えば、それほど難しくはない。