LUA - Dynamic backend selection script using client side certificate CN


#1

I need help to use LUA script wih HAProxy 1.6 for dynamically choosing backend based on client side certificate.

Please suggest how could certificate be passed to LUA script and how could certificate CN (ssl_c_s_dn(cn)) be checked in LUA and appropriate backend be returned?

Access HAProxy to connect with one of servers

curl -vk --key client1.key --cert ./client1.crt https://2.0.0.2/whoami.html

HAProxy IP = 2.0.0.2

HAProxy config

global
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

lua-load /usr/sbin/lua-choose-backend.lua

frontend http-in
mode http
bind *:443 ssl crt /etc/haproxy/server.pem ca-file /etc/haproxy/ca.crt verify required
use_backend %[lua.choose_backend]
default_backend app
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
option forwardfor

backend bk1-gr1
balance roundrobin
server app1 1.0.0.1:80 check

backend bk2-gr1
balance roundrobin
server app2 1.0.0.2:80 check

backend bk3-gr2
balance roundrobin
server app3 1.0.0.3:80 check

backend bk4-gr2
balance roundrobin
server app4 1.0.0.4:80 check

backend default
balance roundrobin
server app5 1.0.0.5:80 check

/usr/sbin/lua-choose-backend.lua

clien1 => CN=client1:group-gr1

clien2 => CN=client2:group-gr1

function choose_backend(txn)
– What logic to add to fetch CN from client side certificate and compare below ?

            Fetch metadata from ssl_c_s_dn(cn) i.e. client1:group-gr1
            Fetch the applicable group gr1 for client1
            Fetch the backends for group gr1 i.e. bk1-gr1, bk2-gr1
            backend = More logic to see which is least loaded backend bk1-gr1, bk2-gr1
            backend will be bk1-gr1 or bk2-gr1               

            return backend
    
    return "default"

end

core.register_fetches(“choose_backend”, choose_backend)


#2

Whats the reason for LUA? This should be possible with standard ACL’s.


#3

Pls see the updated config.

I have backends grouped as gr1 and gr2
Client will send group details in CN field. The LUA should fetch group for client from CN and look into backends for this group and choose the backend by some logic (say least loaded) and return to config.

This is the reason I need to use LUA.
Please add how could this be done?


#4

You don’t load balance between backends, you load-balance between servers of the same backend. Still no need for LUA, but I guess you have a specific use case requiring LUA you don’t want to talk about.

Since I don’t know how to do this with LUA, I will let the LUA experts handle this one then.


#5

Could HAProxy team add some pointers for LUA handling for above case?