getmango / Mango

Mango is a self-hosted manga server and web reader
https://getmango.app
MIT License
1.7k stars 120 forks source link

[Feature Request] Docker: root user #243

Open james7132 opened 2 years ago

james7132 commented 2 years ago

Is your feature request related to a problem? Please describe. The current docker image requires operating as the root user. This is a potential security risk if there's a container escape, as it will then have root access on the host machine. This also gives indiscriminate access to all mounted subdirectories, which may not be 100% desirable.

Describe the solution you'd like Support Docker's user parameter, hardcode a non-root user in the Dockerfile, or provide env vars for configuring the which user the container runs as.

hkalexling commented 2 years ago

Docker always runs containers as root and that's not the problem with Mango itself. As far as I know adding user: "1000:1000" to docker-compose.yml should do the trick. Have you tried that?

james7132 commented 2 years ago

You can override this in the Dockerfile by using USER directives, leaving the default user as non-root. This can be any arbitrary user ID, but preferably one that is named and has a home directory inside the container.

Using the user flag or compose field is at odds with the default Mango container configuration which uses /root. To use a non-root user, a home directory for the user needs to be created in the Dockerfile.

NaruZosa commented 2 years ago

This would be a great addition, as it would also prevent downloads from the plugins being created as the root user.

Similar discussion about this feature on another project: https://github.com/ipsingh06/seedsync/issues/10

cecoates commented 2 years ago

Can confirm that adding user: "1000:1000" (or whatever your specific UID/GID is) to the compose file doesn't work.

Mango ends up unable to start and looping this over and over:

Mango - Manga Server and Web Reader. Version 0.25.0

The config file /.config/mango/config.yml does not exist. Dumping the default config there.
Unhandled exception: Unable to create directory: '/.config': Permission denied (File::AccessDeniedError)
  from usr/share/crystal/src/crystal/system/unix/dir.cr:65:13 in 'mkdir_p'
  from usr/share/crystal/src/gc/boehm.cr:110:5 in 'load'
  from Mango/src/config.cr:36:5 in '->'
  from usr/share/crystal/src/primitives.cr:255:3 in 'start_parse'
  from Mango/src/mango.cr:137:1 in '__crystal_main'
  from usr/share/crystal/src/crystal/main.cr:110:5 in 'main'
  from src/env/__libc_start_main.c:94:2 in 'libc_start_main_stage2'
LostOnTheLine commented 1 year ago

This is a potential security risk if there's a container escape, as it will then have root access on the host machine. This also gives indiscriminate access to all mounted subdirectories, which may not be 100% desirable.

Except... That's not how it works... A container is a self-contained environment. That's like saying if you have root access on your computer & someone shares a folder with you you'll have root access because you are a root user... Now if you both had the same root username & password that might be true, but most likely you will still have to enter the username & password of root on the other machine to have root access Imagine the docker like a separate computer that you want to use for a task. It is blank. The DockerFile essentially formats that computer & installs an operating system with the bare minimum for it to do what it's intended to. Once that computer is up it runs what you need, but as soon as it turns off it's back to being as it was formatted in the begining. If you create a Bind Mount you are essentially sharing those locations over the network & the Docker-Compose or Run commands mounts them as local drives in the system. If you create a VOL that's like a USB drive you connect to the computer for it to use.

The docker environment is a completely isolated "Computer" that is connected inside docker on your computer. As far as the mount directories they have the same access for every user within the container. If you mount it as RO in the compose it's read only, if you mount it as RW in the compose it's read/write, The user logged in has no effect on that.

james7132 commented 1 year ago

The docker environment is a completely isolated "Computer" that is connected inside docker on your computer. As far as the mount directories they have the same access for every user within the container. If you mount it as RO in the compose it's read only, if you mount it as RW in the compose it's read/write, The user logged in has no effect on that.

I think you're confusing virtual machines and containers here. Containers do not contain. The fundamental design has not changed significantly since that was published. An OCI container, generally, is in effect a fancy chroot jail on the host system. By sharing the same kernel, container escapes can/have/will expose internal processes without isolation. The use of a container should generally not be treated as a security boundary in the same way that VMs do. There are application kernels with improved isolation capabilities, but that cannot be assumed to always be used.

Container escapes aside, the files written to and read from the volume bind mounts use the same user/group as the user inside the container, and having universal read/write perms, even on a scoped volume bind mount, is not ideal.

LostOnTheLine commented 1 year ago

Can you provide an example of a container being able to access files not inside a mounted directory? I know there can be issues if you mount the wrong point, but I've never heard of a container being able to access /mnt/f/images/ if it has /mnt/f/docker/container/ as a mount point or it being able to access anything that isn't within the mounted directories. If that were such a big problem I cannot believe they would be used so often in so many places.

From my understanding a container only has access to the points that are mounted to it. No different from a computer not being able to access a USB drive if it's not plugged in or a NAS if it isn't on the same network.