【実務・中級編】HTTP/2の接続確立とALPN(Application-Layer Protocol Negotiation) – HTTPプロトコル・通信規格実践ガイド

HTTP/2の「握手」の裏側:ALPNがもたらす静かなる革命

ネットワークエンジニアとして現場に立っていると、若手から「HTTP/2って結局何が速いの?」と聞かれることがある。ストリームの多重化やHPACKによるヘッダー圧縮も重要だが、真に評価すべきは、「いかにしてHTTP/1.1の呪縛を断ち切り、スムーズに次世代プロトコルへ移行したか」というその接続戦略にある。

今回は、その門番である「ALPN」の仕組みを深掘りしていこう。現場でパケットキャプチャを眺める際に、この握手のシーケンスが見えているかどうかで、トラブルシューティングの解像度が劇的に変わるはずだ。

—

1. なぜALPNが必要だったのか:HTTP/1.1との「見えない壁」

HTTP/1.1からHTTP/2へ切り替える際、最大の問題は「相手がHTTP/2を喋れるか分からない」という点だ。もし適当にHTTP/2のバイナリフレームを投げつけて、相手がHTTP/1.1のサーバーだったらどうなるか? サーバーは不正なリクエストとして即座にコネクションを切断するだろう。

かつてHTTP/1.1で使われていた「Upgradeヘッダー」を使ったネゴシエーション(Cleartext Upgrade)は、非セキュアな通信が前提であり、現代のWebの常識である「HTTPS(TLS)必須」の世界では力不足だった。

ここで登場するのが ALPN (Application-Layer Protocol Negotiation) だ。

—

2. ALPNのシーケンス:TLSハンドシェイクという「特等席」

ALPNの美しさは、TLSハンドシェイクという、プロトコルが確定する前の「最も神聖な儀式」の中に交渉をねじ込んだことにある。

通信の流れは以下の通りだ。

1. Client Hello: クライアントはTLSのハンドシェイクを開始する際、`ALPN`という拡張フィールドを添える。ここに「俺は `h2` も `http/1.1` も喋れるぞ」というリストを載せる。
2. Server Hello: サーバーは送られてきたリストを確認し、自分が対応しているプロトコルの中で最も優先度の高いもの(通常は `h2`)を選び、同じく`ALPN`拡張で返答する。
3. ハンドシェイク完了: この時点で、TLSの暗号化トンネルが構築されると同時に、その中でHTTP/2を使うことが合意される。

この方式なら、余計なラウンドトリップ(往復通信)を発生させることなく、TLSの接続とプロトコルの確定が同時に完了する。まさに「効率の極み」だ。

—

3. 実践:ALPNを確認するためのデバッグ手法

現場で「なぜかHTTP/2にならない」というトラブルはよくある。まずは自分の環境が正しくALPNでネゴシエーションできているか、`curl`を使って確認するのが定石だ。

curlでプロトコルの詳細を覗く

-v: 詳細表示, –http2: HTTP/2での接続を強制するオプションではないが、
ALPNでh2が選択されたかを確認するのに適している
curl -vI https://www.google.com 2>&1 | grep “ALPN”

出力結果に `ALPN, server accepted to use h2` とあれば、その通信は正しくHTTP/2の恩恵を受けている。もしここで `http/1.1` にフォールバックしていたら、サーバー側の設定(Nginxやロードバランサー)がHTTP/2をサポートしていないか、証明書の不備を疑うべきだ。

—

4. サーバー側(Nginx)の設定Tips

インフラエンジニアとして、NginxでHTTP/2を有効にする設定はシンプルだが、落とし穴もある。

server {
listen 443 ssl http2; # 「http2」と書くだけでALPNの設定は自動化される
server_name example.com;

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;

# HTTP/2が有効か確認するためのログフォーマット
log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘$http_user_agent “$http2″‘; # $http2変数でプロトコルを表示
}

注意点: OpenSSLのバージョンが古いとALPNをサポートしていないことがある。最近のOSなら心配無用だが、古いオンプレ環境を保守している場合は `openssl version` で確認を怠らないこと。

—

5. PythonでALPNを叩く:`h2`ライブラリの活用

もしあなたがAPIクライアントを自作しているなら、`requests`ではなく `httpx` や `hyper-h2` を使うことになるだろう。以下は `httpx` を使ったシンプルな接続チェックだ。

import httpx

httpxはデフォルトでHTTP/2をサポートしている
with httpx.Client(http2=True) as client:
response = client.get(“https://www.google.com”)
# どのプロトコルが選ばれたかを表示
print(f”Negotiated Protocol: {response.http_version}”)
# 結果が ‘HTTP/2’ と出ればOK

—

最後に:ネットワークエンジニアとしての視点

HTTP/2のALPNを理解することは、単なるプロトコルの知識向上ではない。それは「通信の開始時に何が起きているか」を可視化する力を養うということだ。

パケットキャプチャを開き、TLSハンドシェイクの `Client Hello` パケットを見てほしい。そこに刻まれたプロトコルのリストは、クライアントの「意思」であり、`Server Hello` で選ばれたプロトコルは、サーバーとの「合意」だ。

Web APIの設計においても、単に「HTTP/2対応」と謳うだけでなく、このようなネゴシエーションの仕組みを理解しているエンジニアであれば、将来のHTTP/3(QUIC)への移行にも迷わず対応できるはずだ。

プロトコルは生き物だ。その呼吸を、ぜひパケットを通して感じてみてほしい。

コメント

タイトルとURLをコピーしました