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

haproxy + nginx: завершающие слэши https перенаправлены на http

У меня есть настройка, в которой трафик HTTP (S) идет с HAProxy на nginx.

            HAProxy    nginx
HTTP -----> :80  ----> :9080
HTTPS ----> :443 ----> :9443

У меня проблемы с неявными перенаправлениями, вызванными конечными косыми чертами, переходящими с https на http, например:

$ curl -k -I https://www.example.com/subdir
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.4
Date: Thu, 04 Oct 2012 12:52:39 GMT
Content-Type: text/html
Content-Length: 184
Location: http://www.example.com/subdir/

Причина, очевидно, в том, что HAProxy работает как распаковщик SSL, а nginx видит только HTTP-запросы. Я попытался настроить X-Forwarded-Proto на https в конфигурации HAProxy, но ничего не сделал.

Моя настройка nginx выглядит следующим образом:

server {
  listen       127.0.0.1:9443;
  server_name  www.example.com;

  port_in_redirect off;

  root   /var/www/example;
  index  index.html index.htm;
}

И соответствующие части из конфигурации HAProxy:

frontend https-in
    bind *:443 ssl crt /etc/example.pem prefer-server-ciphers
    default_backend nginxssl

backend nginxssl
    balance roundrobin
    option forwardfor
    reqadd X-Forwarded-Proto:\ https
    server nginxssl1 127.0.0.1:9443

У меня такая же проблема. В этом случае Nginx выполняет своего рода автоперенаправление, но вы можете поймать и изменить поведение по умолчанию, используя два блока местоположения:

# This location will catch the redirect nginx will do automatically
# because we are using an exact match ("=")
location = /subdir {
    return 301 https://yourdomainname/subdir/;
}

# This location will be used for the other requests
location /subdir {
}

Надеюсь это поможет

Предполагается ли, что ваш бэкэнд-трафик nginx будет SSL (на основе порта 9443)? Если это так, то похоже, что в вашей директиве сервера в вашем бэкэнде nginxssl отсутствует ключевое слово ssl, поэтому;

server nginxssl1 127.0.0.1:9443 ssl

Это заставит haproxy использовать SSL для исходящей связи с сервером nginx. Или, может быть, вы делаете это специально для тестирования в данный момент?

В любом случае, возможно, также стоит указать режим HTTP для вашего внешнего и внутреннего интерфейса, поскольку режим по умолчанию - TCP.

На самом деле это не вопрос http или https, это то, что вы не ожидаете никакой косой черты, но если subdir, поскольку его имя подразумевает подкаталог, то синтаксис в вашем запросе неверен, и nginx исправляет его для вас, чтобы вы могли повторно опубликовать действительный запрос который будет составлять правильную основу для всех последующих запросов, сделанных от относительных объектов, найденных в этом каталоге.

Думаю, у вас было бы то же самое с http на http или https на https.