DNS とは、URL を開いてから画面が出るまで

回 4-4 道 4 ネットワークと暗号

DNS は、www.example.com のような名前を、通信に使う IP アドレスに引く (名前解決する) 仕組みです。ブラウザは近くのリゾルバー (代わりに調べる係) に聞き、リゾルバーはルート、.com の担当、その名前の権威サーバーの順にたどって答えを持ち帰り、TTL の秒数だけ覚えておきます。引いた IP アドレスへ TCP でつなぎ、HTTP の要求を送ると、画面の元になる HTML が返ります。

名前を住所に引く DNS と、その住所へ頼みごとを送る HTTP を、URL を開いてからの順番の中で切り分けられるようになります。

URL を開いてから画面が出るまで、何が起きているのか

URL を開くと、ブラウザは名前を IP アドレスに引き (DNS)、その住所へつなぎ (TCP)、頼みごとを送って (HTTP)、返ってきた HTML を画面に描きます。

https://www.example.com/news?id=7 を開いてから画面が出るまで、裏で何がどの順に行き来しているか、言えるでしょうか。

手がかりは、相手を指すのが名前ではなく IP アドレス (ネットワークの上の住所の番号) だということです。人は www.example.com のような名前 (ドメイン名) を覚え、機械は 203.0.113.20 のような番号で相手を探します。この 2 つを結ぶのが DNS (Domain Name System) です。道筋は次の 5 段です。

  1. URL を部品に分け、名前とポート (つなぐ先の番号) を取り出す
  2. DNS で名前を IP アドレスに引く
  3. その IP アドレスへ TCP でつなぐ
  4. HTTP の要求を送り、応答を受け取る
  5. 返ってきた HTML を画面に描く
HTTPリクエストの旅

DNS と HTTP はどう組み合わさっているのか

DNS は「どこへ」を決め、HTTP は「何をしてほしいか」を伝えます。

URL を部品に分ける

URL は部品の並びで、RFC 3986 (インターネットの決まりの文書) は scheme、authority (名前と番号)、path、query、fragment に分けています。

部品例使い道
schemehttps話し方の決まり
ホスト名www.example.comDNS で引く名前
ポート省略 (443)つなぐ先の番号
path と query/news と id=7サーバーに頼む中身
fragmenttop頁の中の位置

ポートを書かないときは、RFC 9110 の決まりで http は 80、https は 443 です。fragment はサーバーに送られません。DNS に渡るのはホスト名だけです。

DNS で名前を IP アドレスに引く

名前解決は、手元から順に、答えに近い所へ下りていく作業です。

  1. ブラウザと OS が、手元に覚えている答えを探す
  2. 無ければ、プロバイダなどのリゾルバーに頼む
  3. リゾルバーはルートサーバーに聞き、.com の担当の住所を教わる
  4. .com の担当に聞き、example.com の権威サーバーの住所を教わる
  5. 権威サーバーに聞き、IP アドレスの答えをもらう
  6. リゾルバーは答えをブラウザに返し、決められた秒数だけ覚える

上の段は「その下は誰が担当か」だけを知り、答えそのものは一番下の権威サーバーが持っています。問い合わせは、RFC 1035 の決まりで UDP か TCP の 53 番へ送ります。

名前から住所を調べる階段

リゾルバーと権威サーバー、再帰と反復

DNS のサーバーは、答えを探して回る係 (リゾルバー) と、答えを持つ係 (権威サーバー) に分かれます。

役すること
リゾルバー (キャッシュ DNS サーバー)上から順に聞いて回り、答えを覚える
ルートサーバー.com や .jp の担当を教える
TLD の担当その下の権威サーバーを教える
権威サーバー名前の答えそのものを持つ

RFC 1034 は、頼まれたサーバーが最後まで探して答えだけを返すやり方を再帰、「次はあちらに聞いて」と行き先だけを返すやり方を反復と呼びます。ブラウザはリゾルバーに再帰で頼み、リゾルバーは権威サーバーまで反復でたどります。再帰を頼むときは、頭の RD という 1 ビットを立てます。

