Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document security hardening with privileged-mode #549

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lit/docs/install/worker.lit
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ decide much on its own.
--containerd-cni-plugins-dir= Path to CNI network plugins. (default: /usr/local/concourse/bin) [$CONCOURSE_CONTAINERD_CNI_PLUGINS_DIR]
--containerd-request-timeout= How long to wait for requests to Containerd to complete. 0 means no timeout. (default: 5m) [$CONCOURSE_CONTAINERD_REQUEST_TIMEOUT]
--containerd-max-containers= Max container capacity. 0 means no limit. (default: 250) [$CONCOURSE_CONTAINERD_MAX_CONTAINERS]
--containerd-privileged-mode= How many privileges privileged containers get. full is equivalent to root on host. ignore means no extra privileges. fuse-only means enough to use fuse-overlayfs. (default: full) [$CONCOURSE_CONTAINERD_PRIVILEGED_MODE]

Containerd Container Networking:
--containerd-external-ip= IP address to use to reach container's mapped ports. Autodetected if not specified. [$CONCOURSE_CONTAINERD_EXTERNAL_IP]
Expand Down
1 change: 1 addition & 0 deletions lit/docs/operation.lit
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ users that are new to these concepts, we do recommend learning how to set up
\include-section{./operation/tracing.lit}
\include-section{./operation/encryption.lit}
\include-section{./operation/creds.lit}
\include-section{./operation/security-hardening.lit}
\include-section{./operation/container-placement.lit}
\include-section{./operation/opa.lit}
\include-section{./operation/performance-tuning.lit}
Expand Down
65 changes: 65 additions & 0 deletions lit/docs/operation/security-hardening.lit
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
\title{Security Hardening}{security-hardening}

\use-plugin{concourse-docs}

Concourse tasks run in containers, which provide a degree of isolation from the
host. However, if inadequate attention is paid to security, anyone with the
ability to update pipelines or modify a script called in a task might be
able to escape from the container and take control of the host. From there,
they could access other host resources, interfere with pipelines they might
not otherwise have access to, and collect credentials.

Following the guidance in this section can help you to greatly reduce the risk
of a container escape.

\section{
\title{Keeping your kernel up-to-date}

Containers run in different Linux namespaces on the same Linux kernel as the
host system. Vulnerabilities in the kernel version you run can easily allow
for local privilege escalation - which in the Concourse context means allowing
an escape from a Concourse task to full root privileges on the host.

You can greatly reduce the risk of container escapes by staying up to date
with your kernel version, tracking either the latest release, or the latest
kernel from a Linux distribution with a reputable security programme.
}

\section{
\title{Locking down privileged mode}

By default, privileged mode (i.e. tasks with \code{privileged: true} on the
task step) grants containers a very wide set of Linux capabilities, without
any restrictions on syscalls allowed. These privileges are enough to load a
kernel module (allowing arbitrary privilege escalation and container escape),
as well as direct access to all host devices. As such, by default, privileged
tasks are equivalent to full root access on the host.

If you are running a worker using the containerd container runtime, Concourse
provides some options to reduce the risk of container escapes through
privileged tasks.

The \code{--containerd-privileged-mode=ignore} (or by environment variable,
\code{CONCOURSE_CONTAINERD_PRIVILEGED_MODE=ignore}) option to the worker is
the most restrictive, but most secure option. It makes Concourse treat
privileged tasks the same as normal tasks (i.e. grants no extra privileges,
effectively disabling privileged tasks). While this is secure, it is also
restrictive if you want to do things like build or run containers inside
tasks.

The \code{--containerd-privileged-mode=fuse-only} (or by environment
variable, \code{CONCOURSE_CONTAINERD_PRIVILEGED_MODE=fuse-only}) option to
the worker makes it possible to secure privileged tasks against container
escape, while still allowing privileged tasks to build container images with
buildah, and run them with podman from inside the task.

\bold{Caution:} For the fuse-only privileged mode option to be secure against
escapes from privileged tasks, you must run your worker in a container with
user namespaces enabled. Privileged containers in fuse-only mode have
\code{CAP_SYS_ADMIN} capability, which is harmless when in a non-default
user namespace, but equivalent to full root on the host otherwise. When
running the worker in a Docker or podman container, refer to the
\link{Docker}{https://docs.docker.com/engine/security/userns-remap/#enable-userns-remap-on-the-daemon}
or \link{Podman}{https://docs.podman.io/en/latest/markdown/podman-run.1.html#subuidname-name}
docs to learn how to set up user namespaces.
}