Until recently, I wasn’t aware of the ACL system in HAProxy, but once I found it I realized that I have been missing a very important part of load balancing with HAProxy!
While the full configuration settings available for the ACL are listed in the configuration doc, the below example includes the basics that you’ll need to build an HAProxy load balancer that supports multiple host headers.
Here is a quick example haproxy configuration file that uses ACLs:
global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 user haproxy group haproxy daemon defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 contimeout 5000 clitimeout 50000 srvtimeout 50000 frontend http-in bind *:80 acl is_www_example_com hdr_end(host) -i example.com acl is_www_domain_com hdr_end(host) -i domain.com use_backend www_example_com if is_www_example_com use_backend www_domain_com if is_www_domain_com default_backend www_example_com backend www_example_com balance roundrobin cookie SERVERID insert nocache indirect option httpchk HEAD /check.txt HTTP/1.0 option httpclose option forwardfor server Server1 10.1.1.1:80 cookie Server1 server Server2 10.1.1.2:80 cookie Server2 backend www_domain_com balance roundrobin cookie SERVERID insert nocache indirect option httpchk HEAD /check.txt HTTP/1.0 option httpclose option forwardfor server Server1 192.168.5.1:80 cookie Server1 server Server2 192.168.5.2:80 cookie Server2
In HAProxy 1.3, the ACL rules are placed in a “frontend” and (depending on the logic) the request is proxied through to any number of “backends”. You’ll notice in our frontend entitled “http-in” that I’m checking the host header using the hdr_end feature. This feature performs a simple check on the host header to see if it ends with the provided argument.
You can find the rest of the Layer 7 matching options by searching for “7.5.3. Matching at Layer 7” in the configuration doc I linked to above. A few of the options I didn’t use but you might find useful are path_beg, path_end, path_sub, path_reg, url_beg, url_end, url_sub, and url_reg. The *_reg commands allow you to perform RegEx matching on the url/path, but there is the usual performance consideration you need to make for RegEx (especially since this is a load balancer).
The first “use_backend” that matches a request will be used, and if none are matched, then HAProxy will use the “default_backend”. You can also combine ACL rules in the “use_backend” statements to match one or more rules. See the configuration doc for more helpful info.
If you’re looking to use HAProxy with SSL, that requires a different approach, and I’ll blog about that soon.