Struggling with Haproxy 1.5 ACLs using regular expressions and URL Parameters

access-control-listhaproxy

I am using Haproxy 1.5.3 setup with ssl on the frontend and also sending ssl to the backend servers. the mode is http and using acls to determine stickyness.

My test requests are as follows:

  1. wget https: //domain.com/ping?IPT=transpor6t&FROM_ADDRESS=409
  2. wget https: //domain.com/ping?FROM_ADDRESS=409&IPT=transport6
  3. the real url will have 5 different parameters and the FROM_ADDRESS will be the 3rd Parameter.

I need to create sticky requests on this 3rd Parameter and there seems to be many ways to do this using Haproxy and even though using regex is expensive it provides us the most flexibility, so that is what we chose (in this example we moved away from regex to simplify the problem and decided just to look at the last character of the parameter, so to make sure the regex is not the problem.

Our ACL setup (more of a test bed to see if we can get it to work)

acl block_1 urlp_end(FROM_ADDRESS) 0
acl block_2 urlp_end(FROM_ADDRESS) 9

   use_backend block_1_hosts if block_1
   use_backend block_2_hosts if block_2

backend block_1_hosts
    option httpchk GET /ping
    server s1 s1.domain.com:443 weight 1 maxconn 2000 check ssl verify none inter 2000
    server s2 s2.domain.com:443 weight 1 maxconn 2000 check ssl verify none inter 2000 backup

  backend block_2_hosts
    option httpchk GET /ping
    server s1 s1.domain.com:443 weight 1 maxconn 2000 check ssl verify none inter 2000 backup
    server s2 s2.domain.com:443 weight 1 maxconn 2000 check ssl verify none inter 2000

With the testing we have done we believe that only the first parameter it finds in the URL can be matched (it does not search the rest of the parameters). This may be a bug or maybe by design (the docs seem a little ambiguous around urlp at least to us) but it would make sense that you should be able to match all parameter in the URL.

**Test1 - FROM_ADDRESS in the second parameter position fails**
wget https://domain.com/ping?IPT=transpor6t&FROM_ADDRESS=409
haproxy logs:
5.35.250.77:41464 [22/Aug/2014:14:20:49.783] https-in~ https-in/<NOSRV> -1/-1/-1/-1/12 503 212 - - SC-- 0/0/0/0/0 0/0 "GET /ping?IPT=transpor6t HTTP/1.0"

**Test2 - FROM_ADDRESS in the first parameter position passes**
wget https://domain.com/ping?FROM_ADDRESS=409&IPT=transport6
haproxy logs:
5.35.250.77:41465 [22/Aug/2014:14:21:33.763] https-in~ block_2_hosts/rs6 12/0/2/2/16 200 229 - - ---- 0/0/0/0/0 0/0 "GET /ping?FROM_ADDRESS=409 HTTP/1.0"

Shouldn't they both pass with this ACL? Any thoughts?
Many thanks,
Andre

Best Answer

Haven't tested this yet, but try specifying the delimiter:

acl block_1 urlp_end(FROM_ADDRESS,&) 0
acl block_2 urlp_end(FROM_ADDRESS,&) 9