如何防止 nginx 在 AWS 上从 HTTPS 重定向到 HTTP?

如何防止 nginx 在 AWS 上从 HTTPS 重定向到 HTTP?

我有一个由 AWS ELB 负载均衡器后面的 nginx 提供服务的网站。负载均衡器上仅启用了 HTTPS。

请求单个文件或带有尾部斜杠的目录可以正常工作。但是,请求目录没有尾部斜杠不起作用。

原因是,当我请求没有尾部斜杠的目录时,nginx 会重定向到该路径尾部斜杠(没问题),但它也会从 HTTPS 更改为 HTTP。负载均衡器配置为仅允许 HTTPS,因此这不起作用(超时)。

在 nginx 日志文件中,我可以看到请求到达 nginx,并且 nginx 使用 301 永久重定向进行响应(因此这不是负载均衡器设置的问题)。

10.100.10.15 - - [24/Nov/2017:15:41:08 +0000] "GET /admin HTTP/1.1" 301 178 "-" "Wget/1.18 (darwin16.0.0)"

当我通过以下方式请求 URL 时,curl我看到重定向:

$ curl -v https://example.com/admin
*   Trying 1.2.3.4...
* TCP_NODELAY set
* Connected to example.com (1.2.3.4) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: example.com
* Server certificate: Amazon
* Server certificate: Amazon Root CA 1
* Server certificate: Starfield Services Root Certificate Authority - G2
> GET /admin HTTP/1.1
> Host: example.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Mon, 27 Nov 2017 09:19:05 GMT
< Content-Type: text/html
< Content-Length: 178
< Connection: keep-alive
< Server: nginx
< Location: http://example.com/admin/
< X-UA-Compatible: IE=Edge
< 
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host example.com left intact

我的 nginx 配置文件如下

server {
    root /var/www;
}

/etc/nginx/nginx.conf 是这里

我已尝试过server_name_in_redirect off,但并没有什么变化。

我想避免将主机名放在配置文件中,因为它会被打包到 Docker 映像中,然后部署在不同的主机上(QA、Prod 等)。

我希望 nginx 执行此重定向,但仍使用 HTTPS。我该怎么办?

答案1

修复该问题的最佳位置是 SSL 连接终止的地方。如果它正在运行nginx,您将使用proxy_redirect语句映射http到标头httpsLocation。我不知道 AWS ELB,所以无法评论如何在那里修复它。

某些情况下会导致nginx使用重定向进行响应,并且它假定该方案与用于连接它的方案相同(即来自 AWS ELB)。据我所知,有三种方法可以缓解后端nginx服务器中的问题。


1)从 1.11.8 版本开始,该absolute_redirect off;语句将导致Location标头使用相对 URL,这意味着缺少方案和域名。

server {
    absolute_redirect off;
    ...
}

这个文件了解更多信息。


/2)使用以下语句抑制在目录后附加尾随内容的行为try_files

server {
    root /path/to/files;

    location / {
        try_files $uri =404;
    }
    ...
}

这个文件了解更多信息。


3)用明确的语句修复问题return

server {
    root /path/to/files;

    location ~ [^/]$ {
        if (-d $request_filename) {
            return 302 https://$host$uri/$is_args$args;
        }
    }

    location / {
    }
    ...
}

这个文件了解更多信息,这种警告关于 的使用if

答案2

尝试这个

server {
  root /var/www;
  include /etc/nginx/basic.conf;
  try_files $uri $uri/;
}

如果不起作用,请编辑您的问题以包含 basic.conf 和 nginx.conf 中的所有内容。另外,执行 curl 显示问题,包括响应标头和单个相应的 Nginx 访问日志文件。

答案3

你可以尝试使用“邪恶的如果”句子:

server {
    ...
    if ($http_x_forwarded_proto = 'http' ) {
        rewrite ^ https://$host$request_uri? permanent;
    }
    ...
}

答案4

location尚未在 AWS 上测试,但是我在每个块中都使用此行解决了问题:

proxy_redirect ~^http:(.*)$ https:$1;

相关内容