playit-cloud / playit-agent

The playit program
BSD 2-Clause "Simplified" License
257 stars 21 forks source link

Changed entrypoint.sh to run playit not as root and added new env to run playit as root. #94

Closed kevinf100 closed 3 months ago

kevinf100 commented 3 months ago

The changes to entrypoint.sh allows and makes playit not run as root by default. If the user wishes to run playit as root for some reason they can add the env RUN_ROOT = true.
This is achieved by creating a new system user that has no shell or home. A new script usersetup.sh is also added to keep entrypoint.sh cleaner. usersetup.sh will check if the user playit is already made before fully running. The following env are also added and are defaulted to 1000 when not defined.
PLAYIT_UUID allows the user to change the user ID of playit. PLAYIT_GUID allows the user to change the group ID of playit.

loriopatrick commented 3 months ago

Why do we care what user is running inside of the docker container? The container is stateless and only needs host network access. what does this add?

kevinf100 commented 3 months ago

One of the best practices while running Docker Container is to run processes with a non-root user. This is because if a user manages to break out of the application running as root in the container, he may gain root user access on host. In addition, configuring container to user unprivileged is the best way yo prevent privilege escalation attacks.
https://dockerlabs.collabnix.com/security/Running-Containers-as-ROOT.html

Docker containers are not VMs. If somehow a bad actor manages to compromise the container via playit, you don't want them to have root, and it makes it easier for them to escape the container if they are root.
What do you even gain running it as root anyway?

Edit - Another reason. https://www.howtogeek.com/devops/why-processes-in-docker-containers-shouldnt-run-as-root/

Although it can seem like root inside the container is an independent user, it's actually the same as the root account on your host. Separation's only provided by Docker's container isolation mechanisms. There's no strong physical boundary; your container's another process run by the root user on your host's kernel. This means a vulnerability in your application, the Docker runtime, or the Linux kernel could allow attackers to break out of the container and perform root-privileged operations on your machine.

You can see this in htop as well. image

loriopatrick commented 3 months ago

So this is a precaution against an exploit in playit and Linux chroot?

loriopatrick commented 3 months ago

If you want to make a patch to update the Dockerfile to add a new non root user and enter that context before entrypoint I’ll accept that. This is too complicated.

loriopatrick commented 3 months ago

Why not just

user nobody

in the Dockerfile ? Currently no reason for escalated user and these special scripts that don’t have a real purpose is not something I’ll merge.

kevinf100 commented 3 months ago

If you want to make a patch to update the Dockerfile to add a new non root user and enter that context before entrypoint I’ll accept that. This is too complicated.

This can be done. But if you want to allow the user to change the UUID or GUID, they can't use env, but arg instead. The Dockerfile doesn't see any env variables.

Doing it in Dockerfile means, you never allow users to run as root. However I wouldn't be opposed to this. If you want to do that I'll close this and make a new one so we don't pull all this commits in.

So this is a precaution against an exploit in playit and Linux chroot?

Correct. Hopefully playit never has any problems, but you never know or maybe something playit uses has a problem.

loriopatrick commented 3 months ago

👍 let’s make it static in the dockerfile, if we need root in the future we can change.

kevinf100 commented 3 months ago

Done. Can't ever see it needing root. You could always do what you need to do in the Dockerfile. If the user really needs to do something in the container as root, they could always do docker run -it --user root {playit-container} {command} or docker run -it --user root {playit-container} sh