Мой экземпляр nginx находится за балансировщиком нагрузки с завершением SSL, и я хочу, чтобы все URL-адреса попали https
конечные точки, что означает http
быть перенаправленным на https
.
Все хорошо, когда в конце URL есть косая черта. Все они красиво перенаправляются:
#!/bin/sh
do_curl() {
echo "\n$ do_curl $1"
curl -L -s -D - "$1" -o /dev/null | grep -iE 'Location|HTTP/|server'
}
$ do_curl https://example.com/
HTTP/2 200
$ do_curl http://example.com/foo/
HTTP/1.1 301 Moved Permanently
Location: https://example.com/foo/
HTTP/2 200
$ do_curl https://example.com/foo/
HTTP/2 200
Но когда те же URL-адреса не имеют завершающей косой черты, nginx try_files
похоже, издает http
перенаправлять всегда: bad.png
Вот мой nginx vhost.conf
:
server {
listen 80;
root /app/;
index index.html index.htm;
# This 'if' block is only needed because my SSL-terminated Load balancer proxies both http and https to nginx.
# If my Load balancer only proxied https to nginx, and dropped http, this 'if' block can be omitted.
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
Как мне получить nginx try_files
перенаправить напрямую с https
$scheme
когда он попадает в $uri/
параметр (2-й параметр в моем try_files
выше) и успешно находит соответствующий файл $uri/<index>
(где index
определяется index
директиву в конфигурации nginx выше)?
Я искал похожие вопросы, например Вот, Вот, или Вот но так и не смог найти ничего отдаленно относящегося к делу.
Как отметил @Florin в комментариях к вопросу, try_files
выполняет только перезапись. Я вернулся и опустил try_files
блок в моем vhost.conf
и правда, я вернулся к тому же поведению, когда https
URL с без косой черты перенаправить на его http
следом аналог.
Вместо этого заголовок моего вопроса должен был быть больше похож на «Как предотвратить перенаправление nginx с HTTPS на HTTP», что тогда было бы дублирующим вопросом Как предотвратить перенаправление nginx с HTTPS на HTTP на AWS? что @Richard указал в своем комментарии на мой вопрос, и на который он ответил.
По совпадению, мои обстоятельства и вопрос на самом деле идентичны тем, что в этом вопросе. В своем ответе @Richard указывает, что лучший способ смягчить проблему, когда nginx предполагает то же самое $scheme
в качестве инициатора запроса (т. е. балансировщика нагрузки с завершенным SSL) будет выполнять замену http
с участием https
в Location
заголовок в точке балансировщика нагрузки, что для меня было невозможно. Затем он продолжает описывать три способы выполнения редиректов, где $scheme
было бы https
.
Из трех решений, которое сработало для меня, было использование absolute_redirect off;
. Это помешало nginx использовать неправильный $scheme
что он использовал в редиректах.
Теперь мой vhost.conf
просто должно быть:
server {
listen 80;
root /app/;
index index.html index.htm;
absolute_redirect off;
# This 'if' block is only needed because my SSL-terminated Load balancer proxies both http and https to nginx.
# If my Load balancer only proxied https to nginx, and dropped http, this 'if' block can be omitted.
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
}