Как предотвратить перенаправление nginx с HTTPS на HTTP на AWS?
У меня есть веб-сайт, обслуживаемый nginx за балансировщиком нагрузки AWS ELB. На балансировщике нагрузки включен только 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. Что я могу сделать?
4 ответа
Лучшее место для решения этой проблемы - соединение с SSL. Если это было запущено nginx
, вы бы использовали proxy_redirect
заявление к карте http
в https
в Location
заголовок. Я не знаю AWS ELB, поэтому не могу комментировать, как это исправить там.
Определенные обстоятельства вызывают nginx
ответить перенаправлением, и предполагается, что схема такая же, как схема, используемая для подключения к ней (т. е. от AWS ELB). AFAIK Есть три способа смягчить проблему в серверной части 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
,
Попробуй это
server {
root /var/www;
include /etc/nginx/basic.conf;
try_files $uri $uri/;
}
Если это не сработает, пожалуйста, отредактируйте ваш вопрос, чтобы включить все, что есть в basic.conf и nginx.conf. Также выполните скручивание, показывающее проблему, включая заголовки ответа и единственный соответствующий файл журнала доступа Nginx.
Вы можете попытаться использовать предложение "зло, если":
server {
...
if ($http_x_forwarded_proto = 'http' ) {
rewrite ^ https://$host$request_uri? permanent;
}
...
}
Не тестировалось на AWS, однако я решил использовать эту строку в каждомlocation
блокировать:
proxy_redirect ~^http:(.*)$ https:$1;