HAProxy - OR operator - multiple ACLs

Started by markes20754, April 29, 2024, 09:30:27 PM

Previous topic - Next topic
In the HAProxy documentation, an OR operator can be used by defining multiple ACLs with the same name. See https://www.haproxy.com/documentation/haproxy-configuration-tutorials/core-concepts/acls/#or-operator

You can also create an or statement by defining multiple ACLs with the same name. Below, the condition is again true if the requested URL path begins with /images/ or the URL path ends with .jpg:

frontend www
  bind :80
  acl images_url path_beg /images/
  acl images_url path_end .jpg

  use_backend static_assets if images_url
backend static_assets
  server s1 192.168.50.20:80


OPNsense's implementation of HAProxy generates a unique ID name for each ACL rather than to use the actual name that the user gives in the GUI. This appears to make the use of this OR operator not possible. For example, let's say that I had two host names for the same website (foo.com and www.foo.com) If I created an ACL with both of these conditions and gave them both the same name, then in a "normal" HAProxy config (including PFSense), I would only need to build one rule. As it stands now, I have to create a unique rule for each condition and add all of those rules to the front-end pool.

If you examine the OPNSense HAProxy config export, both are given a unique system generated ACL which results in the OR condition not being applied.

    # ACL: h-www_foo_com
    acl acl_662818fddd6816.90414207 hdr(host) -i www.foo.com

    # ACL: h-www_foo_com
    acl acl_662830c24229a7.03064246 hdr(host) -i foo.com

    # ACTION: foo_com_rule
    use_backend foo_backend if acl_662818fddd6816.90414207


Would it be possible to have the system generated ACL name be the same if the user inputed ACL name is the same? This would allow for the OR condition to be used on OPNSense like it does with PFSense and other implementations.

Thanks!
Mark

Hey there. ha-proxy is a community maintained plugin, so it's best if you ask here on github:

https://github.com/opnsense/plugins
Hardware:
DEC740

Why would you?

The HAproxy ACLs are basically the GUI "conditions", the ACTIONs are the "rules".

In order to have the same as what you depicted, you can create two conditions to match the host to www.foo.com and foo.com, respectively. You can then create a rule with a logical OR using both conditions (you can select as many conditions as you wish).
It results in:


    # ACL: foo_com
    acl acl_6630a6c1a88162.09000819 hdr(host) -i foo.com

    # ACL: www_foo_com
    acl acl_6630a6af35a1b8.90849579 hdr(host) -i www.foo.com

    # ACTION: use_foo
    use_backend foo_backend if acl_6630a6c1a88162.09000819 || acl_6630a6af35a1b8.90849579


And serves exactly the same purpose.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 770 up, Bufferbloat A

Consider the following combined host/vpath rules:

ACL NAME "MY_HOSTS"
Host: www.foo.com
Host: foo.com
Host: www.foo.co.uk

ACL_NAME "ALLOWED_VPaths"
VPath: /bar

Without the OR condition on the ACL in OPNSense, you need to create three rules to accomplish the rule condition to only allow https://www.foo.com/bar, https://foo.com/bar and https://www.foo.co.uk/bar

With the OR condition on the same ACL name you can create one rule that effectively says:
(HOSTS Start With [https://www.foo.com OR https://foo.com OR https://www.foo.co.uk]) AND (VPATH Starts With  [/bar])

Hope that makes sense.

April 30, 2024, 03:02:42 PM #4 Last Edit: April 30, 2024, 05:13:39 PM by meyergru
Correct. If you aim to minimize the number of rules, you can use regex matching instead of simple matching, for your example, it amounts to: /^((www\.)?foo\.com)|www\.foo\.co\.uk$/i

I think it is not so easy because every item (at least those selectable) has an ID by which it is referenced. Thus, if you had two conditions with the same name, they still have two IDs. The acl name is derived from this in order to be specific (and for referential integrity). You could create ambiguous configurations if you used the user-assigned names. These are only possible because in reality, their IDS differ. And if you used the user-assigned names directly instead of the IDs to reference items, you would have to require uniqueness, which would not help for your requirement, either.
Intel N100, 4 x I226-V, 16 GByte, 256 GByte NVME, ZTE F6005

1100 down / 770 up, Bufferbloat A

Thanks! The Regex is a good idea.

Yes, the unique ID given to the ACL name is an OPNSense implementation but not one that's contained in other HAProxy implementations where unique ACL names aren't required and, in cases like this, are intentional.

You can see the difference in the OPNSense implementation and its unique ID "injection" when you compare the config file from an OPNSense HAProxy setup to another vendor's setup (let's use PFSense as an example).