Arnaud Morin wrote:
[...] I'd like to understand the difference with privsep daemon.
Is privsep a new daemon which is supposed to replace the rootwrap one? Is privsep being launch after rootwrap? IS privsep enabled by default, so I should not care about rootwrap at all?
I can help with that, since I originally created rootwrap.
Rootwrap is a privilege escalation control mechanism. It serves as a way to filter what the service user on the machine can execute as root via sudo. The idea is that sudoers files do not provide enough granularity, so instead of trying to describe what is allowed and what is not in sudoers file, we basically allow calling "sudo rootwrap command" and let rootwrap figure it out. Rootwrap reads a number of (root-owned) configuration files and decides to allow calling the command or not.
There are two issues with this mechanism. The first is that the performance is not great, as first you run a python executable (rootwrap), which in turn spawns another process if the command is allowed. If you do that for hundreds of "ip" calls as you set up networking in neutron, this can add up pretty fast.
The second issue is that rootwrap is only as secure as its configuration. If for example you configure rootwrap to allow the 'nova' user to run the "chmod" command, well that's basically the same as allowing it run anything as root. You have to use advanced filters to further refine what it can actually do based on command parameter analysis, and there is only so much you can control that way.
Rootwrap-daemon is a way to partially help with the first issue. Rather than calling a new rootwrap Python process every time a command needs to be called, you maintain a long-running rootwrap process that will process all requests. It significantly improves performance, but it adds inter-process communication complexity (never great in a security system). And it does nothing to address the second issue.
Privsep is the "right" way of addressing both issues. Rather than having the code try to call shell commands as root, privsep allows the code to call Python functions as root. This solves the performance issue, as you don't have the overhead of a separate Python process + shell process every time you want to change the ownership of a file, you can just call a Python function that will call os.chown() and get ear to syscall efficiency. It also solves the granularity issue, by allowing to call a function that will only do what you want to do, rather than have to find a way to filter parameters so that the command you call cannot be abused to do other things.
The main issue with privsep is that it requires changing the code. You have to set it up in every project (it's now done for most), but then every place the service calls utils.execute(command, run_as_root=True) needs to be changed to call a privileged Python function instead.
The second issue with privsep is that it still needs root to start. The way this is usually done is by using rootwrap itself to bootstrap privsep... which can be confusing. There are obviously other ways to start the process as root, but since most of those services still make use of rootwrap anyway, that is what continues to be used for the initial bootstrapping.
Ideally services would be completely transitioned to privsep, and we would discontinue rootwrap.
Hoping this helps,