alpinelinux / docker-alpine

Official Alpine Linux Docker image. Win at minimalism!
MIT License
1.07k stars 262 forks source link

Provide a container exec user as part of the base alpine image #407

Open CameronGo opened 1 month ago

CameronGo commented 1 month ago

I think it would be helpful to provide a user intended for app execution in the base image. Best practice dictates that production containers should not be deployed using the root user for app execution. Currently this leaves it to each app owner to create an unprivileged user in their app Dockerfile or maintain a base image with the same. My suggestion is to create a system user that app owners leverage knowing that this user is maintained to adhere to best practices in the base image.

I've submitted https://github.com/alpinelinux/docker-alpine/pull/408 to serve as a starting point, though I'm not sure that what I've currently put forward is consistent with how this image is typically maintained.

fossdd commented 1 month ago

I think you don't need to run as another user, as in a container you're already isolated and have only root permissions to the container and not on the host system. But even if so, I think a user shouldn't be in the base image as use cases for Alpine images vary a lot.

CameronGo commented 1 month ago

I think you don't need to run as another user, as in a container you're already isolated and have only root permissions to the container and not on the host system. But even if so, I think a user shouldn't be in the base image as use cases for Alpine images vary a lot.

For as long as I've used Docker containers, the best practice has always been to run production containers as a non-root user. Google container processes run as root and you'll find plenty of the same. I've seen theories regarding privilege escalation from the container to the host, but no clear evidence of this. I think the more realistic threat is the same as running any other production process as root, which is that the container itself could be compromised by a bad actor exploiting vulnerabilities in the container processes. Here is an excerpt from our security monitoring tool:

A malicious user can run code on a system either thanks to actions that could be deemed legitimate - depending on internal business logic or operational management shells - or thanks to malicious actions. For example, with arbitrary code execution after exploiting a service that the container hosts. In this case, the malicious user can read and exfiltrate any file (including from Docker volumes), open new network connections, install malicious software, or, worse, break out of the container’s isolation context by exploiting other components. Depending on the infrastructure’s resilience, attackers may then extend their attack to other services, such as Kubernetes clusters or cloud providers, in order to maximize their reach.

With that threat in mind, and knowing that alpine is broadly used as the base for production images, what do you propose as the preferred standardized solution? (a) Use the alpine image as the base and add the recommended RUN adduser and USER commands to every Dockerfile for every application and attempt to enforce this by convention or (b) Every community member should build and maintain their own base image, based on the published alpine image, but then must be extended and maintained internally to adhere to best security practices?

If I must choose one of the above, for my part I'd choose option (b), but I prefer to reference the public alpine image in production containers for both convenience and standardization.