Adding Session Persistence for HAProxy

HAProxy provides a multitude of load balancing algorithms, some of which provide features that automatically ensure that web sessions have persistent connections to the same backend server. You can configure a balance algorithm such as hdr, rdp-cookie, source, uri, or url_param to ensure that traffic is always routed to the same web server for a particular incoming connection during the session. For example, the source algorithm creates a hash of the source IP address and maps it to a particular backend server. If you use the rdp-cookie, or url_param algorithms, you might need to configure the backend web servers or the web applications for these mechanisms to run efficiently.

If the implementation requires the use of the leastconn, roundrobin, or static-rr algorithm, you can achieve session persistence by using server-dependent cookies.

  1. Configure the server for standard or weighted round robin load balancing.
  2. Edit the HAProxy configuration to append the cookie directive to each server in the configuration.

    To enable session persistence for all pages on a web server, use the cookie directive to define the name of the cookie to be inserted and add the cookie option and server name to the server lines, for example:

    cookie WEBSVR insert
    server websrv1 192.168.1.71:80 weight 1 maxconn 512 cookie 1 check
    server websrv2 192.168.1.72:80 weight 1 maxconn 512 cookie 2 check

    HAProxy includes the Set-Cookie: header that identifies the web server in its response to the client, for example: Set-Cookie: WEBSVR=N; path=page_path . If a client specifies the WEBSVR cookie in a request, HAProxy forwards the request to the web server whose server cookievalue matches the value of WEBSVR.

    To enable persistence selectively on a web server, use the cookie directive to configure the HAProxy to expect the specified cookie, typically a session ID cookie or other existing cookie, to be prefixed with the server cookie value and a ~ delimiter, for example:

    cookie SESSIONID prefix
    server websrv1 192.168.1.71:80 weight 1 maxconn 512 cookie 1 check
    server websrv2 192.168.1.72:80 weight 1 maxconn 512 cookie 2 check

    If the value of SESSIONID is prefixed with a server cookie value, for example: Set-Cookie: SESSIONID=N~Session_ID;, HAProxy strips the prefix and delimiter from the SESSIONID cookie before forwarding the request to the web server whose server cookie value matches the prefix.

  3. Reload the HAProxy systemd service.
    sudo systemctl reload haproxy
  4. Verify that session persistence is working.

    The following example shows how to use curl to test session persistence by including a cookie in the curl request. You can use a while loop in the shell to repeat the test over a period. To cancel out of the loop, use the Ctrl-C key combination:

    while true; do curl http://10.0.0.10 --cookie "SESSIONID=1~1234;"; sleep 1; done

    The output shows that even though the request is passing through a load balancer that's configured for weighted round-robin load balancing, the request is always directed to the same web server because session persistence is maintained.

    This is HTTP server websrv1 (192.168.1.71).
    This is HTTP server websrv1 (192.168.1.71).
    This is HTTP server websrv1 (192.168.1.71).
    ...

    Note:

    In these examples the web servers are configured to serve a page that describes the web server name and IP address. The outputs in a real world configuration are likely to differ.

    A real web application would typically set the session ID on the server side, in which case the first HAProxy response would include the prefixed cookie in the Set-Cookie: header.