-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add pun_pre_hook #535
add pun_pre_hook #535
Conversation
What does the Apache config change look like in this case? It would seem that we would want to include the appropriate ood-portal-generator modifications to support that change as well. Is there is a way to pass all claim headers to stdin instead of cherry-picking OIDC access token? Is there a way to do this without being OIDC specific? |
Same. We hold our oidc configs separately from what we distribute anyway. Mod auth openidc defaults to passing these items as both header and environment variables, so we'd need to document that you need at least the environment variable for this to work.
Maybe? We could loop through
Sure, but our use case (along with SDSC's) is to use the access token. I guess we could blindly export the entire |
Once we support Dex the OIDC settings will be exposed via ood-portal-generator. That was part of #474 . Part of that PR was to make it possible to define OIDC settings as part of |
Yeah, especially if you don't modify the nginx_stage process's environment (see inline comment above). I think that is the best solution. Other Apache modules set env vars that would end up in this table and this should provide us access to all the OIDC claim headers. So it would be a win-win - our hook scripts get access all the claim headers and it is no longer OIDC specific. One question though: who is this hook script running as? root or the user? We may want to have two hooks: a root hook script and a per user hook script, unless both ours and SDSC can be handled by a per user hook script. |
This runs as root. In my k8s script I |
It's not immediately clear how to copy the environment. I've got to find docs on how to iterate through an |
After some digging I'm fairly certain we can't export the So unless these things are reachable from some other mechanism, I'm not sure if there is a way to do this generically yet. |
Darn. Maybe then we make configurable somehow (comma delimited list) the list of vars in r.subprocess_env to export? Then we can specify all the oidc claim headers we want to pass |
Updated with a configuration. Unfortunately it's in the ood portal generator so there's one config in nginx_stage for the command to run and one config in the ood_portal.yml for what variables to export to the it. I'm not really sure there's a way around it because that's where the environment comes from. If this strategy seems OK I can work on some test cases for both the ood portal and the nginx stage. |
We configure exports in Apache, and lua sets stdin with this when calling nginx_stage Instead of utilizing nginx_stage configuration to tell what prehook to run, what if we just added support for more arguments to nginx stage - for example --pre-hook=/path/to/pre/hook.sh? Then we could handle configuration for the exports and the prehook in ood-portal-generator config. |
That seems fine to me. Do we want to change the name to (also I see the apache tests failing now, so I'll get on that). |
Hold off on the per-user one till this is merged - we can revisit. Maybe the root/user is appended to the end of the name? Instead of |
Give a command and some standard in, get a string for merged stdout and stderr | ||
--]] | ||
function capture2e_with_stdin(cmd, stdin) | ||
local output_file = os.tmpname() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are back to using temporary filenames, and every single PUN launch will now use this, should we do io.tmpfile() instead? Also, this file we should ensure the permissions to be 600 before writing sensitive data to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I was testing this, I saw it was creating 600 files, though that could be platform/configuration dependent. You think a os.execute(chmod ... )
is enough?
Looks like I was using os.tmpname
because it's actually a string, so we don't have to cast it.
> t = os.tmpname()
> os.execute('chmod 600 ' .. t .. ' >/dev/null 2>&1')
true exit 0
> f = io.tmpfile()
> os.execute('chmod 600 ' .. f .. ' >/dev/null 2>&1')
stdin:1: attempt to concatenate a FILE* value (global 'f')
stack traceback:
stdin:1: in main chunk
[C]: in ?
Then I'm not sure how to cast it to a string.
> tostring(f)
file (0x56056fb7ea90)
> tostring(t)
/tmp/lua_8GVcnl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can rely on io.tmpfile()
to create 600 files. It is either that or introduce a tiny race condition with the use of os.tmpname
.
if app_init_url then | ||
cmd = cmd .. " -a '" .. r:escape(app_init_url) .. "'" | ||
end | ||
|
||
local err = capture2e(cmd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we take advantage of this STDIN any other way besides a prehook? Are we comfortable with changing every Execution of nginx_stage by Apache by providing STDIN like we are doing below.
If it could only ever be used for the pre_hook maybe we should consider maintaining the default local err = capture2e(cmd)
and only passing stdin when a pre_hook_root_cmd is provided reduce the scope of this change. I have mixed feelings on this, though.
|
||
os.remove(output_file) | ||
|
||
return output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will need to document that the pre hook when executed by Apache should not output any data to stdout or stderr since we report both as an error.
In #496 we discussed being able to add luaposix. Would that be useful here at all? |
It would help us pass the environment variables directly into the pre hook instead of parsing them from std in. So yes it would be helpful, but I'm not sure if the package management is worth it. We'd have to build and distribute a version for centos/RHEL 7 to say nothing about other platforms. |
PowerTools for CentOS 8 is very common to have to enable and so is EPEL for EL7. I see no problem with depending on those repos. For CentOS they are very simple to get enabled, for RHEL it's a bit more involved but still common to have enabled. |
5af0688
to
a8ef0d3
Compare
Rebased off of current main and added syslog to nginx_stage. We should be good with this now, although it's been so long it's worth looking over it again. |
@johrstrom Were you going to try and use lua posix to handle environment variables? |
I could try, and I'm sure it would work, but I'm hesitant to add the dependency. Of course if folks feel strongly about it, I can change this PR, but my vote would be to defer it at least until we know we want it also for some other use case (like the regex exploration in #710). The user/admin interface would look the same even if the internals change. |
pun_pre_hook runs the configured executable before the PUN starts. This addition also enables logic to pass the OIDC_ACCESS_TOKEN if it exists into the nginx_stage script's standard in (in the form key=value).
to the nginx stage pre hook.
move pun_pre_hook configuration from the nginx_stage to the ood-portal-generator to minimize edit locations for this feature. now we pass in the script to the 'nginx_stage pun' command with the -P option.
most installations will continue to use the same code path as before.
b74eaac
to
328568e
Compare
I'd like to see how the code would change/possibly simplify if we used the lua posix module. If it is less code for us to maintain then I'd say go for it. |
Partial fix for #496.
Adds a pun pre_hook.
--user $USER
is given as a command line argument to the hook andOIDC_ACCESS_TOKEN
is set as an environment variable if it exists in the parent process (the lua scripts inood_mod_proxy
).I can provide a script that exchanges OIDC tokens and sets the kuberenetes config in this PR too. We'll eventually need to put it somewhere to share, I'm just not sure where. The k8s exchange script relies on environment specific things like which IDP to look at for example (OSC's dev/test/prod) and it's unclear where these should be source from (
/etc/ood/profile
?)