У меня есть веб-сайт, обслуживаемый 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. Что я могу сделать?
Лучшее место для решения проблемы - это разрыв 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;
}
...
}