nginx で HTTP/3 を有効にする
Fedora では、nginx 1.26.0 で(experimental)HTTP/3 モジュールが有効になりましたので、早速使ってみることにします。
nginx の設定
HTTP/2 に関する設定が古くなっていたので、最初に修正します。
server {listen 443 ssl http2;listen 443 ssl;listen [::]:443 ssl http2;listen [::]:443 ssl; http2 on; server_name example.com; root /path/to/htdocs; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; ... }
listen
に http2
と指定する書き方は非推奨になりました。代わりに、http2 on;
の行を追加します。
HTTP/3 を有効にします。
server { listen 443 ssl; listen 443 quic reuseport; listen [::]:443 ssl; listen [::]:443 quic reuseport; http2 on; server_name example.com; root /path/to/htdocs; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; add_header Alt-Svc 'h3=":443"; ma=86400'; ... }
上記 3行を追加します。クライアントは、一旦 HTTP/2 で接続し、その際にサーバが「HTTP/3 にも対応してますよ」というヘッダを返すことで、以後の接続を HTTP/3 に切り替えます。このことから、HTTP/2 と HTTP/3 の listen
が必要です。バーチャルホストで複数のサーバを同居させる場合、はどれでもよいので、一つだけのバーチャルホストで上記のように reuseport
を指定します。一つも指定しない、複数指定はいずれもエラーになります。
add_header
を指定して、HTTP/3 対応している旨のヘッダを追加します。
firewalld の設定
firewalld では HTTP/3 は http3
として定義済みです。
# firewall-cmd --permanent --service=http3 --get-ports 443/udp #
サービスを提供する各ゾーンで、http3
の接続を許可します。
# firewall-cmd --permanent --zone=public --add-service=http3 success # firewall-cmd --permanent --zone=trusted --add-service=http3 success # firewall-cmd --reload
自前の証明書を使う
HTTP/3 ではオレオレ証明書を使うことはできないようです。
自前の認証局を作り、その認証局のルート証明書を取り込んで有効にし、その認証局で発行したサーバ証明書を使って、HTTP/3 サーバを建ててみます。
server { listen 10443 quic; listen [::]:10443 quic; listen 10443 ssl; listen [::]:10443 ssl; http2 on; server_name test.seinolab.jp; root /path/to/htdocs; ssl_certificate "/path/to/seinolab.jp.cert.pem"; ssl_certificate_key "/path/to/seinolab.jp.key.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_session_tickets off; ssl_dhparam "/path/to/dh2048.pem"; ssl_protocols TLSv1.3 TLSv1.2; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA; ssl_prefer_server_ciphers on; ssl_client_certificate "/path/to/root.cert.pem"; ssl_crl "/path/to/crl.pem"; add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload'; add_header Alt-Svc 'h3=":443"; ma=86400'; access_log /var/log/nginx/test.access.log; }
このサーバ(seinolab.jp
)でテストしたので、ポート 443
は使えません。適当なポートに変更しています。このサーバは既に Let's Encrypt 発行の SSL 証明書を使用しています。同じポートで複数の SSL 証明書を切り替えて使うことはできません。
seinolab.jp.cert.pem
は自前の認証局で発行した *.seinolab.jp
のワイルドカード証明書です。全く問題なく通信できます。開発環境でも大丈夫です。
自前の認証局を作る方法は、strongSwan 用の証明書を作成するを参照してください。
通信テスト
現状は、Google Chrome か Safari で接続し、nginx のログを確認するしか方法はなさそうです。
curl
も既に対応済みですが、残念ながら、ビルドし直す必要がありそうです。
$ curl --http3-only https://seinolab.jp:433/ curl: option --http3-only: the installed libcurl version doesn't support this curl: try 'curl --help' or 'curl --manual' for more information $