haproxy + stunnel + keep-alive?
This is about HTTP keep-alive, which allows for multiple resource requests to come through a single TCP session (and, with SSL, a single SSL session). This is of great importance to the performance of an SSL site, as without keep-alive, an SSL handshake would be needed for each requested resource.
So, the concern here is one big keep-alive session from the client all the way to the backend server. It's an important thing for performance, and taken as a matter of course for modern HTTP servers, but this patch says it doesn't support it. Let's look into why..
A keep-alive session is just more requests one after another - once the server finishes its response to one request, the server doesn't sent a FIN
packet to end the TCP session; the client can simply send another batch of headers.
To understand what that patch is doing, here's an example of a keep-alive conversation:
Client:
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>
Here's where a non-keep-alive connection would stop. But, keep-alive allows the client to just fire off another:
GET /images/some/image.on.the.page.jpg HTTP/1.1
Connection: keep-alive
Host: domain.com
...
For client ID in proxying, some reverse proxies can add in the X-Forwarded-For
header in each client request. That tells the upstream server where the request is coming from (instead of every request initiating from the reverse proxy's IP), for sanity in logging and other application needs.
The X-Forwarded-For
header needs to be injected into each and every client resource request sent through the keep-alive connection, as the full headers are sent each time; handling of the X-Forwarded-For
header and translation into it being the "real" request IP is done on a per-request, not per-TCP-keep-alive-session, basis. And hey, maybe there's some awesome reverse proxy software out there that uses a single keep-alive session to service requests from multiple clients.
This is where this patch fails.
The patch at that site watches the TCP session's buffer for the end of the first set of HTTP headers in the stream, and injects the new header into the stream after the end of that first set of headers. After this is done, it considers the X-Forwarded-For
job done, and stops scanning for the end of new sets of headers. This method has no awareness of all of future headers coming in via subsequent requests.
Can't really blame them; stunnel wasn't really built to do handling and translation of the contents of its streams.
The effect that this would have on your system is that the first request of a keep-alive stream will get the X-Forwarded-For
header injected properly, and all of the subsequent requests will work just fine - but they won't have the header.
Unless there's another header injection patch out there that can handle multiple client requests per connection (or get this one tweaked with the help of our friends over at Stack Overflow), you may need to look at other options for your SSL termination.
STunnel 4.45 fixes this properly using some new capabilities (proxy protocol) coming with HAProxy 1.15
- http://stunnel.mirt.net/pipermail/stunnel-announce/2011-October/000062.html
- http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
It also fixes the issues with previous patches and Keep Alive