Search code examples
haproxy

haproxy auth'ed user based backend routing


I am new to haproxy but already like it very much. Right away I have a special use case for which I couldn't find a good way yet.

QUESTION: Is is possible to route to a backend-server based on the currently authenticated user?

Something like...

userlist EXAMPLEORG
 user bob password bob123
 user alice password alice987

frontend https
 bind *:443
 mode tcp
 ...
 use_backend a-servers if { CURRENT_USER bob }
 use_backend b-servers if { CURRENT_USER alice }

But what would be the right FETCH syntax for (pseudocode) CURRENT_USER?

Background (=these are the constraints I have to work with): - There are several upstream http proxies (squid) - There are several users (~50) - Each user is assigned to a proxy (ie "Joe Doe" has to use "upstream-squid-5") - But the assignment can change at any time and - the local proxy config (Windows via Group Policy, IOS via profile) cannot be changed (quick enough)

(These points above are out of my hands and we don't need to discuss them ;) )

First attempt was via Proxy Auto Config file (PAC) that could be changed on server and would automatically polled by clients. (so only the pac file would have to be deployed once per user) BUT: It took too long on some devices to update, so this was discarded as unreliable

My research led me to HAPROXY. My idea is to use built-in map functionality to route to the right backend. But I cannot find a suitable fetch source to distinguish request origins. I know that userlist/auth can be set up.

As I said, I'm new to this and couldn't find anything for user based routing.

Any help or pointing in right direction would be highly appreciated.

Also, if you know a much better solution to the problem, I would be very grateful.

Thanks!


Solution

  • I think it easier to put the users in same backend into a group, then write a ACL for them.

    I've created 3 example user groups, named optional then assign users to the group you want. Easy, right? In frontend, we have to check all user first if they're valid (auth'ed) user. Then we create each ACL for each user group then route them to correct backend.

    It's not tested but I'm sure it will works and will cleaner with HAProxy's map function.

    userlist user
      group ube_1
      group ube_2
      group ube_3
    
      user bob password ... groups ube_1
      user alice password ... groups ube_2
    
    frontend
      ...
      acl is_authed_user http_auth_group(user)
      http-request auth realm httpauth unless is_authed_user
    
      acl is_be_1 http_auth_group(user) ube_1
      acl is_be_2 http_auth_group(user) ube_2
    
      use-backend be_1 if is_be_1
      use-backend be_2 if is_be_2