Webアクセスの裏側を見てみよう ― DNSからHTTPS、Webサーバーまでの基本

Webアクセスの裏側を見てみよう ― DNSからHTTPS、Webサーバーまでの基本

田中

 

HTTP(HTTPS)通信の流れ

ユーザーがPCのブラウザーで、以下のようなURLにアクセスする場合、裏では次のような処理が行われています。

アクセス先URL:http://www.example.jp/example.html

① DNSでIPアドレスを調べる(名前解決)

PCからWebサーバーへの通信は、実際にはTCPパケットとして送信されます。TCP/IPの通信はIPアドレスで行われるため、まずはURLのホスト名部分(www.example.jp)のIPアドレスを取得する必要があります。

そこでブラウザーは、PCのネットワーク設定にあるDNSサーバーへ「www.example.jp」のIPアドレスを問い合わせます。たとえばPCのDNSが社内ルーター(192.168.0.1)になっている場合、イメージとしては以下のコマンドと同じ問い合わせが行われます。

nslookup www.example.jp 192.168.0.1

社内ルーターのDNS(192.168.0.1)は、当然 example.jp のDNSレコードを持っていないので、上位のDNSサーバー(プロバイダーのDNSなど)に問い合わせを依頼し、最終的に「example.jp のゾーン情報を持ったDNSサーバー(権威DNSサーバー/ネームサーバー)」を探しにいきます。

では、この「ゾーン情報を持ったネームサーバー」はどのように探すのかというと、ルートDNSサーバー → 「.jp」を管理するDNSサーバー → example.jp のネームサーバーと、上の階層から順番に「委任(NSレコード)」をたどっていきます。example.jp のネームサーバーまでたどり着いたら、そのゾーン内にある「www」というホスト名のIPアドレスが取得できます。

この「どのネームサーバーに委任されているか」は、Whois(ドメイン名登録情報の検索サービス)でも確認することができます。

※Whoisでネームサーバーを確認する例

