diff options
author | Thierry Carrez <thierry@openstack.org> | 2013-11-27 15:17:52 +0100 |
---|---|---|
committer | Thierry Carrez <thierry@openstack.org> | 2013-11-27 15:26:52 +0100 |
commit | 7effec053445f52a520002ed9445980bf39d6bcd (patch) | |
tree | d950ba4c6716555b175b0c589f86a18d4dca2d52 /README.rst | |
parent | fe258e097fbd1f6a1a06fb6ac31d4b338c6d6eca (diff) | |
download | oslo-rootwrap-7effec053445f52a520002ed9445980bf39d6bcd.tar.gz |
Add a complete README.rst
Document the use of oslo-rootwrap in README.rst, before cutting
a first release.
This obsoletes https://wiki.openstack.org/wiki/Rootwrap
Change-Id: Ia7046e5a3c4b5ebdbc1a2d978cb6c6a9e4c69514
Diffstat (limited to 'README.rst')
-rw-r--r-- | README.rst | 271 |
1 files changed, 269 insertions, 2 deletions
@@ -1,5 +1,272 @@ +------------- Oslo Rootwrap -============= +------------- -The Oslo Rootwrap allows fine filtering of shell commands to run as root +The Oslo Rootwrap allows fine filtering of shell commands to run as `root` from OpenStack services. + +Unlike other Oslo deliverables, it should **not** be used as a Python library, +but called as a separate process through the `oslo-rootwrap` command: + +`sudo oslo-rootwrap ROOTWRAP_CONFIG COMMAND_LINE` + +How rootwrap works +================== + +OpenStack services generally run under a specific, unprivileged user. However, +sometimes they need to run a command as `root`. Instead of just calling +`sudo make me a sandwich` and have a blanket `sudoers` permission to always +escalate rights from their unprivileged users to `root`, those services can +call `sudo oslo-rootwrap /etc/oslo/rootwrap.conf make me a sandwich`. + +A sudoers entry lets the unprivileged user run `oslo-rootwrap` as `root`. +`oslo-rootwrap` looks for filter definition directories in its configuration +file, and loads command filters from them. Then it checks if the command +requested by the OpenStack service matches one of those filters, in which +case it executes the command (as `root`). If no filter matches, it denies +the request. This allows for complex filtering of allowed commands, as well +as shipping filter definitions together with the OpenStack code that needs +them. + +Security model +============== + +The escalation path is fully controlled by the `root` user. A `sudoers` entry +(owned by `root`) allows the unprivileged user to run (as `root`) a specific +rootwrap executable, and only with a specific configuration file (which should +be owned by `root`) as its first parameter. + +`oslo-rootwrap` imports the Python modules it needs from a cleaned (and +system-default) `PYTHONPATH`. The configuration file points to root-owned +filter definition directories, which contain root-owned filters definition +files. This chain ensures that the unprivileged user itself is never in +control of the configuration or modules used by the `oslo-rootwrap` executable. + +Installation +============ + +All nodes wishing to run `oslo-rootwrap` should contain a `sudoers` entry that +lets the unprivileged user run `oslo-rootwrap` as `root`, pointing to the +root-owned `rootwrap.conf` configuration file and allowing any parameter +after that. For example, Nova nodes should have this line in their `sudoers` +file, to allow the `nova` user to call `sudo oslo-rootwrap`: + +``nova ALL = (root) NOPASSWD: /usr/bin/oslo-rootwrap /etc/oslo/rootwrap.conf *`` + +Then the node also should ship the filter definitions corresponding to its +usage of `oslo-rootwrap`. You should not install any other filters file on +that node, otherwise you would allow extra unneeded commands to be run as +`root`. + +The filter file(s) corresponding to the node must be installed in one of the +filters_path directories (preferably `/usr/share/oslo/rootwrap`). For example, +on Nova compute nodes, you should only have +`/usr/share/oslo/rootwrap/compute.filters` installed. The file should be owned +and writeable only by the `root` user. + +Rootwrap configuration +====================== + +The `rootwrap.conf` file is used to influence how `oslo-rootwrap` works. Since +it's in the trusted security path, it needs to be owned and writeable only by +the `root` user. Its location is specified in the `sudoers` entry, and must be +provided on `oslo-rootwrap` command line as its first argument. + +`rootwrap.conf` uses an *INI* file format with the following sections and +parameters: + +[DEFAULT] section +----------------- + +filters_path + Comma-separated list of directories containing filter definition files. + All directories listed must be owned and only writeable by `root`. + Example: + ``filters_path=/etc/oslo/rootwrap.d,/usr/share/oslo/rootwrap`` + +exec_dirs + Comma-separated list of directories to search executables in, in case + filters do not explicitely specify a full path. If not specified, defaults + to the system `PATH` environment variable. All directories listed must be + owned and only writeable by `root`. Example: + ``exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin`` + +use_syslog + Enable logging to syslog. Default value is False. Example: + ``use_syslog=True`` + +syslog_log_facility + Which syslog facility to use for syslog logging. Valid values include + `auth`, `authpriv`, `syslog`, `user0`, `user1`... + Default value is `syslog`. Example: + ``syslog_log_facility=syslog`` + +syslog_log_level + Which messages to log. `INFO` means log all usage, `ERROR` means only log + unsuccessful attempts. Example: + ``syslog_log_level=ERROR`` + +.filters files +============== + +Filters definition files contain lists of filters that `oslo-rootwrap` will +use to allow or deny a specific command. They are generally suffixed by +`.filters`. Since they are in the trusted security path, they need to be +owned and writeable only by the `root` user. Their location is specified +in the `rootwrap.conf` file. + +It uses an *INI* file format with a `[Filters]` section and several lines, +each with a unique parameter name (different for each filter you define): + +[Filters] section +----------------- + +filter_name (different for each filter) + Comma-separated list containing first the Filter class to use, followed + by that Filter arguments (which vary depending on the Filter class + selected). Example: + ``kpartx: CommandFilter, /sbin/kpartx, root`` + + +Available filter classes +======================== + +CommandFilter +------------- + +Basic filter that only checks the executable called. Parameters are: + +1. Executable allowed +2. User to run the command under + +Example: allow to run kpartx as the root user, with any parameters: + +``kpartx: CommandFilter, kpartx, root`` + +RegExpFilter +------------ + +Generic filter that checks the executable called, then uses a list of regular +expressions to check all subsequent arguments. Parameters are: + +1. Executable allowed +2. User to run the command under +3. (and following) Regular expressions to use to match first (and subsequent) + command arguments + +Example: allow to run `/usr/sbin/tunctl`, but only with three parameters with +the first two being -b and -t: + +``tunctl: /usr/sbin/tunctl, root, tunctl, -b, -t, .*`` + +PathFilter +---------- + +Generic filter that lets you check that paths provided as parameters fall +under a given directory. Parameters are: + +1. Executable allowed +2. User to run the command under +3. (and following) Command arguments. + +There are three types of command arguments: `pass` will accept any parameter +value, a string will only accept the corresponding string as a parameter, +except if the string starts with '/' in which case it will accept any path +that resolves under the corresponding directory. + +Example: allow to chown to the 'nova' user any file under /var/lib/images: + +``chown: PathFilter, /bin/chown, root, nova, /var/lib/images`` + +EnvFilter +--------- + +Filter allowing extra environment variables to be set by the calling code. +Parameters are: + +1. `env` +2. User to run the command under +3. (and following) name of the environment variables that can be set, + suffixed by `=` +4. Executable allowed + +Example: allow to run `CONFIG_FILE=foo NETWORK_ID=bar dnsmasq ...` as root: + +``dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq`` + +ReadFileFilter +-------------- + +Specific filter that lets you read files as `root` using `cat`. +Parameters are: + +1. Path to the file that you want to read as the `root` user. + +Example: allow to run `cat /etc/iscsi/initiatorname.iscsi` as `root`: + +``read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi`` + +KillFilter +---------- + +Kill-specific filter that checks the affected process and the signal sent +before allowing the command. Parameters are: + +1. User to run `kill` under +2. Only affect processes running that executable +3. (and following) Signals you're allowed to send + +Example: allow to send `-9` or `-HUP` signals to `/usr/sbin/dnsmasq` processes: + +``kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP`` + +IpFilter +-------- + +ip-specific filter that allows to run any `ip` command, except for `ip netns` +(in which case it only allows the list, add and delete subcommands). +Parameters are: + +1. `ip` +2. User to run `ip` under + +Example: allow to run any `ip` command except `ip netns exec` and +`ip netns monitor`: + +``ip: IpFilter, ip, root`` + +IpNetnsExecFilter +----------------- + +ip-specific filter that allows to run any otherwise-allowed command under +`ip netns exec`. The command specified to `ip netns exec` must match another +filter for this filter to accept it. Parameters are: + +1. `ip` +2. User to run `ip` under + +Example: allow to run `ip netns exec <namespace> <command>` as long as +`<command>` matches another filter: + +``ip: IpNetnsExecFilter, ip, root`` + + +Calling oslo-rootwrap from OpenStack services +============================================= + +The `oslo.processutils` library ships with a convenience `execute()` function +that can be used to call shell commands as `root`, if you call it with the +following parameters: + +``run_as_root=True`` + +``root_helper='sudo oslo-rootwrap /etc/oslo/rootwrap.conf`` + +NB: Some services ship with a `utils.execute()` convenience function that +automatically sets `root_helper` based on the value of a `rootwrap_config` +parameter, so only `run_as_root=True` needs to be set. + +If you want to call as `root` a previously-unauthorized command, you will also +need to modify the filters (generally shipped in the source tree under +`etc/rootwrap.d` so that the command you want to run as `root` will actually +be allowed by `oslo-rootwrap`. |