【问题标题】:How to redirect on the same port from http to https with nginx reverse proxy如何使用 nginx 反向代理在同一端口上从 http 重定向到 https
【发布时间】:2013-03-03 23:15:27
【问题描述】:

我用 Nginx 使用反向代理,我想强制请求进入 HTTPS,所以如果用户想用 http 访问 url,他会自动重定向到 HTTPS。

我也在使用非标准端口。

这是我的 nginx 反向代理配置:

server {
    listen 8001  ssl;
    ssl_certificate /home/xxx/server.crt;
    ssl_certificate_key /home/xxx/server.key;
    location / {
        proxy_pass https://localhost:8000;
        proxy_redirect off;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Ssl on;
        proxy_set_header  X-Forwarded-Proto  https;
    }
}

我尝试了很多方法,也阅读了有关它的帖子,包括 this serverfault question,但到目前为止没有任何效果。

【问题讨论】:

  • 重开审稿人:这个问题肯定和编程有关,而且非常具体。只是之前没有提到“非标准端口”,这可能使它之前有点模糊。
  • 这是完全错误的,这被关闭为题外话。 nginx是编程中常用的工具,评分最高的解决方案给出了解决问题的正确代码:error_page 497 https://$host:$server_port$request_uri;

标签: ssl proxy nginx reverse-proxy


【解决方案1】:

这是我的方法,我认为它很干净,并且允许您在需要时添加更多位置。我在 $http_x_forwarded_proto 属性上添加了一个测试,如果该属性为真,则在 NGINX 反向代理设置上强制所有 HTTP 流量到 HTTPS

upstream flask_bootstrap {
    server flask-bootstrap:8000;
}

server {
    # SSL traffic terminates on the Load Balancer so we only need to listen on port 80
    listen 80;

    # Set reverse proxy
    location / {
        proxy_pass http://flask_bootstrap;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect http://localhost/;

        # Permanently redirect any http calls to https
        if ($http_x_forwarded_proto != 'https') {
            return 301 https://$host$request_uri;
        }
    }
}

【讨论】:

    【解决方案2】:

    发现了一些运行良好的东西:

    server {
            listen 8001  ssl;
            ssl_certificate /home/xxx/server.crt;
            ssl_certificate_key /home/xxx/server.key;
            error_page 497 301 =307 https://$host:$server_port$request_uri;
            location /{
                proxy_pass http://localhost:8000;
                proxy_redirect off;
                proxy_set_header Host $host:$server_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Ssl on;
            }
    }
    

    【讨论】:

    • 错误代码 497 是专门为此用例创建的 [在同一端口上从 http 重定向到 https]。我认为这是最好的答案。 wiki.nginx.org/HttpSslModule#Nonstandard_error_codes
    • 非常感谢!! error_page 497 https://$host:$server_port$request_uri; 成功了!
    • 我会考虑添加:error_page 497 301 =307 https://$host:$server_port$request_uri; 这样请求方法不会像默认那样自动转换为 GET
    • @Komu 你救了我:)
    【解决方案3】:

    这对我有用:

    server {
    listen       80;
    server_name  localhost;
    ...
    if ($http_x_forwarded_proto = "http") {
          return 301 https://$server_name$request_uri;
    }
    location / {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://localhost:8080;
    }
    
    ...
    }
    

    【讨论】:

      【解决方案4】:

      你可以

      1. 使用 $server_name 避免再次对您的域名进行硬编码 (DRY),
      2. 使用 return 301 更容易阅读(网络开发人员应该知道这个 http 状态代码)

      注意:我为 https 服务器设置了 443。如果你真的想听的话,你可以听 8001。

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

      【讨论】:

      • 好吧,我在 nginx 中使用反向代理,因为每个应用程序都有不同的 RoR 环境。因此,我使用独立服务器 Passanger + nginx 启动我的应用程序,并使用反向代理添加那些 SSL 证书。因为我无法在独立版本中添加 SSL 证书路径。
      • 如果我更改 error_page 497 https://$host:$server_port$request_uri;通过返回 301 https://$host:$server_port$request_uri;我得到了这个,重定向又被打破了。 400 Bad Request 普通 HTTP 请求被发送到 HTTPS 端口
      • 我明白了。你的答案应该是最好的答案。您的问题是它正在通过一个非标准端口,并且您想在 SAME 端口上从 http 重定向到 https。所以不可能像我最初想的那样设置 2 个服务器块,因为你不能让 2 个服务器块监听同一个端口。
      • @senayar 为什么不回答您自己的问题?我会支持你的。因此,其他人更容易从中学习。另外请更新问题本身并说明主要问题:在同一端口上从 http 重定向到 https
      • 我不能在 2 天内接受我自己的答案 :) 但它已经完成了谢谢。也许有人可以提出另一种解决方案。感谢您的帮助!
      【解决方案5】:

      您确定您的解决方案有效吗?它正在监听 8001 ssl。会接受http请求吗?

      我是这样做的:

      server {
          listen   80;
          server_name  yourhostname.com;
      
          location / {
                  rewrite ^(.*) https://yourhostname.com:8001$1 permanent;
          }
      }
      

      然后是你的配置:

      server {
          listen 8001  ssl;
          ssl_certificate /home/xxx/server.crt;
          ssl_certificate_key /home/xxx/server.key;
          location / {
              proxy_pass https://localhost:8000;
              proxy_redirect off;
              proxy_set_header Host $host:$server_port;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Ssl on;
              proxy_set_header  X-Forwarded-Proto  https;
          }
      }
      

      【讨论】:

      • 是的,我的解决方案正在运行,端口 80 已被另一个具有子域乘客基本 uri 的 nginx 服务器使用。
      猜你喜欢
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2021-04-06
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      相关资源
      最近更新 更多