haproxy + stunnel + keep-alive?


10

Vorrei mettere lo stunnel davanti a haproxy 1.4 per gestire il traffico HTTPS. Ho anche bisogno di stunnel per aggiungere l' intestazione X-Forwarded-For . Ciò può essere ottenuto con le patch "stunnel-4.xx-xforwarded-for.diff" dal sito Web haproxy.

Tuttavia, la descrizione menziona:

Nota che questa patch non funziona con keep-alive, ...

La mia domanda è: cosa significherà questo in pratica per me? Non sono sicuro

  1. se si tratta del keep-alive in mezzo
    • client e stunnel
    • stunnel e haproxy
    • o haproxy e server back-end?
  2. cosa significa per le prestazioni: se ho 100 icone su una pagina Web, il browser dovrà negoziare 100 connessioni SSL complete o può riutilizzare la connessione SSL, creando solo nuove connessioni TCP?

Risposte:


12

Si tratta di HTTP keep-alive, che consente a più richieste di risorse di passare attraverso una singola sessione TCP (e, con SSL, una singola sessione SSL). Ciò è di grande importanza per le prestazioni di un sito SSL, poiché senza keep-alive sarebbe necessaria una stretta di mano SSL per ogni risorsa richiesta.

Quindi, la preoccupazione qui è una grande sessione keep-alive dal client fino al server back-end. È una cosa importante per le prestazioni e, come è ovvio, per i moderni server HTTP, ma questa patch dice che non la supporta. Diamo un'occhiata al perché ...


Una sessione keep-alive è solo più richieste una dopo l'altra: una volta che il server termina la sua risposta a una richiesta, il server non invia un FINpacchetto per terminare la sessione TCP; il client può semplicemente inviare un altro batch di intestazioni.

Per capire cosa sta facendo quella patch, ecco un esempio di conversazione keep-alive:

Cliente:

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

Server:

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

Ecco dove si fermerebbe una connessione non keep-alive. Ma keep-alive consente al client di licenziarne un altro:

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

Per l'ID client nel proxy, alcuni proxy inversi possono aggiungere X-Forwarded-Fornell'intestazione in ogni richiesta client. Ciò indica al server upstream da dove proviene la richiesta (anziché ogni richiesta avviata dall'IP del proxy inverso), per la sanità mentale nella registrazione e altre esigenze dell'applicazione.

L' X-Forwarded-Forintestazione deve essere iniettata in ogni richiesta di risorse client inviata attraverso la connessione keep-alive, poiché le intestazioni complete vengono inviate ogni volta; la gestione X-Forwarded-Fordell'intestazione e la traduzione in essa essendo l'IP "reale" della richiesta viene eseguito su una base per richiesta, non per sessione TCP-keep-alive. Ehi, forse c'è un fantastico software di proxy inverso là fuori che utilizza una singola sessione keep-alive per soddisfare le richieste di più client.

Questo è dove questa patch fallisce.


La patch in quel sito controlla il buffer della sessione TCP per la fine della prima serie di intestazioni HTTP nello stream e inietta la nuova intestazione nello stream dopo la fine della prima serie di intestazioni. Al termine, considera il X-Forwarded-Forlavoro svolto e interrompe la scansione per la fine di nuovi set di intestazioni. Questo metodo non è a conoscenza di tutte le future intestazioni che arrivano tramite richieste successive.

Non posso davvero biasimarli; stunnel non è stato realizzato per gestire e tradurre il contenuto dei suoi flussi.

L'effetto che ciò avrebbe sul tuo sistema è che la prima richiesta di un flusso keep-alive otterrà l' X-Forwarded-Forintestazione iniettata correttamente e tutte le richieste successive funzioneranno bene, ma non avranno l'intestazione.

A meno che non ci sia un'altra patch di iniezione di intestazione là fuori che può gestire più richieste client per connessione (o ottenere questa ottimizzata con l'aiuto dei nostri amici su Stack Overflow), potrebbe essere necessario esaminare altre opzioni per la terminazione SSL.


1
Ottima risposta, grazie. Mi ricorda, perché è una buona idea porre domande qui.
Chris Lercher,

1
Per consentire l'iniezione di intestazione keep-alive nello stunnel, dovrebbe essere in grado di parlare quasi tutto l'HTTP, il che richiederebbe un'enorme quantità di lavoro. Detto questo, puoi anche usare il protocollo PROXY di HAproxy (che richiede una patch per stunnel o in alternativa stud ) e iniettare l'intestazione in HAproxy. Vedi i documenti per maggiori informazioni (dalla cache di Google, poiché il sito HAproxy sembra essere parzialmente inattivo ATM)
Holger Appena il


3

Simile a quello che ho pubblicato in un altro thread, HAProxy supporta SSL nativo su entrambi i lati da 1.5-dev12. Quindi avere X-Forwarded-For, HTTP keep-alive così come un'intestazione che dice al server che la connessione è stata fatta tramite SSL è semplice come la seguente:

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 ...
    ...

È molto più facile che rattoppare lo stunnel e molto meglio che dover lasciar perdere.


Potresti voler usare ssl_fc invece di is_ssl
josch

2

Estendendo l'eccellente risposta di Shane, potresti utilizzare Nginx come terminatore SSL di fronte a HAproxy. Gestisce correttamente keep-alive tra client e nginx, che è il lato più sensibile alla latenza e crea una nuova connessione per il back-end per ogni richiesta del client, inviando l'X-FORWARDED-FOR in ognuno.


1
Tuttavia, se hai bisogno di websocket, nginx non funzionerà.
wt

Inoltre, supporta la cache di sessione SSL.
3molo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.