Initial applications isolation support using Linux namespaces.

This commit is contained in:
Tiago de Bem Natel de Moura
2019-09-19 15:25:23 +03:00
parent 6346e641ee
commit c554941b4f
21 changed files with 1467 additions and 201 deletions

View File

@@ -39,9 +39,6 @@ typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
typedef nxt_int_t (*nxt_conf_vldt_element_t)(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
typedef nxt_int_t (*nxt_conf_vldt_system_t)(nxt_conf_validation_t *vldt,
char *name);
static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type);
@@ -86,10 +83,6 @@ static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_array_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_system(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *name);
static nxt_int_t nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *name);
static nxt_int_t nxt_conf_vldt_environment(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_argument(nxt_conf_validation_t *vldt,
@@ -101,6 +94,21 @@ static nxt_int_t nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt,
static nxt_int_t nxt_conf_vldt_java_option(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
static nxt_int_t
nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data);
static nxt_int_t
nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
#if (NXT_HAVE_CLONE_NEWUSER)
static nxt_int_t nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt,
const char* mapfile, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
#endif
static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[] = {
{ nxt_string("read_timeout"),
@@ -340,6 +348,100 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_processes_members[] = {
};
static nxt_conf_vldt_object_t nxt_conf_vldt_app_namespaces_members[] = {
#if (NXT_HAVE_CLONE_NEWUSER)
{ nxt_string("credential"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
#if (NXT_HAVE_CLONE_NEWPID)
{ nxt_string("pid"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
#if (NXT_HAVE_CLONE_NEWNET)
{ nxt_string("network"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
#if (NXT_HAVE_CLONE_NEWNS)
{ nxt_string("mount"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
#if (NXT_HAVE_CLONE_NEWUTS)
{ nxt_string("uname"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
#if (NXT_HAVE_CLONE_NEWCGROUP)
{ nxt_string("cgroup"),
NXT_CONF_VLDT_BOOLEAN,
NULL,
NULL },
#endif
NXT_CONF_VLDT_END
};
#if (NXT_HAVE_CLONE_NEWUSER)
static nxt_conf_vldt_object_t nxt_conf_vldt_app_procmap_members[] = {
{ nxt_string("container"),
NXT_CONF_VLDT_INTEGER,
NULL,
NULL },
{ nxt_string("host"),
NXT_CONF_VLDT_INTEGER,
NULL,
NULL },
{ nxt_string("size"),
NXT_CONF_VLDT_INTEGER,
NULL,
NULL },
};
#endif
static nxt_conf_vldt_object_t nxt_conf_vldt_app_isolation_members[] = {
{ nxt_string("namespaces"),
NXT_CONF_VLDT_OBJECT,
&nxt_conf_vldt_clone_namespaces,
(void *) &nxt_conf_vldt_app_namespaces_members },
#if (NXT_HAVE_CLONE_NEWUSER)
{ nxt_string("uidmap"),
NXT_CONF_VLDT_ARRAY,
&nxt_conf_vldt_array_iterator,
(void *) &nxt_conf_vldt_clone_uidmap },
{ nxt_string("gidmap"),
NXT_CONF_VLDT_ARRAY,
&nxt_conf_vldt_array_iterator,
(void *) &nxt_conf_vldt_clone_gidmap },
#endif
NXT_CONF_VLDT_END
};
static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
{ nxt_string("type"),
NXT_CONF_VLDT_STRING,
@@ -358,13 +460,13 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
{ nxt_string("user"),
NXT_CONF_VLDT_STRING,
nxt_conf_vldt_system,
(void *) &nxt_conf_vldt_user },
NULL,
NULL },
{ nxt_string("group"),
NXT_CONF_VLDT_STRING,
nxt_conf_vldt_system,
(void *) &nxt_conf_vldt_group },
NULL,
NULL },
{ nxt_string("working_directory"),
NXT_CONF_VLDT_STRING,
@@ -376,6 +478,11 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
&nxt_conf_vldt_object_iterator,
(void *) &nxt_conf_vldt_environment },
{ nxt_string("isolation"),
NXT_CONF_VLDT_OBJECT,
&nxt_conf_vldt_isolation,
(void *) &nxt_conf_vldt_app_isolation_members },
NXT_CONF_VLDT_END
};
@@ -1251,71 +1358,6 @@ nxt_conf_vldt_array_iterator(nxt_conf_validation_t *vldt,
}
static nxt_int_t
nxt_conf_vldt_system(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data)
{
size_t length;
nxt_str_t name;
nxt_conf_vldt_system_t validator;
char string[32];
/* The cast is required by Sun C. */
validator = (nxt_conf_vldt_system_t) data;
nxt_conf_get_string(value, &name);
length = name.length + 1;
length = nxt_min(length, sizeof(string));
nxt_cpystrn((u_char *) string, name.start, length);
return validator(vldt, string);
}
static nxt_int_t
nxt_conf_vldt_user(nxt_conf_validation_t *vldt, char *user)
{
struct passwd *pwd;
nxt_errno = 0;
pwd = getpwnam(user);
if (pwd != NULL) {
return NXT_OK;
}
if (nxt_errno == 0) {
return nxt_conf_vldt_error(vldt, "User \"%s\" is not found.", user);
}
return NXT_ERROR;
}
static nxt_int_t
nxt_conf_vldt_group(nxt_conf_validation_t *vldt, char *group)
{
struct group *grp;
nxt_errno = 0;
grp = getgrnam(group);
if (grp != NULL) {
return NXT_OK;
}
if (nxt_errno == 0) {
return nxt_conf_vldt_error(vldt, "Group \"%s\" is not found.", group);
}
return NXT_ERROR;
}
static nxt_int_t
nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name,
nxt_conf_value_t *value)
@@ -1353,6 +1395,133 @@ nxt_conf_vldt_environment(nxt_conf_validation_t *vldt, nxt_str_t *name,
}
static nxt_int_t
nxt_conf_vldt_clone_namespaces(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data)
{
return nxt_conf_vldt_object(vldt, value, data);
}
static nxt_int_t
nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
void *data)
{
return nxt_conf_vldt_object(vldt, value, data);
}
#if (NXT_HAVE_CLONE_NEWUSER)
typedef struct {
nxt_int_t container;
nxt_int_t host;
nxt_int_t size;
} nxt_conf_vldt_clone_procmap_conf_t;
static nxt_conf_map_t nxt_conf_vldt_clone_procmap_conf_map[] = {
{
nxt_string("container"),
NXT_CONF_MAP_INT32,
offsetof(nxt_conf_vldt_clone_procmap_conf_t, container),
},
{
nxt_string("host"),
NXT_CONF_MAP_INT32,
offsetof(nxt_conf_vldt_clone_procmap_conf_t, host),
},
{
nxt_string("size"),
NXT_CONF_MAP_INT32,
offsetof(nxt_conf_vldt_clone_procmap_conf_t, size),
},
};
static nxt_int_t
nxt_conf_vldt_clone_procmap(nxt_conf_validation_t *vldt, const char *mapfile,
nxt_conf_value_t *value)
{
nxt_int_t ret;
nxt_conf_vldt_clone_procmap_conf_t procmap;
procmap.container = -1;
procmap.host = -1;
procmap.size = -1;
ret = nxt_conf_map_object(vldt->pool, value,
nxt_conf_vldt_clone_procmap_conf_map,
nxt_nitems(nxt_conf_vldt_clone_procmap_conf_map),
&procmap);
if (ret != NXT_OK) {
return ret;
}
if (procmap.container == -1) {
return nxt_conf_vldt_error(vldt, "The %s requires the "
"\"container\" field set.", mapfile);
}
if (procmap.host == -1) {
return nxt_conf_vldt_error(vldt, "The %s requires the "
"\"host\" field set.", mapfile);
}
if (procmap.size == -1) {
return nxt_conf_vldt_error(vldt, "The %s requires the "
"\"size\" field set.", mapfile);
}
return NXT_OK;
}
static nxt_int_t
nxt_conf_vldt_clone_uidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
{
nxt_int_t ret;
if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
return nxt_conf_vldt_error(vldt, "The \"uidmap\" array "
"must contain only object values.");
}
ret = nxt_conf_vldt_object(vldt, value,
(void *) nxt_conf_vldt_app_procmap_members);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
return nxt_conf_vldt_clone_procmap(vldt, "uid_map", value);
}
static nxt_int_t
nxt_conf_vldt_clone_gidmap(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
{
nxt_int_t ret;
if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
return nxt_conf_vldt_error(vldt, "The \"gidmap\" array "
"must contain only object values.");
}
ret = nxt_conf_vldt_object(vldt, value,
(void *) nxt_conf_vldt_app_procmap_members);
if (nxt_slow_path(ret != NXT_OK)) {
return ret;
}
return nxt_conf_vldt_clone_procmap(vldt, "gid_map", value);
}
#endif
static nxt_int_t
nxt_conf_vldt_argument(nxt_conf_validation_t *vldt, nxt_conf_value_t *value)
{