I’m currently in the beginning stages of bringing OOD to our campus-wide multi-cluster HPC service at the University of Washington. Cheers on a great product and an active community.
The OOD deployment will live in pods on our local kubernetes cluster. I’ve borrowed/extended an flask/nginx reverse proxy for other user-facing services which acts as a saml IDP, and can inject the username of an authenticated user as a header down to the service which it forwards traffic to.
Several of our services, most notably grafana and jenkins are able to consume this arbitrarily named header and create/auth users by trusting it.
My question is as follows: would an existing mod_auth_* module allow for the same behavior, which could be used in the ood_portal.yaml config generator? And if not, how difficult would it be to implement that sort of behavior?
If the header “X-WEBAUTH-USER” is already being set to the username by your proxy then it should just be a matter of properly configuring Apache in OnDemand. I don’t think you need any existing mod_auth_*. My guess the ood_portal.yaml would get this option set:
I’m wondering which of these I should be getting rid of to allow the pun dashboard app to pick up on the X_WEBAUTH_USER, I can see from my trace logs that http_request.c is seeing header passed into the portal, I’m a little lost where to go from here.
This didn’t work so well and caused an internal server error as far as what was readable through the returned HTML, I’m going to try and dive through the nginx,passenger,and apache portal logs to see where its unwinding itself, but if you know of a way to just do blind-trusted auth from the header, to the PUN apps, it would be massively appreciated.
Did you try removing all the auth directives? That might work.
But then that introduces the problem of requests made to Apache from the host running Apache itself. We typically treat the OnDemand host like a login node and assume users are provided shell access to that node, so extra security measures are taken as a result.
So it would seem like you would want some type of trust setup between Apache and the authenticating proxy so that Apache doesn’t accept requests from any other source. I’m not an expert in this part of Apache. @tdockendorf might have some ideas.
This is an example of where it would be beneficial if Apache were option in OnDemand, and the main server component that handled starting the PUNs could listen on a Unix socket.
@efranz@tdockendorf since Our auth proxy (That’s also handling 2fa) and the ood container are all running inside the same kubernetes namespace with NetworkSecurityPolicies enabled, and no end-user shell access we’re comfortable implicitly/blindly trusting the auth header.
Update from removing the auth header references:
I removed the following from the /nginx and /pun locations on the virtualhost:
I’m getting a code 500 server internal error. I have a strong feeling that the lua handler is translating the output from the mod_auth_* (whichever one is used, like htpasswd, ldap, shib, etc…) and passing it as a variable down to the PUN (passenger?) process. I’m going to have a look at the lua code at:
/opt/ood/mod_ood_proxy/lib/pun_proxy.lua, func: pun_proxy_handler and see if I can substitute the header string contents into the variable that the downstream PUN is consuming… If you guys can think of anything else it would be appreciated.
function map(r, user_map_cmd, remote_user)
-- run user_map_cmd and read in stdout
local now = r:clock()
-- local handle = io.popen(user_map_cmd .. " '" .. r:escape(remote_user) .. "'")
sys_user = r.subprocess_env["PROX_MAPPED_USER"]
time_user_map = (r:clock() - now)/1000.0
-- r:debug("Mapped '" .. remote_user .. "' => '" .. (sys_user or "") .. "' [" .. time_user_map .. " ms]")
-- failed to map if returns empty string
if not sys_user or sys_user == "" then
r.subprocess_env['MAPPED_USER'] = sys_user -- set as CGI variable for later hooks (i.e., analytics)
r.subprocess_env['OOD_TIME_USER_MAP'] = time_user_map -- set as CGI variable for later hooks (i.e., analytics)
map = map
and on my ood-portal.conf I had to add the following SetEnvIf: