select an haproxy tcp back end depending on source ip

I have basic haproxy knowledge and know how to handle the selection of tcp backends depending on the SNI server name.

The relevant lines are

    acl is_myhost req.ssl_sni -i my.host.com
    acl is_otherhost req.ssl_sni -i other.host.com


    use_backend mybackend if is_myhost
    use_backend otherbackend if is_otherhost

Now I'd like to change them to something that allows me to chose the back end also depending on the source ip but I don't know the exact syntax for below pseudo configuration or whether this is possible at all

    acl is_myhost_for_specif req.ssl_sni -i my.host.com <and source ip = 1.2.3.4>
    acl is_myhost_for_others req.ssl_sni -i my.host.com <and source ip != 1.2.3.4>
    acl is_otherhost req.ssl_sni -i other.host.com


    use_backend mybackend1 if is_myhost_for_specific
    use_backend mybackend2 if is_myhost_for_others
    use_backend otherbackend if is_otherhost


Solution 1:

Your pseudo-code for ACLs is incorrect, because ACL declaration has no syntax for AND/OR logic. Move that to a place, where you use ACL, like in example below.
For source IP there is src (https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#7.3.3-src), e.g.:

Please note that the syntax for matching two conditions in an if statement is not

use_backend mybackend if condition1 and condition2

but just

use_backend mybackend if condition1 condition2

acl test_network src 192.168.10.0/24
acl test_network src 192.168.20.0/24
acl is_myhost_for_specif req.ssl_sni -i my.host.com

# both acls must be true (is_myhost **and** test_network)
use_backend mybackend1 if is_myhost test_network
use_backend mybackend2 if is_myhost

Order of use_backend is important, so IPs from test_network go to mybackend1 and others go to mybackend2 if SNI matches. Declaring test_network ACL twice here means "src_ip matches 192.168.10.0/24 OR 192.168.20.0/24"