Назад | Перейти на главную страницу

Как предотвратить перенаправление 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. Что я могу сделать?

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