Add more usage documentation
The documentation was a bit too dry. Take some information from mikal's blogposts and expose them in the user doc section. Change-Id: I93a91c12e78c5d56913b0953c5a9cfa16e45a265
This commit is contained in:
parent
d84c76108b
commit
6c3a6e27a6
@ -2,7 +2,16 @@
|
||||
oslo.privsep
|
||||
==============
|
||||
|
||||
OpenStack library for privilege separation
|
||||
oslo.privsep is an OpenStack library for privilege separation.
|
||||
|
||||
It helps applications perform actions which require more or less
|
||||
privileges than they were started with in a safe, easy to code
|
||||
and easy to use manner. For more information on why this is generally
|
||||
a good idea please read over the `principle of least privilege`_ and
|
||||
the `specification`_ which created this library.
|
||||
|
||||
.. _principle of least privilege: https://en.wikipedia.org/wiki/Principle_of_least_privilege
|
||||
.. _specification: https://specs.openstack.org/openstack/oslo-specs/specs/liberty/privsep.html
|
||||
|
||||
Contents
|
||||
========
|
||||
|
@ -2,14 +2,109 @@
|
||||
Usage
|
||||
=======
|
||||
|
||||
To use oslo.privsep in a project::
|
||||
oslo.privsep lets you define in your code specific functions that will run
|
||||
in predefined privilege contexts. This lets you run functions with more (or
|
||||
less) privileges than the rest of the code. Privsep functions live in a
|
||||
specific ``privsep`` submodule (for example, ``nova.privsep`` for nova).
|
||||
|
||||
import oslo_privsep
|
||||
Defining a context
|
||||
==================
|
||||
|
||||
You can read the following blog posts in order to know a bit more:
|
||||
Contexts are defined in the ``privsep/__init__.py`` file. For example, this
|
||||
defines a sys_admin_pctxt with ``CAP_CHOWN``, ``CAP_DAC_OVERRIDE``,
|
||||
``CAP_DAC_READ_SEARCH``, ``CAP_FOWNER``, ``CAP_NET_ADMIN``, and
|
||||
``CAP_SYS_ADMIN`` rights (equivalent to ``sudo`` rights)::
|
||||
|
||||
from oslo_privsep import capabilities
|
||||
from oslo_privsep import priv_context
|
||||
|
||||
sys_admin_pctxt = priv_context.PrivContext(
|
||||
'nova',
|
||||
cfg_section='nova_sys_admin',
|
||||
pypath=__name__ + '.sys_admin_pctxt',
|
||||
capabilities=[capabilities.CAP_CHOWN,
|
||||
capabilities.CAP_DAC_OVERRIDE,
|
||||
capabilities.CAP_DAC_READ_SEARCH,
|
||||
capabilities.CAP_FOWNER,
|
||||
capabilities.CAP_NET_ADMIN,
|
||||
capabilities.CAP_SYS_ADMIN],
|
||||
)
|
||||
|
||||
Defining a privileged function
|
||||
==============================
|
||||
|
||||
Functions are defined in files under the ``privsep/`` subdirectory, for
|
||||
example in a ``privsep/motd.py`` file for functions touching the MOTD file.
|
||||
They make use of a decorator pointing to the context we defined above::
|
||||
|
||||
import nova.privsep
|
||||
|
||||
@nova.privsep.sys_admin_pctxt.entrypoint
|
||||
def update_motd(message):
|
||||
with open('/etc/motd', 'w') as f:
|
||||
f.write(message)
|
||||
|
||||
Privileged functions must be as simple, specialized and narrow as possible,
|
||||
so as to prevent further escalation. In this example, ``update_motd(message)``
|
||||
is narrow: it only allows the service to overwrite the MOTD file. If a more
|
||||
generic ``update_file(filename, content)`` was created, it could be used to
|
||||
overwrite any file in the filesystem, allowing easy escalation to root
|
||||
rights. That would defeat the whole purpose of oslo.privsep.
|
||||
|
||||
|
||||
Using a privileged function
|
||||
===========================
|
||||
|
||||
To use the privileged function in the regular code, you can just call it::
|
||||
|
||||
import nova.privsep.motd
|
||||
...
|
||||
|
||||
nova.privsep.motd.update_motd('This node is currently idle')
|
||||
|
||||
It is better to import the complete path (``import nova.privsep.motd``) rather
|
||||
than the motd name (``from nova.privsep import motd``) so that it is easier to
|
||||
spot that the function runs in a different privileged context.
|
||||
|
||||
For more details, you can read the following blog post:
|
||||
|
||||
* `How to make a privileged call with oslo privsep`_
|
||||
* `Adding oslo privsep to a new project, a worked example`_
|
||||
|
||||
.. _How to make a privileged call with oslo privsep: https://www.madebymikal.com/how-to-make-a-privileged-call-with-oslo-privsep/
|
||||
|
||||
|
||||
Converting from rootwrap to privsep
|
||||
===================================
|
||||
|
||||
oslo.rootwrap is a precursor of oslo.privsep to allow code to run commands
|
||||
under sudo if they match a predefined filter. For example, you could define
|
||||
a filter that would allow you to run chmod as root using the following
|
||||
filter::
|
||||
|
||||
chmod: CommandFilter, chmod, root
|
||||
|
||||
Beyond the bad performance of calling full commands in order to accomplish
|
||||
simple tasks, rootwrap also led to bad security: it was difficult to filter
|
||||
commands in a way that would not easily allow privilege escalation.
|
||||
|
||||
Replacing rootwrap filters with privsep functions is easy. The chmod filter
|
||||
above can be replaced with a function that calls ``os.chmod()``. However a
|
||||
straight 1:1 filter:function replacement generally results in functions that
|
||||
are still too broad for good security. It is better to replace each chmod
|
||||
rootwrap *call* with a narrow privsep function that will limit it to specific
|
||||
files.
|
||||
|
||||
Sometimes it is necessary to refactor the calling code: the rootwrap design
|
||||
discouraged the creation of new filters and therefore often resulted in the
|
||||
creation of overly-broad calling functions.
|
||||
|
||||
As an example, this `patch series`_ is work-in-progress to transition Nova
|
||||
from rootwrap to privsep.
|
||||
|
||||
For more details, you can read the following blog post:
|
||||
|
||||
* `Adding oslo privsep to a new project, a worked example`_
|
||||
|
||||
.. _patch series: https://review.openstack.org/#/q/project:openstack/nova+branch:master+topic:my-own-personal-alternative-universe
|
||||
|
||||
.. _Adding oslo privsep to a new project, a worked example: https://www.madebymikal.com/adding-oslo-privsep-to-a-new-project-a-worked-example/
|
||||
|
Loading…
Reference in New Issue
Block a user