Improving Docker Swarm security with separate users?

From a security perspective, Docker Swarm seems like a nightmare, the deeper I look into it. Docker Swarm needs to be run with root, most containers use root user by default.

How can I improve the security by using separate users for the Docker containers? My understanding is that I can pass a user:group via CLI and compose, but that’s the user used inside of the container, and it has to exist inside the container. So if default images use root, I would need to create custom Dockerfiles and maintain those with every update of the original images.

Is there no easy way to tell Docker: use this user:group on the host, it doesn’t matter what the user inside Docker is? A solution that is also working with Docker Swarm?

If I have to, I am willing to create the users on the host first. For me it’s mainly about bind mounts for configuration and logs, which need to be accessed. Then those would be chown’ed to the dedicated users.

Use case: custom docker socket container with access to docker socket on host, traefik reverse proxy containers which need to load custom configuration file and write access log to file, app containers that need to read config file, database that needs to read config file.

You could use uid and gid with the user: element. Both don’t have to exist on the host or inside the container.

I am not sure if most containers run as root, but sadly a lot do. Every image that uses s6-overlay does (e.g. Linuxserver images).

That’s why I prefer to use Bitnami images, as they always run as unprivileged user.
They are still not perfect, especially if your companies compliance policy requires you to run containers with read-only container filesystem.

But that doesn’t really help, because then they can read config files from a bind mount on host, right?

You want to bind a host folder to the container and don’t want the container to be able to access its content? :thinking: There must be more to your thought, that what you expressed :slight_smile:

If you don’t want files in a bind mount to be accessible, they need to have a different owner uid and gid then the container process, and of course permissions for the “others” group would need to be configured to deny access to what’s supposed to be inaccessible. Unix file permissions to the rescue! :smiley:

I want a dedicated bind mount host folder for the dedicated user within container to be read/write.

You mentioned that users don’t have to exist, but I would expect that to be required for this to work :slight_smile:

What makes you think it’s expected? You can use chown with uid:gid that don’t exist on the host, and you can start a container with a uid:gid that doesn’t exist on the host. Will the container process still be able to access such a folder if bind mounted? yes!

Just try, you will see.

Will try that, thanks!

There is a Docker security feature called " Isolate containers with a user namespace" (doc), but the explanation seems really not written for the average Docker user.

Why is there no simple docker run --user-remap guest:guest <image> to have all container interaction with host run under guest:guest, just ignoring which user:group is used inside the container?

Afaik, this only works for plain docker containers but not with swarm.

The idea of user namespace remapping is that the container uid:gid are mapped to other uid:gid, which don’t exist, so that in case of a breakout they can’t do any real harm.