【问题标题】:Dealing with nginx 400 "The plain HTTP request was sent to HTTPS port" error处理 nginx 400 “The plain HTTP request was sent to HTTPS port”错误
【发布时间】:2023-04-03 21:42:01
【问题描述】:

我在乘客/nginx 后面运行一个 Sinatra 应用程序。我试图让它同时响应 http 和 https 调用。问题是,当两者都在服务器块中定义时,https 调用正常响应,但 http 产生 400“普通 HTTP 请求已发送到 HTTPS 端口”错误。这是一个静态页面,所以我猜 Sinatra 与此无关。有关如何解决此问题的任何想法?

这是服务器块:

server {
        listen 80;
        listen 443  ssl;
        server_name localhost;
        root /home/myhome/app/public;
        passenger_enabled on;

        ssl on;
        ssl_certificate      /opt/nginx/ssl_keys/ssl.crt;
        ssl_certificate_key  /opt/nginx/ssl_keys/ssl.key;
        ssl_protocols        SSLv3 TLSv1;
        ssl_ciphers          HIGH:!aNULL:!MD5;

        location /static {
            root  /home/myhome/app/public;
            index  index.html index.htm index.php;
        }

        error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        error_page 500 /500.html;

        access_log /home/myhome/app/logs/access.log;
        error_log /home/myhome/app/logs/error.log;
}

【问题讨论】:

  • 就我而言,浏览器中的网址:my.example.com:443 不起作用。将其改为https://my.example.com 有效。奇怪,apache 从来没有这个问题。
  • ssl on; 告诉 NGINX 通过 SSL 服务 ANY 内容。在 listen 443; 的末尾使用“ssl”标志,例如 listen 443 ssl;如果您的服务器同时提供 http 和 https 流量,并删除 ssl on; 指令。

标签: nginx


【解决方案1】:

我遇到了类似的问题。它可以在一台服务器上运行,而不能在具有相同 Nginx 配置的另一台服务器上运行。在这里找到了由 Igor 回答的解决方案 http://forum.nginx.org/read.php?2,1612,1627#msg-1627

是的。或者您可以将 SSL/非 SSL 服务器组合到一个服务器中:

server {
  listen 80;
  listen 443 default ssl;

  # ssl on   - remember to comment this out

}

【讨论】:

  • 根据 rapam iosif 所说,确保您还包括 ssl off;
  • 只需要去掉ssl on;这行(不需要加上ssl off)。另外,由于我不记得哪个 Nginx 版本,所以没有必要在 listen 443 行上使用 default。所以 OP 配置没问题,只需要删除 ssl on 就可以了。
  • @bobojam 随时包含我的回答中的解释,以便您的回答更加完整。我已经要求 OP 作者接受你的回答。
  • 如何通过评论ssl on解决SSL目的。 @MichaelJ.Evans 下面的答案是一个更好的解决方案。
  • 似乎不适用于多个 conf 文件。说有 2 个重复的默认值。使用 Alexander 的解决方案。
【解决方案2】:

上述答案是不正确的,因为大多数覆盖“此连接是否为 HTTPS”测试以允许通过 http 提供页面而不考虑连接安全性。

