ウェブサイト検索

Nginx の「プレーン HTTP リクエストが HTTPS ポートに送信されました」エラーを修正


この記事では、Nginx HTTP サーバーの「400 Bad Request: The plain HTTP request was send to HTTPS port」という問題を解決する方法を説明します。このエラーは通常、HTTP リクエストと HTTPS リクエストの両方を処理するように Nginx を構成しようとしたときに発生します。

このガイドの目的として、nginx がサーバー ブロック (または Apache の仮想ホスト) を通じて実装された複数の Web サイトにサービスを提供し、1 つの Web サイトのみが SSL を使用し、残りの Web サイトは使用しないというシナリオを検討しています。

こちらもお読みください: Nginx のセキュリティを確保、強化し、パフォーマンスを向上させるための究極のガイド

また、以下のサンプル SSL 設定についても検討します (セキュリティ上の理由から実際のドメイン名は変更しています)。これは、nginx にポート 80443 の両方をリッスンするように指示します。また、HTTP 上のすべてのリクエストはデフォルトで HTTPS にリダイレクトされる必要があります。

Nginx サンプル構成

server{
        listen 80;
        server_name example.com www.example.com;
        return 301 https://www.example.com$request_uri;
}
server {
        listen 443 ssl http2;
        server_name example.com www.example.com;

        root   /var/www/html/example.com/;
        index index.php index.html index.htm;

        #charset koi8-r;
        access_log /var/log/nginx/example.com/example.com_access_log;
        error_log   /var/log/nginx/example.com/example.com_error_log   error;

        # SSL/TLS configs
        ssl on;
        ssl_certificate /etc/ssl/certs/example_com_cert_chain.crt;
        ssl_certificate_key /etc/ssl/private/example_com.key;

        include /etc/nginx/ssl.d/ssl.conf;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   /var/www/html/example.com/;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {

                root   /var/www/html/example.com/;
                fastcgi_pass   127.0.0.1:9001;
                #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include         fastcgi_params;
                include /etc/nginx/fastcgi_params;

        }
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
}

上記の設定を使用して、クライアントがポート 80、つまり http://example.com 経由でサイトにアクセスしようとすると、問題のエラーが次のように表示されます。スクリーンショット。

このエラーが発生するのは、クライアントが HTTP 経由でサイトにアクセスしようとするたびに、リクエストが HTTPS にリダイレクトされるためです。これは、nginx がトランザクションで SSL が使用されることを期待しているにもかかわらず、元のリクエスト (ポート 80 経由で受信) がプレーン HTTP であるため、エラーが発生します。

一方、クライアントが https://example.com を使用する場合、上記のエラーは発生しません。さらに、SSL を使用しないように構成されている他の Web サイトがある場合、nginx はそれらに対してデフォルトで HTTPS を使用しようとします。その結果、上記のエラーが発生します。

このエラーを修正するには、構成内の以下の行をコメントアウトするか、オフに設定します。

#ssl on 
OR
ssl off

ファイルを保存して閉じます。次に、nginx サービスを再起動します。

systemctl restart nginx
OR
sudo systemctl restart nginx

このようにして、nginx が複数のサーバー ブロックに対する HTTP リクエストと HTTPS リクエストの両方を処理できるようにすることができます。

最後に、以下は一般的な Linux ディストリビューションと FreeBSD での SSL HTTPS の設定に関する記事のリストです。

  1. RHEL/CentOS 上の Nginx の Let’s Encrypt SSL 証明書を使用した HTTPS のセットアップ
  2. Ubuntu および Debian で無料の Let’s Encrypt SSL 証明書を使用して Nginx を保護する
  3. SSL で Nginx を保護する方法と FreeBSD で暗号化しましょう

それは今のところすべてです。このエラーを解決する他の方法をご存知の場合は、以下のフィードバック フォームからお知らせください。