haproxy + stunnel + keep-alive?

10

Eu gostaria de colocar o stunnel na frente do haproxy 1.4 para lidar com o tráfego HTTPS. Eu também preciso de stunnel para adicionar o cabeçalho X-Forwarded-For . Isto pode ser conseguido com os patches "stunnel-4.xx-xforwarded-for.diff" do website da haproxy.

No entanto, a descrição menciona:

Note that this patch does not work with keep-alive, ...

Minha pergunta é: O que isso significa na prática para mim? Não tenho certeza,

  1. se isso é sobre o keep-alive entre
    • cliente e stunnel
    • stunnel e haproxy
    • ou haproxy e servidor de back-end?
  2. o que isso significa para desempenho: se eu tiver 100 ícones em uma página da Web, o navegador terá que negociar 100 conexões SSL completas ou poderá reutilizar a conexão SSL, apenas criando novas conexões TCP?
por Chris Lercher 15.08.2011 / 16:35

4 respostas

12

Trata-se de keep-alive de HTTP, que permite que várias solicitações de recursos passem por uma única sessão TCP (e, com SSL, uma única sessão SSL). Isso é de grande importância para o desempenho de um site SSL, pois, sem o recurso keep-alive, um handshake SSL seria necessário para cada recurso solicitado.

Portanto, a preocupação aqui é uma grande sessão de manutenção do cliente até o servidor de back-end. É uma coisa importante para o desempenho e, como é natural, para os servidores HTTP modernos, mas este patch diz que não é compatível. Vamos ver por que ...

Uma sessão keep-alive é apenas mais solicitações uma após a outra - depois que o servidor termina sua resposta a uma solicitação, o servidor não envia um pacote FIN para encerrar a sessão TCP; o cliente pode simplesmente enviar outro lote de cabeçalhos.

Para entender o que esse patch está fazendo, aqui está um exemplo de uma conversa de manter vivo:

Cliente:

GET / HTTP/1.1
Connection: keep-alive
Host: domain.com
...

Servidor:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Server: Apache
Content-Length: 34
.... (other headers)
<html><head>content!</head></html>

Aqui é onde uma conexão não-viva iria parar. Mas o keep-alive permite que o cliente simplesmente dispare outro:

GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...

Para o ID do cliente no proxy, alguns proxies reversos podem incluir o cabeçalho X-Forwarded-For em cada solicitação do cliente. Isso informa ao servidor upstream de onde vem a solicitação (em vez de cada solicitação iniciada a partir do IP do proxy reverso), para sanidade no registro e outras necessidades do aplicativo.

O cabeçalho X-Forwarded-For precisa ser injetado em cada solicitação de recurso do cliente enviada por meio da conexão keep-alive, pois os cabeçalhos completos são enviados a cada vez; O tratamento do cabeçalho X-Forwarded-For e da tradução para ele, sendo o IP de solicitação "real", é feito em uma base por requisição, não por TCP-keep-alive-session. E, ei, talvez haja algum incrível software de proxy reverso que use uma única sessão de manutenção para atender a solicitações de vários clientes.

É aqui que esse patch falha.

O patch nesse site assiste o buffer da sessão TCP para o final do primeiro conjunto de cabeçalhos HTTP no fluxo e injeta o novo cabeçalho no fluxo após o final desse primeiro conjunto de cabeçalhos. Depois disso, ele considera o trabalho X-Forwarded-For concluído e interrompe a verificação para o final de novos conjuntos de cabeçalhos. Este método não tem consciência de todos os futuros cabeçalhos que chegam através de pedidos subsequentes.

Não posso culpá-los; O stunnel não foi realmente construído para lidar e traduzir o conteúdo de seus streams.

O efeito que isso teria em seu sistema é que a solicitação primeiro de um fluxo keep-alive obterá o cabeçalho X-Forwarded-For injetado corretamente, e todas as solicitações subsequentes funcionarão bem - mas eles não terão o cabeçalho.

A menos que exista outro patch de injeção de cabeçalho que possa atender a várias solicitações de clientes por conexão (ou ajustar essa com a ajuda de nossos amigos no Stack Overflow), talvez seja necessário consultar outras opções para sua terminação SSL.

    
por 15.08.2011 / 19:41
5

O STunnel 4.45 corrige isso apropriadamente usando alguns novos recursos (protocolo de proxy) que vêm com o HAProxy 1.15

Também corrige os problemas com os patches anteriores e o Keep Alive

    
por 01.11.2011 / 12:20
3

Semelhante ao que eu publiquei em outro thread, o HAProxy suporta SSL nativo em ambos os lados desde o 1.5-dev12. Então, ter X-Forwarded-For, HTTP keep-alive, assim como um cabeçalho informando ao servidor que a conexão foi feita via SSL é tão simples quanto o seguinte:

listen front
    bind :80
    bind :443 ssl crt /etc/haproxy/haproxy.pem
    mode http
    option http-server-close
    option forwardfor
    reqadd X-Forwarded-Proto:\ https if { is_ssl }
    server srv1 1.1.1.1:80 check ...
    ...

É muito mais fácil do que consertar stunnel e muito melhor do que ter que deixar o keep-alive.

    
por 16.09.2012 / 10:38
2

Estendendo a excelente resposta de Shane, você poderia usar o Nginx como terminador SSL na frente do HAproxy. Ele lida corretamente com o keep-alive entre o client e o nginx, que é o lado mais sensível à latência e faz uma nova conexão com o backend para cada solicitação do cliente, enviando o X-FORWARDED-FOR em cada um.

    
por 17.08.2011 / 16:51