使用 NGINX 特定的 http 4xx 错误代码上的错误页面来重定向客户端以重试对 https 的相同请求的安全答案。 (如此处所述https://serverfault.com/questions/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx

OP 应该使用:

server {
  listen        12345;
  server_name   php.myadmin.com;

  root         /var/www/php;

  ssl           on;

  # If they come here using HTTP, bounce them to the correct scheme
  error_page 497 https://$server_name:$server_port$request_uri;

  [....]
}

【讨论】:

  • 您可能想要 $server_name 而不是 $host,server_name 大概设置为 SSL 证书验证的 CN。这样,如果用户通过 IP 或 localhost 进入,他们就不会被吓到。
  • 我试图在本地安装的 GitLab 上实现这一点,但使用了 Inserting custom NGINX settings into the GitLab server block 方法,因此 nginx['custom_gitlab_server_config'] = "error_page 497 https://$host:$server_port$request_uri;" 成功了
【解决方案3】:

错误实际上说明了一切。您的配置告诉 Nginx 侦听端口 80 (HTTP) 并使用 SSL。当您将浏览器指向http://localhost 时,它会尝试通过 HTTP 进行连接。由于 Nginx 需要 SSL,因此它会报错。

解决方法非常简单。您需要两个 server 部分:

server {
  listen 80;

  // other directives...
}

server {
  listen 443;

  ssl on;
  // SSL directives...

  // other directives...
}

【讨论】:

  • 您实际上并不需要两个服务器部分。根据@bobojam 的回答删除“ssl on”行并更改监听行。
【解决方案4】:

根据wikipedia article on status codes。 Nginx在http流量发送到https端口时有自定义错误码(错误码497)

根据nginx docs on error_page,您可以定义一个URI,它将针对特定错误显示。
因此,我们可以创建一个 uri,当出现错误代码 497 时,客户端将被发送到该 uri。

nginx.conf

#lets assume your IP address is 89.89.89.89 and also 
#that you want nginx to listen on port 7000 and your app is running on port 3000

server {
    listen 7000 ssl;
 
    ssl_certificate /path/to/ssl_certificate.cer;
    ssl_certificate_key /path/to/ssl_certificate_key.key;
    ssl_client_certificate /path/to/ssl_client_certificate.cer;

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri;

    location / {
        proxy_pass http://89.89.89.89:3000/;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Protocol $scheme;
    }
}

但是,如果客户端通过除 GET 之外的任何其他方法发出请求,则该请求将被转换为 GET。从而保留客户端进来的请求方法;我们使用错误处理重定向,如nginx docs on error_page

这就是我们使用301 =307 重定向的原因。

使用这里显示的 nginx.conf 文件,我们可以让 http 和 https 在同一个端口上监听

【讨论】:

【解决方案5】:

我遇到了完全相同的问题,我的配置与您的示例相同,我通过删除该行使其工作:

ssl on;

引用文档:

如果 HTTP 和 HTTPS 服务器相同,则可以通过删除指令“ssl on”并为 *:443 端口添加 ssl 参数来配置同时处理 HTTP 和 HTTPS 请求的单个服务器

【讨论】:

  • 你有没有 doc 的链接?
【解决方案6】:

这是一个在同一配置块中配置 HTTPHTTPS 并支持 ipv6 的示例。该配置在 Ubuntu ServerNGINX/1.4.6 中进行了测试,但这应该适用于所有服务器。

server {
    # support http and ipv6
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # support https and ipv6
    listen 443 default_server ssl;
    listen [::]:443 ipv6only=on default_server ssl;

    # path to web directory
    root /path/to/example.com;
    index index.html index.htm;

    # domain or subdomain
    server_name example.com www.example.com;

    # ssl certificate
    ssl_certificate /path/to/certs/example_com-bundle.crt;
    ssl_certificate_key /path/to/certs/example_com.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;
}

不要包含ssl on,这可能会导致400 错误。上面的配置应该适用于

http://example.com

http://www.example.com

https://example.com

https://www.example.com

希望这会有所帮助!

【讨论】:

    【解决方案7】:

    如果使用 phpmyadmin 添加:fastcgi_param HTTPS on;

    【讨论】:

      【解决方案8】:

      其实你可以这样做:

      ssl off; 
      

      这解决了我使用 nginxvhosts 的问题;现在我可以同时使用 SSL 和纯 HTTP。 甚至可以使用组合端口。

      【讨论】:

      • 在 nginx/1.6.3 上为我工作 :)
      【解决方案9】:

      它的错误 497 而不是错误 400 。您可以像这样处理错误 497,并使用 301(永久移动)或 302(临时移动)将 http 重定向到 https:

      error_page 497 = @foobar;
      
      location @foobar {
      return 301 https://$host:$server_port$request_uri;
      }
      

      这会将您重定向到您请求的确切网址,但将您的请求“http”替换为“https”,没有错误或确认(其 301 重定向并被视为 seo 安全)

      【讨论】:

        【解决方案10】:

        在我的情况下,我的响应从 jenkins 重定向到 443

        刚刚在 nginx 配置中添加了代理重定向以使其工作

        proxy_redirect http://test.example.com:443/ https://test.example.com/;

        【讨论】:

          猜你喜欢
          • 2021-03-23
          • 2018-10-24
          • 2019-04-23
          • 2020-08-22
          • 2015-02-03
          • 2022-12-18
          • 2016-05-19
          • 2022-12-15
          • 1970-01-01
          相关资源
          最近更新 更多