IT の基礎

HTTP と TLS

Web の通信は、ブラウザが送るリクエストと、サーバーが返すレスポンスの 1 往復でできています。結果は 3 桁のステータスコードで返り、HTTPS では TLS が通信を暗号化し、証明書で相手が本物かを確かめます。

Web ページを開くとき、ブラウザはサーバーに「このページをください」というリクエストを送り、サーバーは結果をレスポンスで返します。この決まりが HTTP (HyperText Transfer Protocol) です。結果は 200 や 404 のような 3 桁のステータスコードで返ります。HTTP はそのままだと中身が途中で読めるので、今の Web では TLS で暗号化した HTTPS を使います。Google Cloud では、ロードバランサに証明書を置いて HTTPS を受ける構成が基本です。

URL は行き先を 1 行で書いたもの

https://www.example.com:443/search?q=gcp という URL は、次の部品でできています。

部品例意味
スキームhttps使う方式。http か https
ホストwww.example.comサーバーの名前。DNS で IP アドレスに変える
ポート443省略すると http は 80、https は 443
パス/searchサーバーの中のどのリソース (ページや画像、データ) か
クエリ?q=gcpパスに添える追加の条件

ブラウザはホスト名から IP アドレスを調べ、そのポートに TCP で接続してからリクエストを送ります。TCP とポートは前のページで扱いました。

リクエストとレスポンス

リクエストの 1 行目には、メソッド (何をしたいか) とパスを書きます。2 行目からはヘッダーと呼ぶ「名前: 値」の行が続き、送り先のホスト名や認証情報を載せます。データを送るときは、空行のあとに本文を付けます。レスポンスも同じ形で、1 行目がステータスコード、続いてヘッダー、空行、本文です。

ブラウザサーバーリクエストGET /index.html HTTP/1.1Host: www.example.comレスポンスHTTP/1.1 200 OKContent-Type: text/html<!doctype html> …
リクエストは「メソッドとパス、ヘッダー」、レスポンスは「ステータスコード、ヘッダー、本文」。どちらも 1 行目を見れば何が起きたかが分かる。

メソッド

メソッドは何十もありませんが、よく見るのは 4 つです (RFC 9110)。

  • GET: リソースを読む。ページを開くときはこれ
  • POST: データを送って、新しく作らせる
  • PUT: 指定したパスの中身を置き換える
  • DELETE: リソースを消す

ステータスコード

ステータスコードは、最初の 1 桁で大まかな結果が分かります。2 で始まれば成功、3 は別の場所へ案内 (リダイレクト)、4 は送った側の誤り、5 はサーバー側の失敗です。

コード名前いつ返るか
200OK成功した
201CreatedPOST などで新しく作った
301Moved Permanently別の URL に移った。Location ヘッダーで移転先を返す
401Unauthorizedだれからのリクエストか確かめられない (認証がない、または無効)
403Forbiddenだれかは分かったが、その人には権限がない
404Not Foundそのパスのリソースがない
500Internal Server Errorサーバーのプログラムが失敗した
502Bad Gateway間に立つサーバー (ロードバランサなど) が、奥のサーバーから正しい応答を得られなかった
503Service Unavailable混雑や保守で一時的に応じられない

401 と 403 は混同しやすいコードです。401 は「あなたがだれか分からない」(認証の失敗)、403 は「あなたには許可がない」(認可の失敗) です。認証と認可は認証、認可、暗号化で詳しく扱います。

下のシミュレーターで、メソッド、パス、認証を選ぶとリクエストが組み立てられ、サーバーが返すステータスコードと、そのコードになった理由が出ます。/admin に認証なし、一般ユーザー、管理者で送ると、401、403、200 と変わります。

試すリクエストを組み立てて送る

方式
メソッド

サーバーにあるパス: /index.html、/admin、/api/messages、/old-page

認証

URL: http://www.example.com/index.html

リクエスト (平文のまま送る)

GET /index.html HTTP/1.1
Host: www.example.com

レスポンス200 OK

HTTP/1.1 200 OK
Content-Type: text/html

<!doctype html><title>Example</title>…

/index.html はだれでも読めるページなので、本文を付けて 200 OK を返しました。

HTTPS は TLS で包んだ HTTP

