From 86efafeb8599014848e22267fa7b86b7eb886d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Petazzoni?= Date: Thu, 11 Sep 2025 16:01:33 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9E=95=EF=B8=8F=20Merge=20container=20securi?= =?UTF-8?q?ty=20content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slides/containers/Container_Engines.md | 38 ++++-- slides/containers/Rootless_Networking.md | 75 +++++++++++ slides/containers/Security.md | 162 +++++++++++++++++++++++ slides/intro-fullday.yml | 1 + slides/intro-selfpaced.yml | 2 + slides/intro-twodays.yml | 2 + 6 files changed, 271 insertions(+), 9 deletions(-) create mode 100644 slides/containers/Rootless_Networking.md create mode 100644 slides/containers/Security.md diff --git a/slides/containers/Container_Engines.md b/slides/containers/Container_Engines.md index 8da77c6c..19ee062c 100644 --- a/slides/containers/Container_Engines.md +++ b/slides/containers/Container_Engines.md @@ -84,9 +84,9 @@ like Windows, macOS, Solaris, FreeBSD ... * Each `lxc-start` process exposes a custom API over a local UNIX socket, allowing to interact with the container. -* No notion of image (container filesystems have to be managed manually). +* No notion of image (container filesystems had be managed manually). -* Networking has to be set up manually. +* Networking had to be set up manually. --- @@ -98,10 +98,22 @@ like Windows, macOS, Solaris, FreeBSD ... * Daemon exposing a REST API. +* Can run containers and virtual machines. + * Can manage images, snapshots, migrations, networking, storage. * "offers a user experience similar to virtual machines but using Linux containers instead." +* Driven by Canonical. + +--- + +## Incus + +* Community-driven fork of LXD. + +* Relatively recent [announced in August 2023](https://linuxcontainers.org/incus/announcement/) so time will tell what the notable differences will be. + --- ## CRI-O @@ -140,7 +152,7 @@ We're not aware of anyone using it directly (i.e. outside of Kubernetes). --- -## Kata containers +## [Kata containers](https://katacontainers.io/) * OCI-compliant runtime. @@ -152,7 +164,7 @@ We're not aware of anyone using it directly (i.e. outside of Kubernetes). --- -## gVisor +## [gVisor](https://gvisor.dev/) * OCI-compliant runtime. @@ -170,7 +182,17 @@ We're not aware of anyone using it directly (i.e. outside of Kubernetes). --- -## Overall ... +## Others + +- Micro VMs: Firecracker, Edera... + +- [crun](https://github.com/containers/crun) (runc rewritten in C) + +- [youki](https://youki-dev.github.io/youki/) (runc rewritten in Rust) + +--- + +## To Docker Or Not To Docker * The Docker Engine is very developer-centric: @@ -184,8 +206,6 @@ We're not aware of anyone using it directly (i.e. outside of Kubernetes). * As a result, it is a fantastic tool in development environments. -* On servers: +* On Kubernetes clusters, containerd or CRI-O are better choices. - - Docker is a good default choice - - - If you use Kubernetes, the engine doesn't matter +* On Kubernetes clusters, the container engine is an implementation detail. diff --git a/slides/containers/Rootless_Networking.md b/slides/containers/Rootless_Networking.md new file mode 100644 index 00000000..628fb755 --- /dev/null +++ b/slides/containers/Rootless_Networking.md @@ -0,0 +1,75 @@ +# Rootless Networking + +The "classic" approach for container networking is `veth` + bridge. + +Pros: + +- good performance + +- easy to manage and understand + +- flexible (possibility to use multiple, isolated bridges) + +Cons: + +- requires root access on the host to set up networking + +--- + +## Rootless options + +- Locked down helpers + + - daemon, scripts started through sudo... + + - used by some desktop virtualization platforms + + - still requires root access at some point + +- Userland networking stacks + + - true solution that does not require root privileges + + - lower performance + +--- + +## Userland stacks + +- [SLiRP](https://en.wikipedia.org/wiki/Slirp) + + *the OG project that inspired the other ones!* + +- [VPNKit](https://github.com/moby/vpnkit) + + *introduced by Docker Desktop to play nice with enterprise VPNs* + +- [slirp4netns](https://github.com/rootless-containers/slirp4netns) + + *slirp adapted for network namespaces, and therefore, containers; better performance* + +- [passt and pasta](https://passt.top/) + + *more modern approach; better support for inbound traffic; IPv6...)* + +--- + +## Passt/Pasta + +- No dependencies + +- NAT (like slirp4netns) or no-NAT (for e.g. KubeVirt) + +- Can handle inbound traffic dynamically + +- No dynamic memory allocation + +- Good security posture + +- IPv6 support + +- Reasonable performance + +--- + +## Demo? diff --git a/slides/containers/Security.md b/slides/containers/Security.md new file mode 100644 index 00000000..0d6ecbbf --- /dev/null +++ b/slides/containers/Security.md @@ -0,0 +1,162 @@ +# Security models + +In this section, we want to address a few security-related questions: + +- What permissions do we need to run containers or a container engine? + +- Can we use containers to escalate permissions? + +- Can we break out of a container (move from container to host)? + +- Is it safe to run untrusted code in containers? + +- What about Kubernetes? + +--- + +## Running Docker, containerd, podman... + +- In the early days, running containers required root permissions + + (to set up namespaces, cgroups, networking, mount filesystems...) + +- Eventually, new kernel features were developed to allow "rootless" operation + + (user namespaces and associated tweaks) + +- Rootless requires a little bit of additional setup on the system (e.g. subuid) + + (although this is increasingly often automated in modern distros) + +- Docker runs as root by default; Podman runs rootless by default + +--- + +## Advantages of rootless + +- Containers can run without any intervention from root + + (no package install, no daemon running as root...) + +- Containerized processes run with non-privileged UID + +- Container escape doesn't automatically result in full host compromise + +- Can isolate workloads by using different UID + +--- + +## Downsides of rootless + +- *Relatively* newer (rootless Docker was introduced in 2019) + + - many quirks/issues/limitations in the initial implementations + + - kernel features and other mechanisms were introduced over time + + - they're not always very well documented + +- I/O performance (disk, network) is typically lower + + (due to using special mechanisms instead of more direct access) + +- Rootless and rootful engines must use different image storage + + (due to UID mapping) + +--- + +## Why not rootless everywhere? + +- Not very useful on clusters + + - users shouldn't log into cluster nodes + + - questionable security improvement + + - lower I/O performance + +- Not very useful with Docker Desktop / Podman Desktop + + - container workloads are already inside a VM + + - could arguably provide a layer of inter-workload isolation + + - would require new APIs and concepts + +--- + +## Permission escalation + +- Access to the Docker socket = root access to the machine + ```bash + docker run --privileged -v /:/hostfs -ti alpine + ``` + +- That's why by default, the Docker socket access is locked down + + (only accessible by `root` and group `docker`) + +- If user `alice` has access to the Docker socket: + + *compromising user `alice` leads to whole host compromise!* + +- Doesn't fundamentally change the threat model + + (if `alice` gets compromised in the first place, we're in trouble!) + +- Enables new threats (persistence, kernel access...) + +--- + +## Avoiding the problem + +- Rootless containers + +- Container VM (Docker Desktop, Podman Desktop, Orbstack...) + +- Unfortunately: no fine-grained access to the Docker API + + (no way to e.g. disable privileged containers, volume mounts...) + +--- + +## Escaping containers + +- Very easy with some features + + (privileged containers, volume mounts, device access) + +- Otherwise impossible in theory + + (but of course, vulnerabilities do exist!) + +- **Be careful with scripts invoking `docker run`, or Compose files!** + +--- + +## Untrusted code + +- Should be safe as long as we're not enabling dangerous features + + (privileged containers, volume mounts, device access, capabilities...) + +- Remember that by default, containers can make network calls + + (but see: `--net none` and also `docker network create --internal`) + +- And of course, again: vulnerabilities do exist! + +--- + +## What about Kubernetes? + +- Ability to run arbitrary pods = dangerous + +- But there are multiple safety mechanisms available: + + - Pod Security Settings (limit "dangerous" features) + + - RBAC (control who can do what) + + - webhooks and policy engines for even finer grained control diff --git a/slides/intro-fullday.yml b/slides/intro-fullday.yml index 977550b8..7b4dcd9d 100644 --- a/slides/intro-fullday.yml +++ b/slides/intro-fullday.yml @@ -66,6 +66,7 @@ content: #- containers/Copy_On_Write.md #- containers/Containers_From_Scratch.md #- containers/Container_Engines.md + #- containers/Security.md #- containers/Pods_Anatomy.md #- containers/Ecosystem.md #- containers/Orchestration_Overview.md diff --git a/slides/intro-selfpaced.yml b/slides/intro-selfpaced.yml index c74a5bf1..e806f7e6 100644 --- a/slides/intro-selfpaced.yml +++ b/slides/intro-selfpaced.yml @@ -66,6 +66,8 @@ content: - - containers/Namespaces_Cgroups.md - containers/Copy_On_Write.md - containers/Containers_From_Scratch.md + - containers/Security.md + - containers/Rootless_Networking.md - containers/Images_Deep_Dive.md - - containers/Container_Engines.md - containers/Pods_Anatomy.md diff --git a/slides/intro-twodays.yml b/slides/intro-twodays.yml index b9c43331..2ef4bbac 100644 --- a/slides/intro-twodays.yml +++ b/slides/intro-twodays.yml @@ -78,5 +78,7 @@ content: #- containers/Namespaces_Cgroups.md #- containers/Copy_On_Write.md #- containers/Containers_From_Scratch.md + #- containers/Rootless_Networking.md + #- containers/Security.md #- containers/Pods_Anatomy.md #- containers/Ecosystem.md