HAProxy перенаправляет http на https (ssl)

100

Я использую HAProxy для балансировки нагрузки и хочу, чтобы мой сайт поддерживал только https. Таким образом, я хотел бы перенаправить все запросы с порта 80 на порт 443.

Как мне это сделать?

Изменить: мы хотели бы перенаправить на тот же URL-адрес на https, сохранив параметры запроса. Таким образом, http://foo.com/bar будет перенаправлять на https://foo.com/bar

Джон Чу
источник

Ответы:

141

Я обнаружил, что это самая большая помощь :

Используйте HAProxy 1.5 или новее и просто добавьте следующую строку в конфигурацию внешнего интерфейса:

redirect scheme https code 301 if !{ ssl_fc }
Джей Тейлор
источник
20
Чтобы добавить к этому, из ответа User2966600 ниже, с добавленным 301, используйте это для перенаправления на https только для определенного домена:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Квентин Скоусен
1
Это сработало. Хотя без кода 301 не работает. Спасибо за обновление.
дией
7
Эквивалентный синтаксис для данного ответа будет выглядеть так: http-request redirect scheme https code 301 if !{ ssl_fc }. В документации по перенаправлению http в ALOHA HAProxy 7.0 даже упоминается, что « синтаксис обеих директив одинаковый, при этом перенаправление теперь считается устаревшим, и конфигурации должны перемещаться в форму перенаправления HTTP-запросов ». Не будучи полностью уверенным, я делаю вывод, что то же самое объяснение применимо к более новым выпускам версии HAProxy с открытым исходным кодом.
rodolfojcj
Спасибо за ваш ответ. Не могли бы вы объяснить, где мы должны добавить эту строку? В интерфейсе / бэкэнд / по умолчанию / global / ..?
realtebo
Я обычно помещаю его во внешний интерфейс, но перенаправления - это просто заголовок, поэтому я ожидаю, что перенаправление может быть запущено до тех пор, пока не будут отправлены заголовки ответа. Я хотел бы знать, может ли он работать в обоих местах, возможно, придется попробовать.
Джей Тейлор
68

У меня недостаточно репутации, чтобы прокомментировать предыдущий ответ, поэтому я публикую новый ответ, чтобы дополнить ответ Джея Тейлора. В основном его ответ будет выполнять перенаправление, хотя и неявное перенаправление, что означает, что он выдаст 302 (временное перенаправление), но поскольку вопрос сообщает, что весь веб-сайт будет обслуживаться как https, тогда соответствующее перенаправление должно быть 301 (постоянное перенаправление ).

redirect scheme https code 301 if !{ ssl_fc }

Это кажется незначительным изменением, но влияние может быть огромным в зависимости от веб-сайта, с постоянным перенаправлением мы информируем браузер, что он больше не должен искать версию http с самого начала (избегая будущих перенаправлений) - экономия времени для https места. Это также помогает с SEO, но не разделяет ваши ссылки.

Маркос Абреу
источник
42

Чтобы перенаправить весь трафик:

redirect scheme https if !{ ssl_fc }

Для перенаправления одного URL-адреса (в случае нескольких интерфейсов / бэкэндов)

redirect scheme https if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }

user2966600
источник
1
Спасибо, условие "только на определенном хосте" было именно тем, что я искал!
Quentin Skousen
Приведите, пожалуйста, практический пример второго варианта?
RicarHincapie
16

Согласно http://parsnips.net/haproxy-http-to-https-redirect/ это должно быть так же просто, как настроить haproxy.cfg, чтобы он содержал следующее.

#---------------------------------------------------------------------
# Redirect to secured
#---------------------------------------------------------------------
frontend unsecured *:80
    redirect location https://foo.bar.com

#---------------------------------------------------------------------
# frontend secured
#---------------------------------------------------------------------
frontend  secured *:443
   mode  tcp
   default_backend      app

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    mode  tcp
    balance roundrobin
    server  app1 127.0.0.1:5001 check
    server  app2 127.0.0.1:5002 check
    server  app3 127.0.0.1:5003 check
    server  app4 127.0.0.1:5004 check
