Skip to content

Nginx HTTP/2設定における警告の解決方法

問題の背景

Nginx v1.25.1以降、HTTP/2の設定方法が変更されました。従来のlisten 443 ssl http2;設定が非推奨となり、新たにhttp2 on;ディレクティブの使用が推奨されています。しかし設定変更後に以下の警告が発生することがあります:

bash
nginx: [warn] protocol options redefined for 0.0.0.0:443

この警告は設定ファイル間でプロトコルオプションが重複定義されていることを示します。特に同じIP/ポートの組み合わせに対してhttp2設定が複数存在する場合に発生します。

🔍 根本的な原因

  1. 設定の不一致: 同一サーバー上の複数の設定ファイルでHTTP/2設定が混在している

    • 一部は従来のlisten ... http2構文
    • 一部は新しいhttp2 on;構文
  2. IPv4/IPv6の重複定義: IPv6用の設定(listen [::]:443;)でHTTP/2設定が欠如している場合

  3. デフォルト設定の影響: 未使用と思われるデフォルト設定ファイル(default.conf)に古い設定が残存

✅ 効果的な解決策

全ての設定ファイルで一貫した書式を使用

すべてのサーバーブロックで同じHTTP/2設定方法を適用する必要があります:

nginx
server {
    listen 443 ssl;
    listen [::]:443 ssl;  # IPv6用に明示的に定義
    http2 on;             # ここのみでHTTP/2を有効化
    
    # その他の設定...
}

設定ファイルの一括修正方法

/etc/nginx/sites-available/ディレクトリで以下のsedコマンドを実行:

bash
# 古い記法を削除
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

完全な設定例

nginx
# 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ファイルだけ修正しても警告が消えない場合、全設定ファイルをチェック

🔄 バッチ処理スクリプト

複数の設定ファイルを一括処理するスクリプト:

bash
#!/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 "すべての設定ファイル処理が終了しました"

💡 検証手順

  1. 設定ファイルのエラーチェック:
    bash
    nginx -t
  2. リロード前にログを監視:
    bash
    tail -f /var/log/nginx/error.log
  3. HTTP/2の動作確認:
    bash
    curl -I --http2 https://your-domain.com

補足説明

この警告が解消しない場合の対策:

  1. 完全リビルド検討: ./configure --with-http_v2_moduleを指定してNginxを再ビルド
  2. モジュール状態確認: nginx -V出力でhttp_v2_moduleが存在することを確認
  3. キャッシュクリア: 変更後にnginx -s reloadではなくnginx -s stop && nginxで完全再起動

設定変更時の注意

SSL証明書のパスやリダイレクトURLは実際の環境に合わせて置換してください。特にreturn 301の記述では$request_uriの前にスラッシュを追加しないよう注意(/$request_uriではなく$request_uri

以上の手順を適用することで、HTTP/2機能を保持しつつ警告メッセージを完全に解消できます。設定変更後は必ずnginx -tで構文チェックを行ってからサービスを再起動してください。