mirror of
https://github.com/systemd/systemd.git
synced 2025-02-28 05:57:33 +03:00
Add SELinux support to systemd-nspawn
This patch adds to new options: -Z PROCESS_LABEL This specifies the process label to run on processes run within the container. -L FILE_LABEL The file label to assign to memory file systems created within the container. For example if you wanted to wrap an container with SELinux sandbox labels, you could execute a command line the following chcon system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -R /srv/container systemd-nspawn -L system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -Z system_u:system_r:svirt_lxc_net_t:s0:c0,c1 -D /srv/container /bin/sh
This commit is contained in:
parent
483798e077
commit
a8828ed938
@ -248,6 +248,27 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-L</option></term>
|
||||||
|
<term><option>--file-label=</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Sets the mandatory
|
||||||
|
access control (MAC) file label to be
|
||||||
|
used by tmpfs file systems in the
|
||||||
|
container.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-Z</option></term>
|
||||||
|
<term><option>--process-label=</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Sets the mandatory
|
||||||
|
access control (MAC) label to be used by
|
||||||
|
processes in the container.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--uuid=</option></term>
|
<term><option>--uuid=</option></term>
|
||||||
|
|
||||||
@ -456,6 +477,14 @@
|
|||||||
btrfs snapshot.</para>
|
btrfs snapshot.</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Example 6</title>
|
||||||
|
|
||||||
|
<programlisting># chcon system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -R /srv/container
|
||||||
|
# systemd-nspawn -L system_u:object_r:svirt_sandbox_file_t:s0:c0,c1 -Z system_u:system_r:svirt_lxc_net_t:s0:c0,c1 -D /srv/container /bin/sh</programlisting>
|
||||||
|
|
||||||
|
<para>This runs a container with SELinux sandbox labels.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Exit status</title>
|
<title>Exit status</title>
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
#if HAVE_SELINUX
|
||||||
|
#include <selinux/selinux.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sd-daemon.h"
|
#include "sd-daemon.h"
|
||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
@ -77,6 +80,8 @@ static char *arg_directory = NULL;
|
|||||||
static char *arg_user = NULL;
|
static char *arg_user = NULL;
|
||||||
static sd_id128_t arg_uuid = {};
|
static sd_id128_t arg_uuid = {};
|
||||||
static char *arg_machine = NULL;
|
static char *arg_machine = NULL;
|
||||||
|
static char *process_label = NULL;
|
||||||
|
static char *file_label = NULL;
|
||||||
static const char *arg_slice = NULL;
|
static const char *arg_slice = NULL;
|
||||||
static bool arg_private_network = false;
|
static bool arg_private_network = false;
|
||||||
static bool arg_read_only = false;
|
static bool arg_read_only = false;
|
||||||
@ -125,6 +130,8 @@ static int help(void) {
|
|||||||
" --uuid=UUID Set a specific machine UUID for the container\n"
|
" --uuid=UUID Set a specific machine UUID for the container\n"
|
||||||
" -M --machine=NAME Set the machine name for the container\n"
|
" -M --machine=NAME Set the machine name for the container\n"
|
||||||
" -S --slice=SLICE Place the container in the specified slice\n"
|
" -S --slice=SLICE Place the container in the specified slice\n"
|
||||||
|
" -L --file-label=LABEL Set the MAC file label to be used by tmpfs file systems in container\n"
|
||||||
|
" -Z --process-label=LABEL Set the MAC label to be used by processes in container\n"
|
||||||
" --private-network Disable network in container\n"
|
" --private-network Disable network in container\n"
|
||||||
" --read-only Mount the root directory read-only\n"
|
" --read-only Mount the root directory read-only\n"
|
||||||
" --capability=CAP In addition to the default, retain specified\n"
|
" --capability=CAP In addition to the default, retain specified\n"
|
||||||
@ -173,6 +180,8 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "machine", required_argument, NULL, 'M' },
|
{ "machine", required_argument, NULL, 'M' },
|
||||||
{ "slice", required_argument, NULL, 'S' },
|
{ "slice", required_argument, NULL, 'S' },
|
||||||
{ "setenv", required_argument, NULL, ARG_SETENV },
|
{ "setenv", required_argument, NULL, ARG_SETENV },
|
||||||
|
{ "process-label", required_argument, NULL, 'Z' },
|
||||||
|
{ "file-label", required_argument, NULL, 'L' },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,7 +190,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "+hD:u:bM:jS:", options, NULL)) >= 0) {
|
while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:", options, NULL)) >= 0) {
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
@ -247,6 +256,20 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'L':
|
||||||
|
file_label = strdup(optarg);
|
||||||
|
if (!file_label)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Z':
|
||||||
|
process_label = strdup(optarg);
|
||||||
|
if (!process_label)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_READ_ONLY:
|
case ARG_READ_ONLY:
|
||||||
arg_read_only = true;
|
arg_read_only = true;
|
||||||
break;
|
break;
|
||||||
@ -396,6 +419,7 @@ static int mount_all(const char *dest) {
|
|||||||
|
|
||||||
for (k = 0; k < ELEMENTSOF(mount_table); k++) {
|
for (k = 0; k < ELEMENTSOF(mount_table); k++) {
|
||||||
_cleanup_free_ char *where = NULL;
|
_cleanup_free_ char *where = NULL;
|
||||||
|
_cleanup_free_ char *options = NULL;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
where = strjoin(dest, "/", mount_table[k].where, NULL);
|
where = strjoin(dest, "/", mount_table[k].where, NULL);
|
||||||
@ -418,11 +442,22 @@ static int mount_all(const char *dest) {
|
|||||||
|
|
||||||
mkdir_p(where, 0755);
|
mkdir_p(where, 0755);
|
||||||
|
|
||||||
|
#ifdef HAVE_SELINUX
|
||||||
|
if (file_label && (streq_ptr(mount_table[k].what, "tmpfs") ||
|
||||||
|
streq_ptr(mount_table[k].what, "devpts")))
|
||||||
|
options = strjoin(mount_table[k].options, ",context=\"", file_label, "\"", NULL);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
options = strjoin(mount_table[k].options, NULL);
|
||||||
|
|
||||||
|
if (!options)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
if (mount(mount_table[k].what,
|
if (mount(mount_table[k].what,
|
||||||
where,
|
where,
|
||||||
mount_table[k].type,
|
mount_table[k].type,
|
||||||
mount_table[k].flags,
|
mount_table[k].flags,
|
||||||
mount_table[k].options) < 0 &&
|
options) < 0 &&
|
||||||
mount_table[k].fatal) {
|
mount_table[k].fatal) {
|
||||||
|
|
||||||
log_error("mount(%s) failed: %m", where);
|
log_error("mount(%s) failed: %m", where);
|
||||||
@ -1491,6 +1526,11 @@ int main(int argc, char *argv[]) {
|
|||||||
} else
|
} else
|
||||||
env_use = (char**) envp;
|
env_use = (char**) envp;
|
||||||
|
|
||||||
|
#if HAVE_SELINUX
|
||||||
|
if (process_label)
|
||||||
|
if (setexeccon(process_label) < 0)
|
||||||
|
log_error("setexeccon(\"%s\") failed: %m", process_label);
|
||||||
|
#endif
|
||||||
if (arg_boot) {
|
if (arg_boot) {
|
||||||
char **a;
|
char **a;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user