HAProxy przekierowujące http na https (ssl)

100

Używam HAProxy do równoważenia obciążenia i chcę, aby moja witryna obsługiwała tylko protokół HTTPS. Dlatego chciałbym przekierować wszystkie żądania z portu 80 do portu 443.

Jak bym to zrobił?

Edycja: chcielibyśmy przekierować do tego samego adresu URL pod adresem https, zachowując parametry zapytania. W związku z tym http://foo.com/bar przekierowałoby do https://foo.com/bar

Jon Chu
źródło

Odpowiedzi:

141

Okazało się, że to największa pomoc :

Użyj HAProxy 1.5 lub nowszego i po prostu dodaj następujący wiersz do konfiguracji frontendu:

redirect scheme https code 301 if !{ ssl_fc }
Jay Taylor
źródło
20
Aby to dodać, z poniższej odpowiedzi User2966600, z dodanym 301, użyj tego do przekierowania na https tylko dla określonej domeny:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Quentin Skousen
1
To się udało. Chociaż nie działa bez „kodu 301”. Dzięki za aktualizację.
deej
7
Równoważny składni danego odpowiedź byłaby tak: http-request redirect scheme https code 301 if !{ ssl_fc }. Dokumentacja dotycząca przekierowania http w ALOHA HAProxy 7.0 nawet wspomina, że ​​„ składnia obu dyrektyw jest taka sama, co oznacza, że ​​przekierowanie jest teraz uważane za starsze, a konfiguracje powinny zostać przeniesione do formularza przekierowania żądania http ”. Wnioskuję, nie będąc całkowicie pewnym, że to samo wyjaśnienie dotyczy nowszych wersji otwartej wersji oprogramowania HAProxy.
rodolfojcj
Dzięki za odpowiedź. Czy mógłbyś rozszerzyć, aby wyjaśnić, gdzie musimy dodać tę linię? W interfejsie / backend / default / global / ..?
realtebo
Zwykle umieszczam go w interfejsie użytkownika, ale przekierowania to tylko nagłówek, więc spodziewałbym się, że przekierowanie może zostać wyzwolone do momentu wysłania nagłówków odpowiedzi. Chciałbym wiedzieć, czy może działać w obu lokalizacjach, być może trzeba będzie spróbować.
Jay Taylor
68

Nie mam wystarczającej reputacji, aby skomentować poprzednią odpowiedź, więc zamieszczam nową, uzupełniającą odpowiedź Jaya Taylora. Zasadniczo jego odpowiedź wykona przekierowanie, choć niejawne przekierowanie, co oznacza, że ​​wygeneruje 302 (tymczasowe przekierowanie), ale ponieważ pytanie informuje, że cała witryna będzie obsługiwana jako https, to odpowiednim przekierowaniem powinno być 301 (stałe przekierowanie ).

redirect scheme https code 301 if !{ ssl_fc }

Wydaje się, że to niewielka zmiana, ale wpływ może być ogromny w zależności od strony internetowej, przy stałym przekierowaniu informujemy przeglądarkę, że nie powinna już szukać wersji http od początku (unikając przyszłych przekierowań) - oszczędność czasu dla https witryn. Pomaga również w pozycjonowaniu, ale nie pozwala na dzielenie soku z linków.

Marcos Abreu
źródło
42

Aby przekierować cały ruch:

redirect scheme https if !{ ssl_fc }

Aby przekierować pojedynczy adres URL (w przypadku wielu frontendów / backendów)

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

user2966600
źródło
1
Dzięki, warunek „tylko na określonym hoście” był właśnie tym, czego szukałem!
Quentin Skousen
Czy mógłbyś pokazać praktyczny przykład drugiej opcji?
RicarHincapie
16

Zgodnie z http://parsnips.net/haproxy-http-to-https-redirect/ powinno być tak proste, jak skonfigurowanie haproxy.cfg tak, aby zawierał następujące elementy.

#---------------------------------------------------------------------
# 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
Matthew Brown
źródło
7
To przekierowałoby wszystko do foo.bar.com . Idealnie byłoby jednak, gdyby foo.bar.com/baz przekierowywał na foo.bar.com/baz . Potrzebujemy również parametrów zapytania.
Jon Chu,
@JonChu przedstawia ważny przypadek użycia, jest to tylko częściowe rozwiązanie.
Jay Taylor
3
Zamiast korzystać z lokalizacji przekierowania, spróbuj zamiast tego przedrostek przekierowania https: //foo.bar.com. Powinno to pomóc w przypadku użycia, o którym wspomina Jon Chu.
xangxiong,
16

Najlepszym gwarantowanym sposobem przekierowania wszystkiego z http na https jest:

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

Jest to trochę bardziej wyszukane przy użyciu „kodu 301”, ale równie dobrze może dać klientowi znać, że jest to trwałe. Część „tryb http” nie jest niezbędna przy domyślnej konfiguracji, ale nie zaszkodzi. Jeśli masz mode tcpsekcję defaults (tak jak ja), to jest to konieczne.

Maitreya
źródło
10

Niewielka odmiana rozwiązania user2966600 ...

Aby przekierować wszystko oprócz jednego adresu URL (w przypadku wielu frontend / backend):

redirect scheme https if !{ hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Josh Currier
źródło
4

Jak powiedział Jay Taylor, HAProxy 1.5-dev ma redirect schemedyrektywę konfiguracyjną, która spełnia dokładnie to, czego potrzebujesz.

Jeśli jednak nie możesz używać wersji 1.5 i masz ochotę skompilować HAProxy ze źródła, dokonałem backportowania tej redirect schemefunkcjonalności, aby działała w wersji 1.4. Możesz pobrać łatkę tutaj: http://marc.info/?l=haproxy&m=138456233430692&w=2

zardzewiały
źródło
2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com
sanyi
źródło
1

W nowszych wersjach HAProxy zalecane jest użycie

http-request redirect scheme https if !{ ssl_fc }

przekierować ruch http na https.

Ten facet
źródło
0

Jeśli chcesz przepisać adres URL, musisz zmienić virtualhost w swojej witrynie, dodając następujące linie:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

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

Ale jeśli chcesz przekierować wszystkie swoje żądania na porcie 80 do portu 443 serwerów WWW za proxy, możesz wypróbować następujący przykład conf na swoim 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

Mam nadzieję, że to ci pomoże

Mieszkanie
źródło
0

Dlaczego nie używasz list ACL do rozróżniania ruchu? na mojej głowie:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Jest to uzupełnienie tego, co odpowiedział Matthew Brown.

Zobacz dokumentację ha , wyszukaj takie rzeczy, jak hdr_dom i poniżej, aby znaleźć więcej opcji ACL. Istnieje wiele możliwości wyboru.

Glenn Plas
źródło
0

Można to zrobić w ten sposób -

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

Każdy ruch docierający do http będzie przekierowywany do https

chandan
źródło
0

instrukcja przekierowania jest starsza

zamiast tego użyj przekierowania żądania http

acl http      ssl_fc,not
http-request redirect scheme https if http
Amir Jalali
źródło
0

Po prostu:

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
Badr Fennane
źródło