キャッシュと TTL

引いた答えは、ブラウザ、OS、リゾルバーが、答えに付いた TTL (Time To Live、覚えてよい秒数) の間だけ覚え、その間は上の段に聞きに行きません。RFC 1035 は、TTL を 32 ビットの秒数とし、0 ならその場限りで覚えないと定めています。TTL が長いほど問い合わせは減りますが、サーバーを引っ越したとき、古い番号が残る時間も長くなります。

レコードの種類

DNS の答えはレコードという単位で、同じ名前に型の違う物を何種類も置けます。型の番号は RFC 1035 と RFC 3596 (AAAA) が決めています。

型番号中身
A1IPv4 アドレス
NS2権威サーバーの名前
CNAME5別名の元の名前
PTR12番号から名前を引く (逆引き)
MX15メールを受けるサーバー
TXT16自由な文字列
AAAA28IPv6 アドレス

CNAME は「あちらの名前の別名です」という答えで、受け取った側はあちらを引き直します。RFC 1034 は CNAME を置いた名前に他のデータを置かないと定めるので、NS や MX を持つ example.com そのものには置けません。メールを送る側は、宛先の @ の右の名前の MX を引きます。

同じ名前に、形の違う答えが何種類も付く

TCP でつなぎ、HTTP で頼む

IP アドレスが分かると、ブラウザはその 443 番 (https) か 80 番 (http) へ TCP でつなぎ、HTTP の要求を送ります。TCP は、つなぐ前に three-way handshake (3 回のやり取り) で互いの準備を確かめます (RFC 9293、くわしくは 4-3)。

HTTP/1.1 の要求は文字の行の並びです。RFC 9112 は、1 行目を「メソッド、対象、版」とし、行の終わりを CR と LF の 2 字にし、頭 (ヘッダー) の後ろに空の行を置くと定めています。メソッドは受け取る GET、中身を送る POST などです。応答の 1 行目は「版、状態の番号、理由の言葉」で、RFC 9110 は番号の 1 桁目が 2 なら成功、3 は別の場所へ、4 は頼み方の誤り、5 はサーバーの失敗と決めています。

https では、同じ HTTP の文字列を暗号にくるんで送ります。暗号化は 4-5 で扱います。

動かして確かめる

通信はせずに、手元で 1 段ずつ確かめます。まず URL を分けます。

動かす URL を部品に分ける

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

scheme   https
hostname www.example.com
port     None
path     /news
query    id=7
fragment top
先 www.example.com 443

ポートは None なので、https の既定の 443 につなぎます。

次に、リゾルバーへ送る DNS の問い合わせを、RFC 1035 の形でバイト列に組みます。頭は 2 バイトの欄が 6 つで 12 バイト、名前は「長さ 1 バイト、その長さの字」を点ごとに並べ、長さ 0 のバイトで終えます。

動かす DNS の問い合わせを組む

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

頭 12
12 34 01 00 00 01
00 00 00 00 00 00
問い 21
b'\x03www' b'\x07example'
全部 33

12 34 は問い合わせの番号 (ID)、01 00 は旗で RD の 1 ビットだけが立ち、00 01 は問いが 1 つという意味です。名前は 03 www、07 example、03 com、00 の 17 バイトで、型とクラスの 4 バイトを足して 21 バイトです。> は上の桁から並べる指定 (ビッグエンディアン) です。

続けて、リゾルバーの答えを読みます。バイト列は手で書いた例です。

動かす DNS の答えを読む

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

ID 0x1234
答え? 1
RD 1 RA 1
RCODE 0
問い www.example.com
名前の印 0xc00c
型 1 TTL 300 秒
IP 203.0.113.20

