HAProxy redirecionando http para https (ssl)

99

Estou usando o HAProxy para balanceamento de carga e só quero que meu site ofereça suporte a https. Portanto, gostaria de redirecionar todas as solicitações na porta 80 para a porta 443.

Como eu faria isso?

Edit: Gostaríamos de redirecionar para o mesmo url em https, preservando os parâmetros de consulta. Assim, http://foo.com/bar redirecionaria para https://foo.com/bar

Jon Chu
fonte

Respostas:

137

Eu descobri que esta é a maior ajuda :

Use o HAProxy 1.5 ou mais recente e simplesmente adicione a seguinte linha à configuração do front-end:

redirect scheme https code 301 if !{ ssl_fc }
Jay Taylor
fonte
20
Para adicionar a isso, a partir da resposta do usuário 2966600 abaixo, com 301 adicionados, use isso para redirecionar para https apenas para um domínio específico:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc }
Quentin Skousen
1
Isso funcionou. Embora não funcione sem o 'código 301'. Obrigado pela atualização.
deej
6
Uma sintaxe equivalente à resposta dada seria assim: http-request redirect scheme https code 301 if !{ ssl_fc }. A documentação para redirecionamento de http no ALOHA HAProxy 7.0 chega a mencionar que " a sintaxe de ambas as diretivas é a mesma, isto é, o redirecionamento agora é considerado legado e as configurações devem passar para o formulário de redirecionamento de solicitação http ". Eu deduzo, sem ter certeza absoluta, que a mesma explicação se aplica aos lançamentos mais recentes da versão de código aberto do HAProxy.
rodolfojcj
Obrigado pela sua resposta. Você poderia expandir para explicar onde devemos adicionar esta linha? No frontend / backend / default / global / ..?
realtebo de
Normalmente, coloco-o dentro do front-end, mas os redirecionamentos são apenas um cabeçalho, portanto, espero que um redirecionamento possa ser acionado até que os cabeçalhos de resposta sejam enviados. Gostaria de saber se funciona nas duas localidades, posso tentar.
Jay Taylor
68

Não tenho reputação suficiente para comentar uma resposta anterior, então estou postando uma nova resposta para complementar a resposta de Jay Taylor. Basicamente, sua resposta fará o redirecionamento, porém um redirecionamento implícito, o que significa que emitirá um 302 (redirecionamento temporário), mas como a pergunta informa que todo o site será servido como https, então o redirecionamento apropriado deve ser 301 (redirecionamento permanente )

redirect scheme https code 301 if !{ ssl_fc }

Parece uma pequena mudança, mas o impacto pode ser enorme dependendo do site, com um redirecionamento permanente estamos informando ao navegador que ele não deve mais procurar a versão http desde o início (evitando redirecionamentos futuros) - uma economia de tempo para https sites. Também ajuda com SEO, mas não divide o suco de seus links.

Marcos Abreu
fonte
41

Para redirecionar todo o tráfego:

redirect scheme https if !{ ssl_fc }

Para redirecionar um único url (no caso de vários frontend / backend)

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

user2966600
fonte
1
Obrigado, a condição "apenas em um host específico" era exatamente o que eu estava procurando!
Quentin Skousen
Você pode mostrar um exemplo prático da segunda opção, por favor?
RicarHincapie
16

De acordo com http://parsnips.net/haproxy-http-to-https-redirect/ , deve ser tão fácil quanto configurar seu haproxy.cfg para conter o seguinte.

#---------------------------------------------------------------------
# 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
fonte
7
Isso redirecionaria tudo para foo.bar.com . Porém, o ideal é que foo.bar.com/baz redirecione para foo.bar.com/baz . Também precisamos de parâmetros de consulta.
Jon Chu
@JonChu levanta um caso de uso válido, esta é apenas uma solução parcial.
Jay Taylor
3
Em vez de usar o local de redirecionamento, tente redirecionar o prefixo https: //foo.bar.com. Deve ajudar com o caso de uso que Jon Chu menciona.
xangxiong
16

A melhor maneira garantida de redirecionar tudo de http para https é:

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

Isso é um pouco mais elaborado usando o 'código 301 ′, mas pode muito bem deixar o cliente saber que é permanente. A parte 'modo http' não é essencial com a configuração padrão, mas não faz mal. Se você tiver mode tcpna seção de padrões (como eu fiz), então é necessário.

Maitreya
fonte
10

Uma ligeira variação da solução do user2966600 ...

Para redirecionar todos, exceto um único URL (no caso de vários front-end / back-end):

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

Como disse Jay Taylor, o HAProxy 1.5-dev tem a redirect schemediretiva de configuração, que realiza exatamente o que você precisa.

No entanto, se você não puder usar o 1.5, e se estiver pronto para compilar o HAProxy a partir do código-fonte, fiz backport da redirect schemefuncionalidade para que funcione no 1.4. Você pode obter o patch aqui: http://marc.info/?l=haproxy&m=138456233430692&w=2

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

Em versões mais recentes do HAProxy, é recomendado o uso

http-request redirect scheme https if !{ ssl_fc }

para redirecionar o tráfego http para https.

Aquele cara
fonte
0

Se você deseja reescrever o url, você deve alterar o host virtual do seu site adicionando estas linhas:

### Enabling mod_rewrite
Options FollowSymLinks
RewriteEngine on

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

Mas, se você deseja redirecionar todas as suas solicitações na porta 80 para a porta 443 dos servidores da web atrás do proxy, você pode tentar este exemplo de configuração em seu 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 isso lhe ajude

Plano
fonte
0

Por que você não usa ACLs para distinguir o tráfego? no topo da minha cabeça:

acl go_sslwebserver path bar
use_backend sslwebserver if go_sslwebserver

Isso vai além do que Matthew Brown respondeu.

Veja os documentos ha , pesquise coisas como hdr_dom e abaixo para encontrar mais opções de ACL. Existem muitas opções.

Glenn Plas
fonte
0

Pode ser feito assim -

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

Qualquer tráfego que alcance http será redirecionado para https

Chandan
fonte
0

declaração de redirecionamento é legada

use redirecionamento de solicitação http em vez disso

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

Simplesmente:

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
fonte