DELOGs
[サーバ構築編#9] Nginxでhttp/3を設定しつつ、gzip 圧縮の最適化にも対応

サーバ構築編#9
Nginxでhttp/3を設定しつつ、gzip 圧縮の最適化にも対応

Nginxでhttp/3通信できるように設定。合わせてconfファイルのgzip 圧縮最適化も。

初回公開日

最終更新日

サーバ構築編第9回は、Nginxでhttp/3に対応しつつ、confファイルへgzip 圧縮の設定を加えます。 Nginx1.28.0での設定内容となっています。
Nginxはバージョン1.25.0以降、QUICおよびHTTP/3のサポートを実験的に提供しています。 ただし、HTTP/3のサポートはデフォルトでは有効になっておらず、Nginxを--with-http_v3_moduleオプションを使用してビルドする必要があります。
さらに、QUICをサポートするSSLライブラリ(BoringSSL、LibreSSL、QuicTLSなど)を使用する必要があります。 デフォルトのOpenSSLでは、QUICの完全なサポートが得られない可能性があります。
HTTP/3 は QUIC を使う新しいプロトコルで、より高速&安定した通信が可能です。主要な最新ブラウザでは対応されていますが、対応していないブラウザは HTTP/2 で動作するように ALPN を設定していきます。

1. Nginx が HTTP/3 に対応しているか確認

念の為、現在のバージョンでHTTP/3に対応済みかをチェックします。
bash
1sudo nginx -V 2>&1 | grep -o 'http_v3'
bash
1・・・--with-http_v3_module・・・
  • 上記のようにhttp_v3を含むモジュールがあれば、対応ずみです。

2. nginx.conf に HTTP/3 (QUIC) の設定を追加

まずは、nginx.confの設定を編集して HTTP/3 を有効化します。
bash
1sudo vi /etc/nginx/nginx.conf
httpブロックに下記のように追記していきます。
bash : nginx.conf
1・・・ファイル上部は省略・・・ 2http { 3 ・・・ブロック内のデフォルトのままの部分省略・・・ 4 #gzip on; 5 6 ## ここから追記 7 # ====== HTTP/3 (QUIC) の設定 ====== 8 # TLS 設定(HTTP/3 には TLS 1.3 が必須) 9 ssl_protocols TLSv1.3; 10 ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256; 11 12 # ECDH カーブを手動設定 13 ssl_ecdh_curve X25519:P-256:P-384; 14 15 # QUIC(HTTP/3)の安定化設定 16 quic_retry on; 17 quic_gso on; 18 quic_host_key /etc/nginx/quic_host_key; 19 20 # HTTP/3 をサポートすることを通知(Alt-Svc ヘッダー) 21 add_header Alt-Svc 'h3=":443"; ma=86400' always; 22 23 # QUIC(HTTP/3)の最大並列ストリーム数(デフォルト 100 のままだけど、後から調整しやすいように) 24 http3_max_concurrent_streams 100; 25 26 # HTTP/3 非対応のブラウザでは HTTP/2 にフォールバック 27 ssl_prefer_server_ciphers on; 28 ssl_session_cache shared:SSL:10m; 29 ssl_session_timeout 1d; 30 ssl_session_tickets off; 31 32 ## ここまで追記 33 34 include /etc/nginx/conf.d/*.conf; 35}

HTTP/3 (QUIC) を有効化するための nginx.conf 設定ポイント

○HTTP/3 (QUIC) の基本設定
bash : nginx.conf
1ssl_protocols TLSv1.3; 2ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
  • HTTP/3 は TLS 1.3 が必須
  • TLS 1.3 で推奨される暗号スイートを設定!
bash : nginx.conf
1ssl_ecdh_curve X25519:P-256:P-384;
  • TLS (SSL) の暗号化に使う 「楕円曲線 (Elliptic Curve)」 を指定する設定
  • ssl_ecdh_curve で X25519 や P-256 などの安全な楕円曲線を手動指定!
  • X25519が最速&高セキュリティなので優先して、P-256(一般的で広く使われている)、P-384(強力なセキュリティだけど重い)の順にフォールバック!
○QUIC (HTTP/3) の安定化設定
bash : nginx.conf
1quic_retry on;
  • QUIC のアドレス検証を有効化し、接続の安定性を向上!
  • 初回1度だけリトライするので、DDoS攻撃対策としても有効!
bash : nginx.conf
1quic_gso on;
  • Generic Segmentation Offload (GSO) を有効化!
  • パケットを効率的に送信し、CPU 負荷を軽減!
bash : nginx.conf
1quic_host_key /etc/nginx/quic_host_key;
  • QUIC 用のトークンを管理するホストキーを指定!
  • まずは openssl でキーを作成する必要あり!(後述)
○HTTP/3 を通知する Alt-Svc ヘッダー
bash : nginx.conf
1add_header Alt-Svc 'h3=":443"; ma=86400' always;
  • ブラウザに HTTP/3 で接続できることを通知!
  • ma=86400 は 24時間(86,400秒) HTTP/3 を優先する設定!
○HTTP/3 の最大並列ストリーム数
bash : nginx.conf
1http3_max_concurrent_streams 100;
  • QUIC の 1 接続あたりの最大ストリーム数を制限!
  • デフォルト (100) で運用し、必要なら調整できるようにしておく!
○HTTP/3 非対応のブラウザでは HTTP/2 にフォールバック
bash : nginx.conf
1ssl_prefer_server_ciphers on;
  • サーバー側で暗号スイートの選択を優先!
  • クライアント(ブラウザ)との互換性を確保!
bash : nginx.conf
1ssl_session_cache shared:SSL:10m; 2ssl_session_timeout 1d; 3ssl_session_tickets off;
  • セッションキャッシュを有効化し、SSL のハンドシェイクを最適化!
  • セキュリティ向上のため、SSL セッションチケット を無効化!
  • SSL セッションチケット (Session Tickets) は、onにするとSSL/TLS の 再接続を高速化する仕組みだが、チケットが漏洩すると、盗聴・改ざんのリスクがあるので、ここではoff

3. QUIC のホストキーを作成

quic_host_key を設定する前に、以下のコマンドで 16バイトの乱数キー を作成します。
bash
1sudo openssl rand -out /etc/nginx/quic_host_key 16 2sudo chmod 600 /etc/nginx/quic_host_key
  • QUIC の トークン認証 に使用する秘密キーを生成!
  • セキュリティを考慮し、ファイルのパーミッションを 600 に設定!

4.conf.d/example.com.conf に HTTP/3 の設定を追加

バーチャルホスト用の設定にHTTP/3の設定を追加します。
bash
1sudo vi /etc/nginx/conf.d/example.com.conf
example.com.confの内容は、サーバ構築編第8回までの内容を踏襲しています。 リダイレクト先になっているlisten 433 sslserverブロックについて、listen ディレクティブを HTTP/3 対応に修正
bash : example.com.conf
1・・・ファイル上部を省略・・・ 2 3server { 4##追記箇所ここから 5 listen 443 ssl default_server; # HTTP/2 6 listen [::]:443 ssl default_server; 7 http2 on; 8 listen 443 quic reuseport; # HTTP/3 9 listen [::]:443 quic reuseport; 10##追記箇所ここまで 11 12 server_name example.com; 13 14##追記箇所ここから 15# HTTP/3 をサポートすることを通知(Alt-Svc ヘッダー) 16 add_header Alt-Svc 'h3=":443"; ma=86400' always; 17##追記箇所ここまで 18 19 # Basic認証 20 auth_basic "Restricted Area"; # <-認証プロンプトのタイトル 21 auth_basic_user_file /etc/nginx/.htpasswd; # <-認証ファイルのパス 22 ## 23 24 root /var/www/example.com/html; 25 index index.html; 26 27 location / { 28 try_files $uri $uri/ =404; 29 } 30 31 # listen 443 ssl; # managed by Certbot <-ここはブロックの上部で記述したので削除かコメントアウト 32 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot 33 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot 34 include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 35 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 36 37} 38・・・ファイル下部を省略・・・ 39
Certbotが記述したlisten 443 sslの部分は削除するかコメントアウトするのをお忘れなく。
listenの箇所はメインとなるドメインの設定の場合だけ
bash : example.com.conf
1 listen 443 ssl default_server; 2 listen [::]:443 ssl default_server; 3 http2 on; 4 listen 443 quic reuseport; 5 listen [::]:443 quic reuseport;
このように記述します。`` それ以外のドメインの設定については、下記のようにします。
bash : hogehoge.com.conf
1 listen 443 ssl; 2 listen [::]:443 ssl; 3 http2 on; 4 listen 443 quic; 5 listen [::]:443 quic;
このようにdefault_serverreuseportはメインのドメインにだけつけるようにします。 こうしないと構文チェックsudo nginx -tで下記のようなエラーが出ます。
bash
1nginx: [emerg] duplicate listen options for 0.0.0.0:443 in /etc/nginx/conf.d/・・・

5.構文チェック&Nginxの再起動

ここまで完了したら、構文をチェックして問題なければNginx再起動します。
bash
1sudo nginx -t 2sudo systemctl restart nginx

6.ブラウザでHTTP/3の動作確認

まず、確実にHTTP/3でアクセス可能なGoogleでブラウザがHTTP/3プロトコルでの通信ができるかを確認します。 https://www.google.com 上記へアクセスします。
ChromeやSafariでサイトを開いたら、管理者ツールを起動して「ネットワーク」を開きます。 その後、サイトをリロード(更新)するとダウンロードしたファイルリストが表示されて、プロトコルの種類も表示されます。
もし、ファイルリストに「プロトコル」の表示がなければ、「名前」などの表示項目の上で右クリックすると表示可能な項目がポップアップされますので、「プロトコル」を選択します。
すると下記のように、chromeならh3HTTP/3で通信できていることが表示されるのが確認できます。 ブラウザの管理者ツール-ネットワーク
もし、この段階でh3HTTP/3ではなくh2HTTP/2となっている場合は、ノートンなどのセキュリティソフトがHTTP/3 (QUIC)が使用するUDP 443 をブロックしている可能性があります。実は、私の環境でこの状態が発生しました。 ノートン360なら「セーフウェブ」で「Webサイトスキャン」を一時無効(除外設定では駄目でした。。)にすると動作確認できました。この作業をやった場合は、ブラウザのキャッシュをクリアして、一度立ち上げ直す必要があります。 ちなみにノートンのサポートには除外設定でもブロックされてしまう現象は報告して、サポートの部門の人に一緒に状況を見てもらっています(2025年3月19日)。
GoogleサイトでHTTP/3で通信できることが確認できたら、今回設定したサイトにアクセスして同様にHTTP/3でアクセスできることを確認してください。
ノートン が HTTP/3 (QUIC) をブロックする理由
HTTP/3 (QUIC) 自体は「有害」ではありませんが、セキュリティソフトの Webサイトスキャン には QUIC に対する警戒心があります。
  • HTTP/2 (h2) 以前は TCP 443 を使っていたため、セキュリティソフトはパケットを解析しやすかった
  • HTTP/3 (QUIC) は UDP 443 を使用するため、パケットの中身をスキャンしにくい
  • その結果、セキュリティソフトは「スキャンできないから QUIC をブロックする」動作になっている可能性が高い 事実、一部のマルウェアが QUIC を悪用するケースがあります
  • 以前に QUIC を利用する C2 (Command and Control) サーバーを使った マルウェア が発見されたことがある
  • これを警戒して、一部のセキュリティソフトは QUIC を「リスクがある通信」として扱い、デフォルトでブロックする
セキュリティソフトによっては、このようにブロックされることになり、せっかく設定を行っても、ユーザにHTTP/3の恩恵を届けられないことになります。それは認識しつつも、対応だけはできるようになっておくことは重要ではないかと考えています。

7.ついでにnginx.confにgzipの圧縮設定も追記

一旦、HTTP/3の設定が完了したら、ついでにコンテンツの圧縮設定もしておきます。
再度、/etc/nginx/nginx.confを編集します。
bash
1sudo vi /etc/nginx/nginx.conf
#gzip on;とコメントアウトされている箇所があるので、その箇所を編集します。
bash : nginx.conf
1 # ========================= 2 # Gzip 圧縮の設定 3 # ========================= 4 gzip on; 5 gzip_comp_level 6; # 圧縮率(1~9、6がバランス良し) 6 gzip_min_length 1024; # 1KB以上のレスポンスを圧縮 7 gzip_proxied any; # プロキシ経由のリクエストでも圧縮 8 gzip_vary on; # `Vary: Accept-Encoding` を追加 9 10 # 圧縮対象の MIME タイプ 11 gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 6;
  • 1 (最速・低圧縮) 〜 9 (最遅・高圧縮) の範囲で設定
  • 6 は速度と圧縮率のバランスが良い!
gzip_min_length 1024;
  • 1KB 以上のレスポンスを圧縮
  • 小さいファイル は圧縮しても効果が少ないので 無駄な負荷 を減らす!
gzip_proxied any;
  • CDN や Cloudflare などのプロキシ経由のリクエストも gzip 圧縮を適用!
gzip_vary on;
  • ブラウザの Accept-Encoding に応じて gzip を適用し、キャッシュの最適化を行う!
gzip_types ...
  • JS, CSS, JSON, XML, HTML などを圧縮対象に!
  • 画像や動画 (JPEG, PNG, MP4, WEBP など) は既に圧縮されているので対象外!
  • woff, woff2, ttf などのフォントは、もともと gzip 圧縮されているケースが多いのこれも対象外!
編集が完了したら、構文をチェックして問題なければNginx再起動します。
bash
1sudo nginx -t 2sudo systemctl restart nginx

8.まとめ

以上でHTTP/3とgzip圧縮の設定は完了です。 Nginxの設定としてはまだ「キャッシュの設定」や「add_headerによるセキュリティ強化」がありますが、これはNext.js向けの設定で行う予定です。 Nginxの汎用的な設定としてはここまでにしたいと思います。
次回からはpostfix+devcotでメールサーバの構築を始めます。
続きはこちら...
前回の確認はこちら...
この記事の執筆・編集担当
DE

松本 孝太郎

DELOGs編集部/中年新米プログラマー

ここ数年はReact&MUIのフロントエンドエンジニアって感じでしたが、Next.jsを学んで少しずつできることが広がりつつあります。その実践記録をできるだけ共有していければと思っています。