Nginx

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

  • September 29, 2021

我在 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)"

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

我的 nginx 配置文件只是

server {
   root /var/www;
}

/etc/nginx/nginx.conf 在這裡

我試過server_name_in_redirect off了,但沒有任何區別。

我想避免將主機名放在配置文件中,因為它被打包到一個 Docker 映像中,然後部署在不同的主機(QA、Prod 等)上。

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

解決問題的最佳位置是終止 SSL 連接的位置。如果它正在執行nginx,您將使用一個proxy_redirect語句映射http到標題中httpsLocation我不知道 AWS ELB,所以無法評論如何在那裡修復它。

某些情況會導致nginx以重定向響應,並且假定該方案與用於連接它的方案相同(即來自 AWS ELB)。AFAIK 有三種方法可以緩解後端nginx伺服器中的問題。


1)從1.11.8版本開始,該absolute_redirect off;語句會導致Locationheader使用相對URL,即缺少scheme和域名。

server {
   absolute_redirect off;
   ...
}

有關更多資訊,請參閱此文件


/2)通過使用try_files語句來禁止向目錄附加尾隨的行為:

server {
   root /path/to/files;

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

有關更多資訊,請參閱此文件


return3) 使用顯式語句修復問題。

server {
   root /path/to/files;

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

   location / {
   }
   ...
}

有關更多資訊,請參閱文件,以及使用.if

引用自:https://serverfault.com/questions/885046