5

How can we implement session stickiness in HAProxy when SSL must terminate on the backend servers? We need the stickiness because backends cannot share sessions.

This is my original configuration:

# SSL passthrough
listen https_handler
    bind 1.2.3.4:443
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

# haproxy logs (not sticking)
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.396] fe BACKEND_Website/s1 37/0/1/3/41 200 8364
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s1 36/0/1/1/39 200 9082
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.456] fe BACKEND_Website/s2 35/0/1/3/39 200 2529
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 35/0/0/3/38 200 1460
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.501] fe BACKEND_Website/s2 36/0/1/1/109 200 376
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.545] fe BACKEND_Website/s1 36/0/1/1/74 200 2298
10.x.x.2:xxxxx [17/Dec/2014:19:29:41.604] fe BACKEND_Website/s1 35/0/1/2/38 200 5542

The config below is my attempt to read the src:

This results in a 502 Bad Gateway error. I assume, it is because the traffic is already decrypted by the time it reaches the backend.

# terminate SSL at HAProxy 
listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443
    server s2 1.1.1.2:443

Notice that I plugged the cert to the binding. This is for HAProxy to be able to read the src and setup the stick-table. (Not sure if this is correct.) And at this point, the traffic is already decrypted.

I think the problem lies when this decrypted traffic is passed to the backend servers which expects encrypted traffic...

I have seen these suggestions:

  1. Terminate SSL at HAProxy 1.5 - not possible in my case. SSL need to be handled by the backend servers.
  2. Use SSL Session ID to maintain stickiness. - I'm skeptical to try this out because I don't quite understand it yet. And it seems to be using a modified (?) version of haproxy.
  3. Use send-proxy directive & X-Forward-Proto header. - but realized this also needs an HTTP-only backend.

Would appreciate any advice.

2 Answers2

3

The easiest solution is to use balance source, but if many clients come from the same IP, it may not be very fair on your backend servers.

See http://blog.haproxy.com/2013/04/22/client-ip-persistence-or-source-ip-hash-load-balancing/ for more discussion on methods to accomplish this.

Jim G.
  • 2,707
0

If the root of your issue is the fact that the backend servers expect traffic to be HTTPS rather than HTTP, try encrypting the HTTP and do your regular Layer7 load balancing.

listen https_handler
    bind 1.2.3.4:443 ssl crt /etc/ssl/certs/certs.pem
    mode http
    balance leastconn
    # any stick rules you need
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

Easier yet - as you apparently try to stick by src anyway, why are you even decrypting the TCP traffic in the first place?

listen https
    bind 1.2.3.4:443 # <- NO ssl setting
    mode tcp
    balance leastconn
    stick match src
    stick-table type ip size 200k expire 30m
    server s1 1.1.1.1:443 ssl
    server s2 1.1.1.2:443 ssl

In TCP mode, you don't care about the payload. Specifically, you don't care whether it's encrypted and how.

Felix Frank
  • 3,123