Мэтью Браун
источник
7
Таким образом, все будет перенаправлено на foo.bar.com . Однако в идеале мы хотели бы, чтобы foo.bar.com/baz перенаправлял на foo.bar.com/baz . Еще нам нужны параметры запроса.
Джон Чу
@JonChu поднимает допустимый вариант использования, это только частичное решение.
Джей Тейлор
3
Вместо использования местоположения перенаправления попробуйте использовать префикс перенаправления https: //foo.bar.com. Это должно помочь с вариантом использования, о котором упоминает Джон Чу.
xangxiong
16

Лучший гарантированный способ перенаправить все с http на https:

frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

Это немного удобнее использовать «код 301», но с тем же успехом можно сообщить клиенту, что это навсегда. Часть 'mode http' не важна для конфигурации по умолчанию, но не повредит. Если у вас есть mode tcpраздел по умолчанию (как у меня), то это необходимо.

Майтрейя
источник
10

Небольшое изменение решения user2966600 ...

Чтобы перенаправить все, кроме одного URL (в случае нескольких интерфейсов / бэкэндов):

redirect scheme https if !{ hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Джош Карриер
источник
4

Как сказал Джей Тейлор, HAProxy 1.5-dev имеет redirect schemeдирективу конфигурации, которая выполняет именно то, что вам нужно.

Однако, если вы не можете использовать 1.5, и если вы готовы скомпилировать HAProxy из исходного кода, я перенес эту redirect schemeфункциональность, чтобы она работала в 1.4. Вы можете получить патч здесь: http://marc.info/?l=haproxy&m=138456233430692&w=2

ржавый
источник
2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com
Саньи
источник
1

В более новых версиях HAProxy рекомендуется использовать

http-request redirect scheme https if !{ ssl_fc }

для перенаправления http-трафика на https.

Этот парень
источник
0

Если вы хотите переписать URL-адрес, вам нужно изменить виртуальный хост своего сайта, добавив следующие строки:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

### Rewrite http:// => https://
RewriteCond %{SERVER_PORT} 80$
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,NC,L]

Но если вы хотите перенаправить все свои запросы с порта 80 на порт 443 веб-серверов за прокси-сервером, вы можете попробовать этот пример conf на своем haproxy.cfg:

##########
# Global #
##########
global
    maxconn 100
    spread-checks 50
    daemon
    nbproc 4

############
# Defaults #
############
defaults
    maxconn 100
    log global
    mode http
    option dontlognull
    retries 3
    contimeout 60000
    clitimeout 60000
    srvtimeout 60000

#####################
# Frontend: HTTP-IN #
#####################
frontend http-in
    bind *:80
    option logasap
    option httplog
    option httpclose
    log global
    default_backend sslwebserver

#########################
# Backend: SSLWEBSERVER #
#########################
backend sslwebserver
    option httplog
    option forwardfor
    option abortonclose
    log global
    balance roundrobin
    # Server List
    server sslws01 webserver01:443 check
    server sslws02 webserver02:443 check
    server sslws03 webserver03:443 check

Я надеюсь это поможет тебе

Квартира
источник
0

Почему вы не используете ACL для различения трафика? над моей головой:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Это дополняет то, что ответил Мэтью Браун.

См. Документацию ha , поищите такие вещи, как hdr_dom и ниже, чтобы найти дополнительные параметры ACL. Есть много вариантов.

Гленн Плас
источник
0

Можно сделать так -

  frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

Любой трафик, попадающий в http, будет перенаправлен на https

чандан
источник
0

инструкция перенаправления является устаревшей

вместо этого используйте перенаправление http-запроса

acl http      ssl_fc,not
http-request redirect scheme https if http
Амир Джалали
источник
0

Просто:

frontend incoming_requsts
        bind *:80
        bind *:443 ssl crt *path_to_cert*.**pem**
        **http-request redirect scheme https unless { ssl_fc }**
        default_backend k8s_nodes
Бадр Феннане
источник