<div dir="ltr"><div class="gmail_quote">On Sat Feb 14 2015 at 1:14:09 AM Thierry Carrez <<a href="mailto:thierry@openstack.org">thierry@openstack.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Angus Lees wrote:<br>
> So inspired by the "Rootwrap on root-intensive nodes" thread, I went and<br>
> wrote a proof-of-concept privsep daemon for<br>
> neutron: <a href="https://review.openstack.org/#/c/155631" target="_blank">https://review.openstack.org/#<u></u>/c/155631</a><br>
<br>
Nice work! Trying to check where the security model is actually weaker<br>
than the one provided by rootwrap here...<br>
<br>
If I read this correctly, one of the drawbacks compared to the rootwrap<br>
approach is that all the functions are accessible on any node running<br>
the privsep daemon.<br>
<br>
When properly packaged, the rootwrap system only has the relevant filter<br>
definition files present, which dramatically reduces what you allow to<br>
run as root there. For example, nova-metadata nodes can only run<br>
iptables to add a firewall rule, since that's the only filter definition<br>
file shipped on those nodes. That's a benefit of shipping allowed<br>
commands in the configuration, rather than in the code. With the<br>
proposed system, the nova-metadata node running with nova-privsep would<br>
have access to any function defined there, including the rather<br>
permissive file manipulations that nova-compute needs.<br>
<br>
Maybe one way to solve that would be to have several different privsep<br>
daemons in nova to run on the various types of nodes, each with their<br>
own set of allowed functions...<br>
<br>
Additionally, rootwrap was extremely lean in terms of dependencies --<br>
basically only allowing Python stdlib module imports to reduce the<br>
envelope of code you need to trust to run things as root. Here you are<br>
reusing the Neutron agent framework, which has a pretty long list of<br>
module imports, which are all imported before the rights are dropped.<br>
That means you end up blindly trusting a widely larger envelope of modules.<br>
<br>
My suggestion would be to not run it as an agent but as a standalone<br>
daemon with an aggressively-limited set of module imports (ideally only<br>
stdlib).<br></blockquote><div><br></div><div>Yeah, good point - I was assuming we needed to protect against exploits that might occur after we started processing network events rather than something that might have already modified root-write-only python library files before we even started...</div><div><br></div><div>At the high level, I feel that interfacing via the relevant syscalls directly is going to be more reliable and more easily understood (and of course less overhead) than via command line tools.  This direction necessarily involves pulling in more libraries to help with that, however.</div><div><br></div><div>(Thinking as I type) Hrm, I was going to suggest re-execing the interpreter at privsep startup, but that can still assumes the python environment is safe at that point (in which case you've already forked and you may as well continue in this safe environment - without the exec).  I think an improvement here requires starting the agent and all its imports as non-root, and then gaining privileges at the same time as using a fresh interpreter by starting the privsep daemon via sudo.  That way you only have to audit for malicious monkey-patching in the code of anything privsep imports after that point.</div><div>This also helps with the migration story (see previous post) and I'll add it to my todo list.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That's all I could spot with a cursory look :)<br></blockquote><div><br></div><div>(Thanks for looking!)</div><div><br></div><div> - Gus </div></div></div>