Using the ACL in HAProxy for Load Balancing Named Virtual Hosts

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.

XenServer 3.2.0: Upgrade Debian Linux from Sarge to Etch

If you are running XenServer 3.2.0, then you have a built in Debian Sarge image. If you happen to want to upgrade an instance to Debian Etch (the latest stable build as of February 1, 2008), you should follow these steps. It isn’t a simple apt-get dist-upgrade command as other websites may have you believe. The following steps are a summary of what commands I performed while following the official upgrade guide.

If you aren’t running a XenServer instance, then I would suggest following the official guide yourself to prevent anything bad from happening (Debian Etch Upgrade Guide). My instance that I used for this installation was a fresh install of the Sarge image, so I won’t be going into any special circumstances that may need to be addressed by those who have installed a whole load of extras.

Let’s go!

Choose a Mirror
Go to Debian Mirror List and select a mirror. I happened to choose http://ftp.us.debian.org/debian as my mirror because I’m in the United States.

Update /etc/apt/sources.list with…

deb http://ftp.us.debian.org/debian etch main contrib

Perform the Upgrade


rm /etc/apt/preferences
mount -o remount,rw /
aptitude update
aptitude upgrade
aptitude install initrd-tools
aptitude dist-upgrade
aptitude update

See? Not so hard. That is all I needed to do to upgrade my XenServer 3.2.0 Debian Sarge instance to Debian Etch. I am not saying these simplified steps will work for everyone, but for those few that have the same type of setup as we do, these instructions should simplify the upgrade process. Please comment with questions and/or suggestions… and if all else fails, use the official guide!

– Matt