0から分かるDNSと通信の裏側 〜URLを入力してから画面が出るまでの0.1秒〜
1. 3行でわかる結論と全体図
- インターネット上のコンピュータ同士は、「
google.com」のような名前ではなく、**「142.250.196.110」のような数字の住所(IPアドレス)**だけで通信しています。 - **DNS(ドメイン・ネーム・システム)とは、人間が覚えやすい名前を、コンピュータ用の数字の住所に変換してくれる「世界最大の電話帳(住所録)」**です。
- 1台の巨大なサーバーがすべて覚えているのではなく、右から順に「.(ルート)」→「com」→「google」とバケツリレーで聞き回ることで、世界中の何億台もの住所を0.01秒で特定しています。
2. なぜ生まれたか?(昔の不便と解決策)
インターネットが始まったばかりの1970年代、接続されていたコンピュータは世界に数十台しかありませんでした。
そのため、当時は**「hosts.txt」というたった1つのメモ帳**に、世界中のコンピュータの名前と数字の住所を手作業で書き込み、みんなでそのメモ帳をコピーして配り合っていました。
しかし、コンピュータの数が何万台、何百万台と爆発的に増えると、2つの致命的な問題が発生しました。
- 名前の重複:誰かが勝手に「apple」という名前を登録すると、他の人が同じ名前を使えなくなる。
- 更新の限界:毎秒のように世界中で新しいサイトが生まれるため、1つのメモ帳を全員に配り直す作業が完全にパンクした。
これを解決するために1983年に発明されたのが「DNS」です。 DNSは、住所を「右から左へ」階層(ピラミッド構造)に分けるルールを作りました。
www.google.co.jp- 1番右のグループ:
jp(日本)の担当係 - その次のグループ:
co(会社)の担当係 - その次のグループ:
googleの担当係 - 1番左の目印:
www(Webサーバー)
- 1番右のグループ:
このように担当を細かく分けたことで、世界中のサーバーが協力して分担管理できるようになり、今では全世界で毎秒何十億回ものアクセスを安全にさばいています。
3. 仕組みの種明かし(3つの重要ルール)
インターネット通信の骨格を理解するための、3つのキーワードです。
| 専門用語 | 小学生でもわかる例え | 実際にやっていること |
|---|---|---|
| IPアドレス | 機械用の「電話番号・住所」 | インターネットに繋がるすべての機器(PC、スマホ、サーバー)に割り当てられる「数字の識別番号(例: 192.168.1.1)」です。 |
| ドメイン名 | 人間用の「看板・表札」 | 数字の羅列だと人間が覚えられないため、「yahoo.co.jp」のように文字で看板をつけたものです。 |
| DNSキャッシュ | 手帳の「メモ書き」 | 毎回世界中に電話帳を問い合わせると時間がかかるため、1度調べた住所をスマホやルーターが数分〜数時間だけ手元にメモしておく仕組みです。 |
触って試す:DNS問い合わせステップ実行
📞 DNS問い合わせを1ステップずつ追ってみよう
「google.com」の住所(IPアドレス)を調べる旅です。「次へ」ボタンを押すたびに、問い合わせが次の係へ進みます。青が「いま聞いているところ」、緑が「終わったところ」です。
4. 作って暴く!(Google Colab 15分ミニ実験)
「本当に文字が数字の住所に変換されているのか?」「ブラウザを使わずに直接手紙を送るとどうなるか?」を、Pythonで実験してみましょう。 以下のリンクからGoogle Colabを開き、コードを実行してみてください。
実験①:電話帳(DNS)をめくり、ドメインの裏の住所を暴く
Pythonの通信部品(socket)を使って、普段見ている有名サイトの「本当の数字の住所」を引っ張り出します。
# === 実験①:DNSを使ってドメイン名を数字の住所(IPアドレス)に変換する ===
import socket
domains = ["google.com", "yahoo.co.jp", "wikipedia.org"]
print("--- 🔍 ドメイン名から数字の住所(IPアドレス)を検索 ---")
for d in domains:
# DNSサーバーに問い合わせてIPアドレスを取得する関数
ip_address = socket.gethostbyname(d)
# さらに詳しい情報(別名や複数のサーバー住所)を調べる
name, aliases, ip_list = socket.gethostbyname_ex(d)
print(f"\n【ドメイン名】: {d}")
print(f" 👉 代表のIPアドレス: {ip_address}")
print(f" 👉 控えている全サーバーのIP: {ip_list}")
実験①の種明かし
google.com などの大きなサイトを調べると、IPアドレスが何個も並んで表示されます。
これはアクセスが集中してもサーバーが落ちないように、電話帳の中に何台もの予備の住所を登録し、アクセスする人を自動で分散(ロードバランシング)させているからです。
実験②:ブラウザを使わずに、IPアドレスへ直接手紙を送る
ブラウザ(ChromeやSafari)が裏で何をしているかを完全再現します。 数字の住所に直接通信用のパイプをつなぎ、生の命令文(HTTPリクエスト)を手動で送り込んでみます。
# === 実験②:ブラウザなしでIPアドレスへ直接手紙を送り、画面データを奪う ===
import socket
# 1. 接続先ドメインから住所(IP)を取得
target_host = "example.com"
target_ip = socket.gethostbyname(target_host)
target_port = 80 # Webの標準ドア番号(HTTP)
print(f"1. 『{target_host}』の住所【{target_ip}】の {target_port}番ドアに接続します...")
# 2. ネットワークの通信パイプ(ソケット)を作成して接続
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_ip, target_port))
# 3. ブラウザがいつも送っている「手紙(HTTP GETリクエスト)」を手書きする
# ※ 「トップページの画面(HTML)をください」という英語の命令
request_letter = f"GET / HTTP/1.1\r\nHost: {target_host}\r\nConnection: close\r\n\r\n"
client.send(request_letter.encode())
# 4. サーバーから返ってきた返事を受け取る
response = b""
while True:
data = client.recv(1024)
if not data:
break
response += data
client.close()
# 5. 返ってきた生データ(HTML)の先頭を表示
print("\n--- 📨 サーバーから返ってきた生の手紙(最初の500文字) ---")
text_data = response.decode('utf-8', errors='ignore')
print(text_data[:500])
print("\n👉 ブラウザは、この英数字の塊(HTML)を受け取って、綺麗なWeb画面を描画しています。")
5. 現実世界での悪用と限界(次回への伏線)
インターネットの根幹を支えるDNSですが、誕生した当時は「世界中の技術者がお互いを信頼していた時代」だったため、致命的なセキュリティの穴がありました。
それが**「DNSキャッシュポイズニング(電話帳の書き換え攻撃)」**です。
もし悪いハッカーが、あなたが使っているDNSサーバーに嘘の情報を割り込ませて、
「my-bank.com(あなたの銀行)の住所は 123.45.67.89(ハッカーの偽サイト)だよ」
と嘘のメモを覚え込ませたらどうなるでしょうか?
あなたはブラウザのURL欄に正しく銀行のURLを入力しているのに、画面にはハッカーが作った本物そっくりの偽ログイン画面が表示され、IDとパスワードが盗まれてしまいます。
「相手から送られてきた住所や手紙は、途中で悪人にすり替えられていないか?」 「今通信している相手は、本当に本物の銀行なのか?」
この疑念を解決するために生まれたのが、**数学の「素数」を利用した現代暗号の最高傑作「公開鍵暗号」と、パスワードを過去のものにする最新技術「パスキー」**です。次回・第6回でその正体を暴きます。