HAProxy redireccionando http a https (ssl)

99

Estoy usando HAProxy para equilibrar la carga y solo quiero que mi sitio admita https. Por lo tanto, me gustaría redirigir todas las solicitudes en el puerto 80 al puerto 443.

¿Cómo haría esto?

Editar: nos gustaría redirigir a la misma URL en https, conservando los parámetros de consulta. Por lo tanto, http://foo.com/bar redirigiría a https://foo.com/bar

Jon Chu
fuente

Respuestas:

137

Encontré que esta es la mayor ayuda :

Use HAProxy 1.5 o más reciente, y simplemente agregue la siguiente línea a la configuración de la interfaz:

redirect scheme https code 301 if !{ ssl_fc }
Jay Taylor
fuente
20
Para agregar a esto, de la respuesta de User2966600 a continuación, con 301 agregado, use esto para redirigir a https solo para un dominio específico:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Quentin Skousen
1
Eso funciono. Aunque no funciona sin el 'código 301'. Gracias por la actualización.
deej
6
Una sintaxis equivalente a la respuesta dada sería así: http-request redirect scheme https code 301 if !{ ssl_fc }. La documentación para la redirección http en ALOHA HAProxy 7.0 incluso menciona que " la sintaxis de ambas directivas es la misma, dicho esto, la redirección ahora se considera heredada y las configuraciones deben pasar al formulario de redirección de solicitud http ". Deduzco, sin estar completamente seguro, que la misma explicación se aplica a las versiones más recientes de la versión de código abierto de HAProxy.
rodolfojcj
Gracias por su respuesta. ¿Podría ampliar para explicar dónde debemos agregar esta línea? ¿En el frontend / backend / default / global / ..?
Realtebo
Por lo general, lo coloco dentro de la interfaz, pero las redirecciones son solo un encabezado, por lo que esperaría que se active una redirección hasta que se hayan enviado los encabezados de respuesta. Me gustaría saber si puede funcionar en ambas ubicaciones, quizás tenga que probarlo.
Jay Taylor
68

No tengo suficiente reputación para comentar una respuesta anterior, por lo que estoy publicando una nueva respuesta para complementar la respuesta de Jay Taylor. Básicamente, su respuesta hará el redireccionamiento, aunque un redireccionamiento implícito, lo que significa que emitirá un 302 (redireccionamiento temporal), pero dado que la pregunta informa que todo el sitio web será servido como https, entonces el redireccionamiento apropiado debería ser un 301 (redireccionamiento permanente ).

redirect scheme https code 301 if !{ ssl_fc }

Parece un cambio pequeño, pero el impacto puede ser enorme dependiendo del sitio web, con un redireccionamiento permanente le informamos al navegador que ya no debería buscar la versión http desde el principio (evitando redireccionamientos futuros) - un ahorro de tiempo para https sitios. También ayuda con el SEO, pero sin dividir el jugo de sus enlaces.

Marcos Abreu
fuente
41

Para redirigir todo el tráfico:

redirect scheme https if !{ ssl_fc }

Para redirigir una sola URL (en caso de múltiples frontend / backend)

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

usuario2966600
fuente
1
Gracias, la condición "solo en un anfitrión específico" era justo lo que estaba buscando.
Quentin Skousen
¿Podría mostrar un ejemplo práctico de la segunda opción, por favor?
RicarHincapie
16

Según http://parsnips.net/haproxy-http-to-https-redirect/ debería ser tan fácil como configurar su haproxy.cfg para que contenga lo siguiente.

#---------------------------------------------------------------------
# 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
fuente
7
Así que redirigiría todo a foo.bar.com . Sin embargo, lo ideal sería que foo.bar.com/baz redirigiera a foo.bar.com/baz . También necesitamos parámetros de consulta.
Jon Chu
@JonChu plantea un caso de uso válido, esta es solo una solución parcial.
Jay Taylor
3
En lugar de utilizar la ubicación de redireccionamiento, intente redireccionar el prefijo https: //foo.bar.com. Debería ayudar con el caso de uso que menciona Jon Chu.
xangxiong
16

La mejor forma garantizada de redirigir todo http a https es:

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

Esto es un poco más elegante usando el 'código 301', pero también podría hacerle saber al cliente que es permanente. La parte 'modo http' no es esencial con la configuración predeterminada, pero no hace daño. Si tiene mode tcpen la sección de valores predeterminados (como lo hice yo), entonces es necesario.

Maitreya
fuente
10

Una ligera variación de la solución de user2966600 ...

Para redirigir todo excepto una sola URL (en caso de múltiples frontend / backend):

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

Como dijo Jay Taylor, HAProxy 1.5-dev tiene la redirect schemedirectiva de configuración, que logra exactamente lo que necesita.

Sin embargo, si no puede usar 1.5, y si está dispuesto a compilar HAProxy desde la fuente, hice una copia de respaldo de la redirect schemefuncionalidad para que funcione en 1.4. Puede obtener el parche aquí: http://marc.info/?l=haproxy&m=138456233430692&w=2

oxidado
fuente
2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com
sanyi
fuente
1

En las versiones más recientes de HAProxy se recomienda utilizar

http-request redirect scheme https if !{ ssl_fc }

para redirigir el tráfico http a https.

Ese tipo
fuente
0

Si desea reescribir la URL, debe cambiar el host virtual de su sitio agregando estas líneas:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

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

Pero, si desea redirigir todas sus solicitudes en el puerto 80 al puerto 443 de los servidores web detrás del proxy, puede probar este ejemplo conf en su 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

Espero que esto te ayude

Plano
fuente
0

¿Por qué no usa ACL para distinguir el tráfico? encima de mi cabeza:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Esto se suma a lo que respondió Matthew Brown.

Consulte los documentos de ha , busque cosas como hdr_dom y más abajo para encontrar más opciones de ACL. Hay muchas opciones.

Glenn Plas
fuente
0

Se puede hacer así:

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

Cualquier tráfico que llegue a http se redirigirá a https

chandan
fuente
0

la declaración de redireccionamiento es heredada

utilice redireccionamiento de solicitud http en su lugar

acl http      ssl_fc,not
http-request redirect scheme https if http
1AmirJalali
fuente
0

Simplemente:

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
fuente