HTTP のリクエストは文字のまま流れるので、同じ Wi-Fi にいる人や途中の機器から、パスワードや認証のトークンがそのまま読めます。書き換えられても気づけません。HTTPS は、HTTP の通信を TLS (Transport Layer Security) で暗号化したものです。TLS は通信を暗号化し、途中で書き換えられていないことを確かめ、相手が本物のサーバーかを証明書で確かめます。

HTTPブラウザ途中の機器サーバー平文平文トークンまで読めるHTTPSブラウザ途中の機器サーバー暗号文暗号文宛先しか分からない
HTTP と HTTPS で経路は同じ。違うのは、途中の Wi-Fi やルーターから中身が読めるかどうか。

TCP の接続ができたあと、リクエストを送る前に、ブラウザとサーバーは TLS のハンドシェイクで暗号の鍵をそろえます。今の版の TLS 1.3 (RFC 8446) では、ブラウザが使える暗号と鍵の材料を送り (ClientHello)、サーバーが暗号を選んで鍵の材料と証明書を返し (ServerHello と Certificate)、両側で同じ鍵ができたことを確かめます (Finished)。シミュレーターで方式を HTTPS に切り替えると、この段階がリクエストの前に出ます。

途中の機器から見えるのは、相手の IP アドレスとポート、多くの場合は接続先のホスト名など、届けるのに要る情報だけです。パス、ヘッダー、本文は暗号化されます。

証明書は「このドメインの持ち主」の証明

暗号化しても、相手が偽のサーバーなら意味がありません。そこでサーバーは証明書を見せます。証明書には、ドメイン名、サーバーの公開鍵 (暗号に使う鍵の片方)、有効期限が書かれ、認証局 (CA) と呼ぶ発行元が署名しています。ブラウザや OS には信頼する CA の一覧が入っていて、その CA の署名があり、ドメイン名が URL のホストと一致し、期限内なら本物とみなします。どれかが合わなければ、ブラウザは警告を出して接続を止めます。

証明書には期限があるので、更新を忘れるとサイトが警告で開けなくなります。Google Cloud では、更新を自動で行う Google マネージド証明書を選ぶと、この運用を省けます。

Google Cloud では TLS をロードバランサで終える

外部アプリケーションロードバランサに証明書を置くと、利用者からの HTTPS はロードバランサで復号されます (TLS の終端)。ロードバランサはその先のバックエンドに HTTP、HTTPS、HTTP/2 などで転送します。証明書は、Google が発行と更新を行う Google マネージド証明書か、自分で用意したセルフマネージド証明書から選び、Certificate Manager でまとめて管理できます。

利用者ロードバランサ証明書を持つVMバックエンドHTTPSHTTP などここで TLS を終える
証明書はバックエンドの VM ごとではなく、ロードバランサに 1 か所で置く。VM を増やしても証明書の管理は増えない。

試験では「証明書の更新の手間を減らしたい」「HTTPS で公開したい」という要件が出ます。どちらも、外部アプリケーションロードバランサと Google マネージド証明書の組み合わせが答えの候補になります。ロードバランサの種類はVPC の設計で扱います。

試してみる

Cloud Shell か手元のターミナルで curl に -v を付けると、通信の中身が見えます。* で始まる行に TLS のハンドシェイクと証明書 (発行元の CA、ドメイン名、有効期限)、> で始まる行に送ったリクエスト、< で始まる行に返ってきたレスポンスのステータスコードとヘッダーが出ます。

curl -v -o /dev/null https://cloud.google.com/

次のページDNSでは、URL のホスト名を IP アドレスに変える DNS を扱います。

理解度チェック

答えを開く前に、自分で考えてください。結果はこのブラウザにだけ残り、間違えた問題は復習のページでまとめて解き直せます。

思い出す

ステータスコードの 401 と 403 は、どちらもページが見られないときに返ります。2 つは何が違いますか。

状況で選ぶ

Compute Engine の VM 10 台で動く Web サイトを HTTPS で公開します。以前、証明書の更新を忘れてサイトが警告で開けなくなったことがあり、更新の手間をなくしたいと考えています。どう構成しますか。

説明する

公衆 Wi-Fi から HTTPS のサイトにログインするとき、同じ Wi-Fi にいる人には何が見えて、何が見えませんか。暗号化に加えて証明書が要るのはなぜかも説明してください。