JPドメインの場合は、JPRSのWhoisサービス(https://whois.jprs.jp/)で以下のように検索ができます。
※comなど、その他のTLDはそれぞれのWhoisサービスへの問い合わせとなります。

当社ドメイン(pageone.ne.jp)のネームサーバーは、以下の赤枠の部分となります。

なお、上記のネームサーバーもホスト名形式なので、「ではネームサーバー自体のIPアドレスはどうやって取得するのか?」という疑問があると思います(卵が先か、鶏が先か…みたいな話です)。

ネームサーバーのホスト名(ns1-04.azure-dns.com など)も、同じように上位からの委任をたどって名前解決されます。また、ネームサーバーが自分自身のゾーン内のホスト名(例:example.jp のネームサーバーが ns1.example.jp)の場合は、上位(.jp)側にネームサーバーのIPアドレスを直接登録しておく「グルーレコード」という仕組みがあります。これにより、ぐるぐる循環することなく、ネームサーバーのIPアドレスへ名前解決ができるようになっています。

こうして、example.jp のネームサーバーから www.example.jp のIPアドレスが取得できます。

nslookup www.example.jp
→ 203.0.113.10 (※説明用のアドレスです)

② Webサーバーへリクエストを送る

取得したIPアドレスをもとに、以下のようなパケットが、www.example.jp のWebサーバーのTCP/80ポートに送信されます。

宛先IP:ポート 宛先ホスト名(Hostヘッダー) リクエスト内容
203.0.113.10:80 www.example.jp GET /example.html
(example.html の内容をください)

サーバー側の動作と仮想ホスト(Virtual host)について

サーバー側では、このリクエストを受信して example.html の内容を返答し、ユーザーのブラウザーに example.html の内容が表示されます。

なお、Webサーバーソフト(Apache HTTP Server、Microsoft IIS、Nginx など)では、同じサーバー(同じグローバルIP)で複数のサイトを運用している場合がほとんどです。そうしないと、サイトごとにIPアドレスを用意する必要が出てしまいます。

そこで、Webサーバーソフトには仮想ホスト(Virtual host)という機能があり、以下のように「ポート番号」と「宛先ホスト名」の組み合わせで、どのサイト(ドキュメントルート)を返すかを振り分けています。

<Virtual host 設定(例)>

ポート サーバー名(宛先ホスト名) ドキュメントルート
80 www.example.jp /home/www_example_jp/public_html
80 www.example02.jp /home/www_example02_jp/public_html
443 www.sslexample.jp /home/www_sslexample_jp/public_html
443 www.sslexample02.jp /home/www_sslexample02_jp/public_html

今回のリクエストは「ポート80」「www.example.jp」宛てなので、上記の設定から、Webサーバー内の以下のファイルをユーザーのブラウザーに返します。

/home/www_example_jp/public_html/example.html

ユーザーのブラウザーには、以下のURLが表示された状態で、example.html の内容が表示されます。

http://www.example.jp/example.html

HTTP通信とHTTPS通信の違いについて

ここまでは暗号化されていないHTTP(TCP/80)の通信を見てきましたが、これがHTTPS通信の場合はどうなるでしょうか?

※わかりやすくするため、HTTPS用には以下のホスト名を使います。

アクセス先URL:https://www.sslexample.jp/example.html

※www.example.jp、www.sslexample.jp はどちらも同じグローバルIPアドレス(203.0.113.10)が割り当てられているとします。

DNSの仕組みなどは同様で、TCPパケットの宛先ポートが「443」になります。

宛先IP:ポート 宛先ホスト名(Hostヘッダー) リクエスト内容
203.0.113.10:443 www.sslexample.jp GET /example.html
(example.html の内容をください)

HTTPSの場合、SSL/TLSの仕組みによって通信内容が暗号化されます。HTTPとの違いは、経路上から見たときに以下のようになる点です。

宛先IP:ポート 宛先ホスト名(Hostヘッダー) リクエスト内容
平文 暗号化 暗号化
203.0.113.10:443 www.sslexample.jp GET /example.html
(example.html の内容をください)

上記のとおり、ユーザーのPCからWebサーバー(Webサーバーソフト)までの通信では、「Hostヘッダー」と「リクエスト内容(URLのパスや、要求・応答の中身)」が暗号化されています。そのため、たとえば社内のハブやルーター、インターネット経路上などでパケットキャプチャができたとしても、どのページにアクセスして、どのようなやり取り(要求内容や応答結果)をしているのかは見られない状態となります。

当然ですが、TCP/IPのパケットはIPアドレスでルーティングされるため、宛先IPアドレスとポート番号は暗号化されていません。

ちょっと補足:接続先のホスト名は完全には隠れません

暗号化通信を始める最初の手順(TLSハンドシェイク)では、ブラウザーが「どのホスト名に接続したいか」をSNI(Server Name Indication)という項目でサーバーに伝えます。このSNIは通常は平文で送られるため、経路上からでも「www.sslexample.jp に接続している」ことまでは分かります(アクセスしたページのパスや内容は暗号化されているので分かりません)。また、事前のDNSの問い合わせも通常は暗号化されていません。

実はこのSNIのおかげで、同じIPアドレス・同じ443ポートで複数のHTTPSサイトを運用していても、Webサーバーはホスト名ごとに正しいサーバー証明書を選んで返すことができます。なお、SNIも暗号化するECH(Encrypted Client Hello)という仕組みも普及し始めています。

サーバー証明書の役割とWebサーバー側での復号

HTTPSで使われるSSL/TLS証明書(サーバー証明書)には、大きく2つの役割があります。

  • 接続先が本物の www.sslexample.jp であることを証明する(なりすまし防止)
  • 暗号化通信に使う鍵を、安全に取り決めるために使う

暗号化された通信は、Webサーバーソフト(Apache HTTP Server、Microsoft IIS、Nginx など)が、サーバー証明書と対になる秘密鍵を使って復号します。復号後はHostヘッダーが読めるので、HTTPのときと同じように仮想ホストの設定で振り分けて、

アクセス先URL:https://www.sslexample.jp/example.html

の example.html の内容をユーザーに返答します。

<Virtual host 設定(例)>

ポート サーバー名(宛先ホスト名) ドキュメントルート
80 www.example.jp /home/www_example_jp/public_html
80 www.example02.jp /home/www_example02_jp/public_html
443 www.sslexample.jp /home/www_sslexample_jp/public_html
443 www.sslexample02.jp /home/www_sslexample02_jp/public_html

なお、ここではユーザー → サーバー方向で説明しましたが、サーバー → ユーザー方向(応答)も同様の仕組みで暗号化されています。

あとがき

AIの利用なども含め、Webサービス、APIアクセスなど、さまざまなアプリ・機能間の通信のほとんどでHTTPSが使用されています。作業時に直接ここまでの理解が必要になることは少ないかもしれませんが、トラブルシュートや概要設計の検討などの際に、このあたりの仕組みの違いを知っておくことで、何かのお役に立てていただければと思います。

 

株式会社ページワン

〒030-0823
青森県青森市橋本二丁目13-5 グランスクエア青森 6F