lloesche / valheim-server-docker

Valheim dedicated gameserver with automatic update, World backup, BepInEx and ValheimPlus mod support
https://hub.docker.com/r/lloesche/valheim-server
Apache License 2.0
1.94k stars 272 forks source link

Specify user and group ID #20

Closed coolmule0 closed 3 years ago

coolmule0 commented 3 years ago

Is it possible to change the owning user and group of the container so root does not own everything?

This helps with mounted volumes not be root access level

Supportlik commented 3 years ago

I will add this feature on this weekend.

ericlathrop commented 3 years ago

I tried running this container as non-root, and got an error about supervisord being unable to drop privileges.

Do-while-Bacon commented 3 years ago

Just adding in that I would really like to have this feature. I feel that it is good security practice to isolate containers (and associated volumes) under their own service accounts.

lloesche commented 3 years ago

I would love this feature. Here's a couple of things to consider for an implementation:

This image is being used by a lot of NAS users who might not be familiar with UIDs and changing permissions. I do not want to break the image for them. For instance on a Synology when starting the server on a directory that hasn't been properly set up the container might see permissions 000 on all the world files copied to the /config/worlds directory with some unknown UID/GID as owner. Solving this is how the WORLDS_DIRECTORY_PERMISSIONS and WORLDS_FILES_PERMISSIONS env vars were born.

For tech savvy users it is already possible to run the container in a different User namespace using subordinate UID/GIDs so UID 0 is not mapped to the hosts root account anyways and therefor changing the UID within the container has little effect on the overall security of the system. For anyone concerned with security of the host system this is likely a must-do regardless.

There are multiple levels of implementation that we could look at.

One would be building the container and running supervised and the valheim-server/-updater/-backup scripts as root but running the actual server binary as non-root. This would still allow the container to change permissions on files like described above but add some security to the one component that is exposed to the Internet and therefor vulnerable to remote exploits. This would also allow to supply a UID/GID via environment variables and change the server permissions to those IDs on startup.

The other would be to drop privileges right in the Dockerfile. Essentially the image would be built as root but then permissions are changed to UID 1001 and right before the ENTRYPOINT we would have USER 1001. This is how Bitnami builds all their images. It has the obvious advantage that none of the processes inside the container run as root but the obvious disadvantage that anyone volume mounting external world files into the container must make sure that UIDs inside and outside the container match up. Also the UID/GID can not be changed at runtime and are set to a fixed value in the Dockerfile at build time. This I feel is prohibitively complex for the NAS user that just wants to play some Valheim with their friends but does not have the required Linux knowledge to make this work for them.

If we'd go the later route it would definitely be in a separate Docker image. Like we could have a :strictmode tagged image for advanced users or something along those lines.

InB4DevOps commented 3 years ago

"Security comes at a cost."

It's not too hard to get UID and GID from a user. Even "dumb" NAS users can get those values. And can't we implement the container in a way that it keeps using root for when not-so-security-savvy-NAS-users don't / can't set those UID & GID ENV vars?

lloesche commented 3 years ago

And can't we implement the container in a way that it keeps using root for when not-so-security-savvy-NAS-users don't / can't set those UID & GID ENV vars?

We absolutely can in the first scenario where the container is still started as root and then inside the container we drop privileges for valheim-server. We could make UID/GID 0 by default and allow setting it via env vars.

In the second implementation example where the entire container runs as UID 1001 hard coded via the Dockerfile this would not be possible as the Dockerfile would determine the UID at build time and there's no way to change permissions at runtime then. See https://engineering.bitnami.com/articles/why-non-root-containers-are-important-for-security.html for examples of how Bitnami builds their images that way.

I think the later is out of scope or maybe we'll do it for a :strictmode tagged image. The first one where we allow setting UID/GID via env vars and then drop privileges only for the server inside the container seems like a good compromise between usability and security. And again, even in that case personally I will always use subordinate UID/GIDs on the host so that UID 0 inside the container is not the same as UID 0 on the host. That's just good practice.

lloesche commented 3 years ago

Thank you @martinfelis for working on this!

We've been testing the change in the :dev branch for a week now and it seems to not cause any issues for us. I'll merge to :main today and keep an eye on any upcoming issues. Anybody who wants to test this can do so using the PUID and PGID env variables.