Nginx HTTP/2設定における警告の解決方法
問題の背景
Nginx v1.25.1以降、HTTP/2の設定方法が変更されました。従来のlisten 443 ssl http2;
設定が非推奨となり、新たにhttp2 on;
ディレクティブの使用が推奨されています。しかし設定変更後に以下の警告が発生することがあります:
nginx: [warn] protocol options redefined for 0.0.0.0:443
この警告は設定ファイル間でプロトコルオプションが重複定義されていることを示します。特に同じIP/ポートの組み合わせに対してhttp2
設定が複数存在する場合に発生します。
🔍 根本的な原因
設定の不一致: 同一サーバー上の複数の設定ファイルでHTTP/2設定が混在している
- 一部は従来の
listen ... http2
構文 - 一部は新しい
http2 on;
構文
- 一部は従来の
IPv4/IPv6の重複定義: IPv6用の設定(
listen [::]:443;
)でHTTP/2設定が欠如している場合デフォルト設定の影響: 未使用と思われるデフォルト設定ファイル(
default.conf
)に古い設定が残存
✅ 効果的な解決策
全ての設定ファイルで一貫した書式を使用
すべてのサーバーブロックで同じHTTP/2設定方法を適用する必要があります:
server {
listen 443 ssl;
listen [::]:443 ssl; # IPv6用に明示的に定義
http2 on; # ここのみでHTTP/2を有効化
# その他の設定...
}
設定ファイルの一括修正方法
/etc/nginx/sites-available/
ディレクトリで以下のsedコマンドを実行:
# 古い記法を削除
sed -i 's/listen 443 ssl http2;/listen 443 ssl;/' *.conf
# IPv6設定とhttp2ディレクティブを追加
sed -i 's/listen \[::\]:443 ssl http2;/listen \[::\]:443 ssl;\nhttp2 on;/' *.conf
完全な設定例
# HTTP → HTTPSリダイレクト
server {
listen 80;
server_name domain.name www.domain.name;
location ^~ /.well-known/acme-challenge/ {
root /acme-challenge;
allow all;
}
location / {
return 301 https://www.domain.name$request_uri;
}
}
# HTTPS non-www → wwwリダイレクト
server {
listen 443 ssl;
listen [::]:443 ssl; # IPv6対応追加
http2 on; # 追加部分
server_name domain.name;
ssl_certificate /ssl/live/domain.name/fullchain.pem;
ssl_certificate_key /ssl/live/domain.name/privkey.pem;
location ^~ /.well-known/acme-challenge/ {
root /acme-challenge;
allow all;
}
location / {
return 301 https://www.domain.name$request_uri;
}
}
# 特定パスへリダイレクト
server {
listen 443 ssl;
listen [::]:443 ssl; # IPv6対応追加
http2 on; # 追加部分
server_name www.domain.name;
ssl_certificate /ssl/live/domain.name/fullchain.pem;
ssl_certificate_key /ssl/live/domain.name/privkey.pem;
location ^~ /.well-known/acme-challenge/ {
root /acme-challenge;
allow all;
}
location / {
return 301 https://www.other.domain.name/app/;
}
}
重要なポイント
- デフォルト設定ファイルも修正:
/etc/nginx/conf.d/default.conf
など未使用の設定ファイルも修正対象 - IPv6設定を明示: 警告回避には
listen [::]:443 ssl;
の明記が必須 - 一斉変更: 1ファイルだけ修正しても警告が消えない場合、全設定ファイルをチェック
🔄 バッチ処理スクリプト
複数の設定ファイルを一括処理するスクリプト:
#!/usr/bin/env bash
CONF_DIR="/etc/nginx/sites-enabled"
for conf_file in "$CONF_DIR"/*.conf; do
echo "処理中: $conf_file"
# listenディレクティブを更新
sed -i.bak -e 's/listen 443 ssl http2;/listen 443 ssl;/' "$conf_file"
sed -i -e 's/listen \[::\]:443 ssl http2;/listen \[::\]:443 ssl;\n http2 on;/' "$conf_file"
echo "$conf_file を更新完了"
done
echo "すべての設定ファイル処理が終了しました"
💡 検証手順
- 設定ファイルのエラーチェック:bash
nginx -t
- リロード前にログを監視:bash
tail -f /var/log/nginx/error.log
- HTTP/2の動作確認:bash
curl -I --http2 https://your-domain.com
補足説明
この警告が解消しない場合の対策:
- 完全リビルド検討:
./configure --with-http_v2_module
を指定してNginxを再ビルド - モジュール状態確認:
nginx -V
出力でhttp_v2_module
が存在することを確認 - キャッシュクリア: 変更後に
nginx -s reload
ではなくnginx -s stop && nginx
で完全再起動
設定変更時の注意
SSL証明書のパスやリダイレクトURLは実際の環境に合わせて置換してください。特にreturn 301
の記述では$request_uri
の前にスラッシュを追加しないよう注意(/$request_uri
ではなく$request_uri
)
以上の手順を適用することで、HTTP/2機能を保持しつつ警告メッセージを完全に解消できます。設定変更後は必ずnginx -t
で構文チェックを行ってからサービスを再起動してください。