ID が問いと同じ 0x1234 なので、どの問いへの答えかが分かります。旗の一番上のビットの 1 は答え、RA の 1 は再帰を引き受けるという意味、RCODE (結果の番号) の 0 は誤り無しです。答えの名前の欄の c0 0c は、上の 2 ビットが 1 なので「12 バイト目の名前と同じ」という印 (圧縮) です。答えは 203.0.113.20 で、300 秒は覚えてよいと付いています。

最後に、HTTP の要求と応答を組んで分けます。

動かす HTTP の要求と応答を分ける

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

69 バイト
GET | /news?id=7 | HTTP/1.1
HTTP/1.1 200 OK
Content-Type = text/html
Content-Length = 13
13 <h1>News</h1>

要求に fragment の top は入っていません。応答は空の行で頭と中身に分かれ、Content-Length の 13 は中身の字数と一致します。

どこで崩れるか

DNS のキャッシュは、エラーを出さずに古い答えを返し続けるという崩れ方をします。

引っ越した後も、TTL の間は古い番号が返る

リゾルバーの覚え方を辞書で模します。時刻は秒の数を手で渡します。

動かす TTL のキャッシュを模す

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

0 203.0.113.20 問い合わせ
10 203.0.113.20 手元
120 203.0.113.20 手元
200 203.0.113.20 手元
299 203.0.113.20 手元
300 198.51.100.7 問い合わせ
問い合わせ 2 回

6 回引いて、聞きに行ったのは 0 秒目と 300 秒目の 2 回だけです。途中で答えを替えても、299 秒目までは古い番号が返りました。古いサーバーを先に止めると、この間は開かないサイトになります。

名前の長さには上限がある

RFC 1035 は、点で区切った 1 つの部分 (ラベル) を 63 バイトまで、名前全体を 255 バイトまでと定めています。長さの 1 バイトの上の 2 ビットを圧縮の印に使うので、ラベルの長さは 6 ビットで書ける 63 までです。数え方は、上の qname と同じく、ラベルごとに長さの 1 バイトと、終わりの 1 バイトです。

動かす 名前の長さの上限

python実行可能
出力

▶ 実行ボタンを押すと結果がここに表示されます

実行すると、次の通りに出ます

OK 68
NG ラベル 64
NG 名前 306

64 字のラベルは組めず、60 字を 5 つつなぐと 306 バイトで 255 を超えます。サブドメインを自動で作る仕組みは、この上限で崩れます。

崩れる前提は、ほかに次の 2 つです。

  • IP アドレスにつながればサイトが出る、という前提。RFC 9112 は Host の行の無い要求に 400 を返すと定めている
  • 引いた答えは本物だ、という前提。偽の答えがキャッシュに入ると、TTL の間は偽の番号へ案内される (下の実例)

仕事でどう確かめるか

仕事では、どの段で止まっているかを段ごとに確かめます。

1 つ目は名前が引けるかです。端末で dig www.example.com A を打つと、答えの番号と残りの TTL が出ます。+trace を付けるとルートから順にたどる様子が見えます。ブラウザが覚えている答えは、Chrome なら chrome://net-internals/#dns で見て消せます。

2 つ目は HTTP の番号です。curl -v に URL を渡すと、送った要求と返った番号と頭が出ます。

3 つ目は引っ越しの段取りです。替える前に TTL を短くし、古い TTL の秒数が過ぎてから番号を替えます。

関わる実例

DNS が崩れると、サーバーが元気でも誰もたどり着けません。

DNS のキャッシュに偽の答えを入れる穴 VU#800113 (2008 年 7 月 8 日)

米国の CERT/CC は 2008 年 7 月 8 日、多くの DNS の実装が、キャッシュに偽の答えを入れる攻撃 (キャッシュポイズニング) に弱いと公表しました。問い合わせの ID は 16 ビットしかなく、送り元のポートを固定した実装では、ID さえ当てれば偽の答えを受け取らせられます。CERT/CC は、攻撃の実用性を示した人として Dan Kaminsky の名を挙げ、送り元のポートを問い合わせごとに散らす直しを勧めました。崩れた前提は「ID の合う答えは本物だ」です。

