Closed ctheune closed 8 months ago
When I implemented checking the security of scripts, I was fully aware that the check was only valid for the state of the system when keepalived starts, and that permissions could subsequently be changed. However, for such a change to occur it requires elevated privileges, and therefore the setup could not be modified by an unprivileged user, which was the primary objective. This was necessary because keepalived runs as root, although some people do now run keepalived as a non root user with specific elevated privileges granted, but these privileges need to be fairly extensive (an alternative approach is to use SELinux to restrict what keepalived can do, and in particular limit from what directories keepalived can execute scripts).
I think it would be wrong to alter now the default way keepalived handles scripts, but I think we could add a new global keyword use_symlink_path
or something like that, so that keepalived uses the originally configured path (including symlinks) for scripts (this would apply for both VRRP notify scripts and IPVS check_misc scripts). keepalived would still do the same security checks as it currently does, but would execute the scripts via the original specified path (i.e. including any symlinks) rather than resolved path.
Would this suit your requirements?
Yeah, I agree with the overall analysis and with the suggestion.
To clarify: this would result in the checks being performed the moment before calling the script as well, right?
It wasn't my intention to perform the checks immediately before calling the script. My view is that keepalived will have checked all parts of the path (both the real patch and the path via symlinks) are non-root writeable at startup; it therefore requires someone with root privileges to modify the script, and we must assume that they know what they are doing (after all a root user can simply modify the script).
Sure. I guess this is an aspect of why I consider the original check somewhat moot, but - just to make sure - I'm not arguing about that aspect and just wanted to understand what you're suggesting.
So: yeah, I'd appreciate using the original path when calling as you suggested. Much appreciated!
Commit ebf37b9 should resolve this issue. The new keyword is use_symlink_paths
, which is slightly different from what I suggested earlier.
Thanks! I'll pass this over to my colleague for testing!
Describe the bug
NixOS uses a lot of symlinks to scripts and binaries that will have their underlying targets change relatively often. This can result in an active configuration referring to a path like
/run/current-system/sw/bin/myscript
being resolved on startup/reload then refer to something like/nix/store/<cryptographichash>-myscript/bin/myscript
where the latter might be changing every now and then and get cleaned up from garbage collection a while later.From a theoretical standpoint one could (and maybe should) perfectly manage those dependencies and ensure that resolved store paths are inserted into the config file and then this automatically becomes a trigger to execute a config reload.
Unfortunately,
doing something perfect
in this case doesn't prohibit one to (human brains have limits) accidentally insert an implicit dependency that works and then suddenly fails a few months later without a chance of noticing that it broke.So, from a sysadmin perspective, keepalived robs me of the ability to use symlinks even when I'm ensuring that they aren't writable by non-root users. Disabling the script_security flag doesn't help either.
The security aspect of what keepalived is doing here is interesting because if we perform the script security checks but do not statically resolve symlinks, then the question whether something in the path is writable by non-root can change over time. However, that sounds like a sysadmin failure on a different level where countering this within keepalived kills orthogonality/composability of basic Unix features.
To Reproduce Any steps necessary to reproduce the behaviour:
Expected behavior A clear and concise description of what you expected to happen.
Keepalived version
Distro (please complete the following information):
Details of any containerisation or hosted service (e.g. AWS) If keepalived is being run in a container or on a hosted service, provide full details
Configuration file:
Notify and track scripts
The actual scripts aren't relevant AFAICT and the referenced
fc-manage
script is a somewhat larger piece of software ... ;)System Log entries
Did keepalived coredump?
nope