mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 13:03:02 +02:00
confd: add limited support for container capabilities
This change adds limited support for container capabilities. It allows a more fine-grained control than priviliged mode does. Fixes #365 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -103,8 +103,8 @@ create()
|
||||
logging="--log-driver k8s-file --log-opt path=/run/containers/$name.fifo"
|
||||
fi
|
||||
|
||||
args="$args --cgroup-parent=containers"
|
||||
args="$args --restart=$restart --systemd=false --tz=local $privileged --replace --quiet"
|
||||
args="$args --replace --quiet --cgroup-parent=containers $caps"
|
||||
args="$args --restart=$restart --systemd=false --tz=local $privileged"
|
||||
args="$args $ro $vol $mount $hostname $entrypoint $env $port $logging"
|
||||
pidfn=/run/container:${name}.pid
|
||||
|
||||
@@ -226,6 +226,8 @@ options:
|
||||
-a, --all Show all, of something
|
||||
--dns NAMESERVER Set nameserver(s) when creating a container
|
||||
--dns-search LIST Set host lookup search list when creating container
|
||||
--cap-add CAP Add capability to unprivileged container
|
||||
--cap-drop CAP Drop capability, for privileged containter
|
||||
-c, --creds USR[:PWD] Credentials to pass to curl -u for remote ops
|
||||
-d, --detach Detach a container started with 'run IMG [CMD]'
|
||||
-e, --env FILE Environment variables when creating container
|
||||
@@ -276,6 +278,14 @@ while [ "$1" != "" ]; do
|
||||
-a | --all)
|
||||
all="-a"
|
||||
;;
|
||||
--cap-add)
|
||||
shift
|
||||
caps="$caps --cap-add=$1"
|
||||
;;
|
||||
--cap-drop)
|
||||
shift
|
||||
caps="$caps --cap-drop=$1"
|
||||
;;
|
||||
-c | --creds)
|
||||
shift
|
||||
creds="-u $1"
|
||||
|
||||
+38
-8
@@ -44,20 +44,24 @@ container networking in podman.
|
||||
Caution
|
||||
-------
|
||||
|
||||
A word of warning, containers can run on your system in privileged mode,
|
||||
as `root`. This gives them full access to devices on your system. But
|
||||
even when though unprivileged containers are fenced from the host with
|
||||
Linux namespaces, and resource limited using Linux cgroups, which scope
|
||||
container applications from seeing and accessing the complete system,
|
||||
there is no guarantee that an application cannot ever break out of this
|
||||
confinement.
|
||||
A word of warning. Containers can run on your system in privileged
|
||||
mode, as `root`, giving them full access to devices on your system.
|
||||
Even though containers are fenced from the host with Linux namespaces,
|
||||
resource limited using cgroups, and normally run with capped privileges,
|
||||
a privileged container is relatively easy to break out of. A trivial
|
||||
example is given in the [Advanced](#advanced) section of this document.
|
||||
|
||||
We recommend avoiding privileged containers, if possible (they do have
|
||||
valid use-cases) and instead use [capabilities](#capabilities).
|
||||
|
||||
Remember:
|
||||
|
||||
- If the system is compromised, containers can be used to easily
|
||||
install malicious software in your system and over the network
|
||||
- Your system is as secure as anything you run in the container
|
||||
- If you run containers, there is no security guarantee of any kind
|
||||
- Running 3rd party container images on your system could open a
|
||||
security hole/attack vector/attack surface
|
||||
security hole/attack vector/surface
|
||||
- An expert with knowledge how to build exploits will be able to
|
||||
jailbreak/elevate to root even if best practices are followed
|
||||
|
||||
@@ -258,6 +262,31 @@ the upgrade command as
|
||||
7ab4a07ee0c6039837419b7afda4da1527a70f0c60c0f0ac21cafee05ba24b52
|
||||
|
||||
|
||||
Capabilities
|
||||
-------------
|
||||
|
||||
An unprivileged container works for almost all use-cases, but there are
|
||||
occasions where they are too restricted and users being looking for the
|
||||
`privileged` flag. Capabilities offers a middle ground.
|
||||
|
||||
For example, a system container from which `ping` does not work:
|
||||
|
||||
admin@example:/config/container/system/> edit capabilities
|
||||
admin@example:/config/container/system/capabilities/> set add net_raw
|
||||
admin@example:/config/container/system/capabilities/> end
|
||||
admin@infix-00-00-00:/config/container/system/> show
|
||||
...
|
||||
capabilities {
|
||||
add net_raw;
|
||||
}
|
||||
...
|
||||
|
||||
Infix supports a subset of all [capabilities][6] that are relevant for
|
||||
containers. Please note, that this is and advanced topic and will
|
||||
require time and analysis of your container application to figure out
|
||||
which capabilities you need.
|
||||
|
||||
|
||||
Networking and Containers
|
||||
-------------------------
|
||||
|
||||
@@ -645,4 +674,5 @@ control an Infix system this way, see [Scripting Infix](scriptiong.md).
|
||||
[3]: https://github.com/opencontainers/image-spec/blob/main/image-layout.md
|
||||
[4]: system.md#ssh-authorized-key
|
||||
[5]: https://docs.docker.com/build/exporters/oci-docker/
|
||||
[6]: https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
[podman]: https://podman.io
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define LOGGER "logger -t container -p local1.notice"
|
||||
|
||||
static const struct srx_module_requirement reqs[] = {
|
||||
{ .dir = YANG_PATH_, .name = MODULE, .rev = "2024-02-01" },
|
||||
{ .dir = YANG_PATH_, .name = MODULE, .rev = "2024-03-27" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
{
|
||||
const char *image = lydx_get_cattr(cif, "image");
|
||||
const char *restart_policy, *string;
|
||||
struct lyd_node *node, *network;
|
||||
struct lyd_node *node, *nets, *caps;
|
||||
FILE *fp, *ap;
|
||||
|
||||
fp = fopenf("w", "%s/%s.sh", INBOX_QUEUE, name);
|
||||
@@ -61,6 +61,14 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
if (lydx_is_enabled(cif, "privileged"))
|
||||
fprintf(fp, " --privileged");
|
||||
|
||||
caps = lydx_get_descendant(lyd_child(cif), "capabilities", NULL);
|
||||
if (caps) {
|
||||
LYX_LIST_FOR_EACH(lyd_child(caps), node, "add")
|
||||
fprintf(fp, " --cap-add %s", lyd_get_value(node));
|
||||
LYX_LIST_FOR_EACH(lyd_child(caps), node, "drop")
|
||||
fprintf(fp, " --cap-drop %s", lyd_get_value(node));
|
||||
}
|
||||
|
||||
LYX_LIST_FOR_EACH(lyd_child(cif), node, "volume")
|
||||
fprintf(fp, " -v %s-%s:%s", name, lydx_get_cattr(node, "name"),
|
||||
lydx_get_cattr(node, "target"));
|
||||
@@ -126,12 +134,12 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
fprintf(fp, " -e /run/containers/args/%s.env", name);
|
||||
}
|
||||
|
||||
network = lydx_get_descendant(lyd_child(cif), "network", NULL);
|
||||
if (network) {
|
||||
if (lydx_is_enabled(network, "host")) {
|
||||
nets = lydx_get_descendant(lyd_child(cif), "network", NULL);
|
||||
if (nets) {
|
||||
if (lydx_is_enabled(nets, "host")) {
|
||||
fprintf(fp, " --net host");
|
||||
} else {
|
||||
LYX_LIST_FOR_EACH(lyd_child(network), node, "interface") {
|
||||
LYX_LIST_FOR_EACH(lyd_child(nets), node, "interface") {
|
||||
struct lyd_node *opt;
|
||||
const char *name;
|
||||
int first = 1;
|
||||
@@ -146,7 +154,7 @@ static int add(const char *name, struct lyd_node *cif)
|
||||
}
|
||||
}
|
||||
|
||||
LYX_LIST_FOR_EACH(lyd_child(network), node, "publish")
|
||||
LYX_LIST_FOR_EACH(lyd_child(nets), node, "publish")
|
||||
fprintf(fp, " -p %s", lyd_get_value(node));
|
||||
}
|
||||
}
|
||||
|
||||
+39
@@ -22,6 +22,11 @@ module infix-containers {
|
||||
prefix infix-if;
|
||||
}
|
||||
|
||||
revision 2024-03-27 {
|
||||
description "Add support for capabilities.";
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
revision 2024-02-01 {
|
||||
description "Initial revision";
|
||||
reference "internal";
|
||||
@@ -61,6 +66,26 @@ module infix-containers {
|
||||
}
|
||||
}
|
||||
|
||||
typedef capabilities {
|
||||
type enumeration {
|
||||
enum dac_override;
|
||||
enum fsetid;
|
||||
enum net_admin;
|
||||
enum net_bind_service;
|
||||
enum net_raw;
|
||||
enum setgid;
|
||||
enum setuid;
|
||||
enum setpcap;
|
||||
enum syslog;
|
||||
enum sys_admin;
|
||||
enum sys_chroot;
|
||||
enum sys_module;
|
||||
enum sys_ptrace;
|
||||
enum sys_rawio;
|
||||
enum sys_time;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Data Nodes
|
||||
*/
|
||||
@@ -217,6 +242,20 @@ module infix-containers {
|
||||
type boolean;
|
||||
}
|
||||
|
||||
container capabilities {
|
||||
description "Capabilities to add for unprivileged and drop for privileged containers.";
|
||||
|
||||
leaf-list add {
|
||||
type capabilities;
|
||||
description "List of capabilities to add to (an unprivileged) container.";
|
||||
}
|
||||
|
||||
leaf-list drop {
|
||||
type capabilities;
|
||||
description "List of capabilities to drop from (a privileged) container.";
|
||||
}
|
||||
}
|
||||
|
||||
list mount {
|
||||
description "Files, content, and directories to mount inside container.";
|
||||
key name;
|
||||
Reference in New Issue
Block a user