diff --git a/.deploy/helm/eupf/README.md b/.deploy/helm/eupf/README.md index ec628603..0b1a20d6 100644 --- a/.deploy/helm/eupf/README.md +++ b/.deploy/helm/eupf/README.md @@ -19,7 +19,7 @@ The default values produce a working pod: eUPF is configured via `UPF_*` environ kubelet --allowed-unsafe-sysctls 'net.ipv4.ip_forward' ``` -- **Privileges**: eUPF loads eBPF programs, mounts bpffs/debugfs (via the image entrypoint) and raises `RLIMIT_MEMLOCK`. By default the chart runs the container as `privileged: true`. If your environment allows a finer-grained setup, override `securityContext`, e.g.: +- **Privileges**: eUPF loads eBPF programs, mounts bpffs/debugfs (via the image entrypoint) and raises `RLIMIT_MEMLOCK`. By default the chart gives the container the capabilities this takes and nothing more: ```yaml securityContext: @@ -27,6 +27,13 @@ The default values produce a working pod: eUPF is configured via `UPF_*` environ add: [NET_ADMIN, SYS_ADMIN, SYS_RESOURCE, BPF, PERFMON] ``` + The container keeps the device cgroup, the masked `/proc` and `/sys` paths and the runtime's seccomp and AppArmor profiles. Some environments deny the entrypoint's mounts even with `SYS_ADMIN`: nodes whose AppArmor profile forbids `mount` (the runtime's default profile on Ubuntu and Debian does), a custom seccomp profile that blocks `mount` or `bpf`, or a runtime that rejects `BPF` and `PERFMON` on a kernel before 5.8. There, either allow the mounts (for AppArmor: `securityContext.appArmorProfile: {type: Unconfined}` on Kubernetes 1.30+, the `container.apparmor.security.beta.kubernetes.io/eupf: unconfined` pod annotation before) or fall back to a privileged container: + + ```yaml + securityContext: + privileged: true + ``` + - The `/sys` hostPath is mounted read-only into the pod (required by the entrypoint to mount bpffs/debugfs). ## Configuration diff --git a/.deploy/helm/eupf/templates/NOTES.txt b/.deploy/helm/eupf/templates/NOTES.txt index 834050d1..5fdffd9d 100644 --- a/.deploy/helm/eupf/templates/NOTES.txt +++ b/.deploy/helm/eupf/templates/NOTES.txt @@ -24,6 +24,7 @@ eUPF is configured via a ConfigMap (config.enabled=true), mounted at Notes: - Nodes must allow the unsafe sysctl net.ipv4.ip_forward (kubelet --allowed-unsafe-sysctls='net.ipv4.ip_forward'). -- The container runs privileged by default (eBPF data plane requires it); - see the chart README for a capabilities-based alternative. +- The container runs with the capabilities the eBPF data plane needs + (NET_ADMIN, SYS_ADMIN, SYS_RESOURCE, BPF, PERFMON), not privileged; see the + chart README for the environments that need the privileged fallback. - The REST API is served on port {{ .Values.service.port }} (service port "http"). diff --git a/.deploy/helm/eupf/values.yaml b/.deploy/helm/eupf/values.yaml index 2a845eb6..740a17b7 100644 --- a/.deploy/helm/eupf/values.yaml +++ b/.deploy/helm/eupf/values.yaml @@ -223,13 +223,18 @@ podSecurityContext: - name: net.ipv4.ip_forward value: "1" -# eUPF loads eBPF programs, mounts bpffs/debugfs and raises RLIMIT_MEMLOCK, -# which requires elevated privileges. If your environment allows it, a more -# fine-grained alternative is: -# capabilities: -# add: [NET_ADMIN, SYS_ADMIN, SYS_RESOURCE, BPF, PERFMON] +# eUPF loads eBPF programs (BPF, PERFMON), attaches XDP and sets routes +# (NET_ADMIN), raises RLIMIT_MEMLOCK (SYS_RESOURCE) and mounts bpffs/debugfs +# from the image entrypoint (SYS_ADMIN). These capabilities are all it needs; +# the container keeps the device cgroup, the masked /proc and /sys paths and +# the runtime's seccomp and AppArmor profiles. Where the mounts are denied +# anyway (an AppArmor profile that forbids mount, a seccomp profile that +# blocks mount or bpf, a runtime that does not know CAP_BPF on a kernel +# before 5.8), fall back to a privileged container: +# privileged: true securityContext: - privileged: true + capabilities: + add: [NET_ADMIN, SYS_ADMIN, SYS_RESOURCE, BPF, PERFMON] extraContainerPorts: - name: metrics diff --git a/.trivyignore b/.trivyignore index c5486963..5c15ca27 100644 --- a/.trivyignore +++ b/.trivyignore @@ -16,11 +16,17 @@ AVD-KSV-0030 AVD-KSV-0106 AVD-KSV-0117 -# eUPF data plane requires a privileged (root) container to load eBPF -# programs, mount bpffs/debugfs and raise RLIMIT_MEMLOCK - running with -# a restricted security context is not supported by design. +# The eUPF data plane runs as root with the capabilities it needs (NET_ADMIN, +# SYS_ADMIN, SYS_RESOURCE, BPF, PERFMON) to load eBPF programs, mount +# bpffs/debugfs and raise RLIMIT_MEMLOCK - a restricted security context is +# not supported by design. AVD-KSV-0118 +# SYS_ADMIN is what the image entrypoint mounts bpffs and debugfs with; the +# other capabilities are a smaller grant than the privileged container the +# chart ran before, which had every capability and no runtime profile. +AVD-KSV-0005 + # The eUPF data plane needs a read-only /sys hostPath mount: the image # entrypoint mounts bpffs and debugfs under /sys to load the eBPF # programs. A "disallowed volume type" (hostPath) is by design here.