Meta の DNS に外から届かなくなった障害 (2021 年 10 月)

Meta の技術ブログは 2021 年 10 月 5 日、前日の障害の中身を公表しました。保守の作業で出した命令がデータセンターを結ぶ基幹の網をすべて切り、DNS の権威サーバーは自分が不健全だと判断して、自分への道筋の広告 (BGP) を取り下げました。サーバーは動いていたのに、外から届かなくなりました。崩れた前提は「権威サーバーが動いていれば名前は引ける」です。

よくある問い

DNS の役割は何ですか

DNS の役割は、人が覚える名前を、機械が使う IP アドレスに引けるようにすることです。IP アドレスは番号そのもので、DNS は名前から番号を引く仕組みです。番号が変わっても、利用者は同じ名前のままたどり着けます。

DNS の設定はどうすればいいですか

自分の名前でサイトを出すときは、名前を買った会社 (レジストラ) か DNS の会社の管理画面で、権威サーバーに A や CNAME のレコードを登録します。権威サーバーを自前で立てるのは、運用の手間を引き受けられる場合です。パソコンやルーターの DNS の設定は、どのリゾルバーに聞くかを決める物で、サイトの答えの登録とは別です。

1.1.1.1 の DNS とは何ですか

1.1.1.1 は、Cloudflare が運用する公開のリゾルバーの番号です。パソコンやルーターの設定で、聞く先をここに替えられます。替わるのは代わりに調べる係で、サイトの権威サーバーの答えは変わりません。

DNS は安全ですか

もとの DNS の問い合わせと答えには暗号も署名も無いので、上の実例のように、偽の答えをキャッシュに入れる攻撃が知られています。対策には、送り元のポートを散らす実装の直しや、答えに署名を付ける DNSSEC があります。

確認クイズ

答えだと思う選択肢を押すと、その場で正誤と理由が開きます。4 問すべてに正しく答えると、この回は修了で、石が緑に変わります (この端末のブラウザに残ります)。間違えた問いは、あとから解き直せます。

1 問目

キャッシュに何も無いとき、リゾルバーが www.example.com を引くために聞いて回る順はどれですか。

2 問目

このコードを動かすと何が出ますか。

名前を長さ付きで並べたバイト数

name = "www.example.com"
labs = name.split(".")
n = sum(map(len, labs))
print(n + len(labs) + 1)

3 問目

DNS の答えに付く TTL が 300 のとき、正しいのはどれですか。

4 問目

HTTP の応答の状態の番号が 404 でした。どの段まで進めたと言えますか。

説明課題

ブラウザに https://www.example.com/news を打ってから画面が出るまでを、URL、リゾルバー、権威サーバー、TTL、TCP、GET、200 の言葉を使って、5 行で順に説明してください。書いたら、下の模範解答を開いて比べてください。

模範解答

自分の説明を書いてから開いて、比べてください。

この回の先の一歩

Web の仕事では、サイトが開かないときに、名前が引けないのか、つながらないのか、HTTP の番号が悪いのかを分けて探します。この回の順番が、その切り分けの地図になります。

もっと深く

この回の続きを、ゆめさくのコースの章や道具で深められます。頁の中の確認クイズに答えたあと、手を動かす量を増やしたいときに使ってください。

一次資料

どれも 2026年10月27日に開いて、題と中身を確かめました。

次へ

道 4 ネットワークと暗号の回

  1. 4-1層に分けて考えるOSI、TCP/IP、パケット頁で読む
  2. 4-2IP とサブネットIP アドレス、CIDR、ルーティング頁で読む
  3. 4-3TCP と UDP再送、輻輳制御、ポート頁で読む
  4. 4-4HTTP と DNSHTTPS、HTTP/3、名前解決この回
  5. 4-5TLS と暗号の基礎共通鍵、公開鍵、ハッシュ、署名頁で読む

道 4 の頁へ戻るほかの道を見る