<div dir="ltr">4) Write a small daemon that runs as root, accepting commands over a unix domain socket or similar. Easier to audit, less code running as root.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 4 February 2015 at 12:58, Thierry Carrez <span dir="ltr"><<a href="mailto:thierry@openstack.org" target="_blank">thierry@openstack.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
This is the follow-up of the discussion we started yesterday on rootwrap<br>
usage at the cross-project meeting.<br>
<br>
A bit of history to stage this story first. OpenStack nodes sometimes<br>
need to run things with elevated privileges. Nova started out as calling<br>
sudo shell commands to execute those, which basically allowed it to run<br>
anything as root. Distributions didn't really like that, so packagers<br>
started to ship sudoers files that restricted the commands Nova could<br>
run with sudo. It created a maintenance nightmare, where the code and<br>
the packaging were routinely out of sync. Rootwrap was designed so that<br>
we would maintain the allowed commands in the code itself, which<br>
facilitated maintenance. It would also allow more complex rules than<br>
sudoers allowed, like the ability to only kill a certain executable<br>
processes.<br>
<br>
Rootwrap was then adopted by Cinder and Neutron, and moved to oslo to<br>
avoid code duplication. There were still two long-standing problems with<br>
it, though.<br>
<br>
The first one is performance -- each call would spawn a Python<br>
interpreter which would then call the system command. This was fine when<br>
there were just a few calls here and there, not so much when it's called<br>
a hundred times in a row. During the Juno cycle, a daemon mode was added<br>
to solve this issue. It is significantly faster than running sudo<br>
directly (the often-suggested alternative). Projects still have to start<br>
adopting it though. Neutron and Cinder have started work to do that in Kilo.<br>
<br>
The second problem is the quality of the filter definitions. Rootwrap is<br>
a framework to enable isolation. It's only as good as the filters each<br>
project defines. Most of them rely on CommandFilters that do not check<br>
any argument, instead of using more powerful filters (which are arguably<br>
more painful to maintain). Developers routinely add filter definitions<br>
that basically remove any isolation that might have been there, like<br>
allowing blank dd, tee, chown or chmod.<br>
<br>
Basically, some nodes run such a variety of commands as root that<br>
maintaining proper isolation is a non-trivial amount of work: that's the<br>
case for Nova's compute nodes and Cinder's volume nodes. I would argue<br>
that for all other types of nodes, rootwrap is still an appropriate way<br>
to provide isolation. But for nodes which need to make a very wide<br>
variety of root calls, we pretend to isolate, but the filter definitions<br>
are so full of holes that we actually don't.<br>
<br>
What solutions do we have ?<br>
<br>
(1) we could get our act together and audit and fix those filter<br>
definitions. Remove superfluous usage of root rights, make use of<br>
advanced filters for where we actually need them. We have been preaching<br>
for that at many many design summits. This is a lot of work though...<br>
There were such efforts in the past, but they were never completed for<br>
some types of nodes. Worse, the bad filter definitions kept coming back,<br>
since developers take shortcuts, reviewers may not have sufficient<br>
security awareness to detect crappy filter definitions, and I don't<br>
think we can design a gate test that would have such awareness.<br>
<br>
(2) bite the bullet and accept that some types of nodes actually need<br>
root rights for so many different things, they should just run as root<br>
anyway. I know a few distributions which won't be very pleased by such a<br>
prospect, but that would be a more honest approach (rather than claiming<br>
we provide efficient isolation when we really don't). An added benefit<br>
is that we could replace a number of shell calls by Python code, which<br>
would simplify the code and increase performance.<br>
<br>
(3) intermediary solution where we would run as the nova user but run<br>
sudo COMMAND directly (instead of sudo nova-rootwrap CONFIG COMMAND).<br>
That would leave it up to distros to choose between a blanket sudoer or<br>
maintain their own filtering rules. I think it's a bit hypocritical<br>
though (pretend the distros could filter if they wanted it, when we<br>
dropped the towel on doing that ourselves). I'm also not convinced it's<br>
more secure than solution 2, and it prevents from reducing the number of<br>
shell-outs, which I think is a worthy idea.<br>
<br>
In all cases I would not drop the baby with the bath water, and keep<br>
rootwrap for all the cases where root rights are needed on a very<br>
specific set of commands (like neutron, or nova's api-metadata). The<br>
daemon mode should address the performance issue for the projects making<br>
a lot of calls.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Thierry Carrez (ttx)<br>
<br>
__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">Duncan Thomas</div>
</div>