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

Adr*_*ith 3 nginx https amazon-elb

我在 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)"
Run Code Online (Sandbox Code Playgroud)

当我通过curl我看到重定向请求 URL 时:

$ 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
Run Code Online (Sandbox Code Playgroud)

我的 nginx 配置文件只是

server {
    root /var/www;
}
Run Code Online (Sandbox Code Playgroud)

/etc/nginx/nginx.conf 在这里

我试过了,server_name_in_redirect off但没有任何区别。

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

我希望 nginx 执行此重定向,但仍使用 HTTPS。我能做什么?

Ric*_*ith 6

解决问题的最佳位置是 SSL 连接终止的位置。如果它运行nginx,你可以使用一个proxy_redirect以地图陈述http,以httpsLocation报头。我不知道 AWS ELB,所以无法评论如何在那里修复它。

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


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

server {
    absolute_redirect off;
    ...
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此文档


2)/使用以下try_files语句禁止将尾随附加到目录的行为:

server {
    root /path/to/files;

    location / {
        try_files $uri =404;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此文档


3) 用显式return语句修复问题。

server {
    root /path/to/files;

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

    location / {
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

请参见本文件的更多,而这种谨慎的使用if