Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run Docker container as non-root user #476

Open
robflate opened this issue Sep 13, 2024 · 6 comments
Open

Run Docker container as non-root user #476

robflate opened this issue Sep 13, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@robflate
Copy link

robflate commented Sep 13, 2024

Is your feature request related to a problem? Please describe.

I'm running Backrest in Docker. When it writes new files in bind mounts /data, /config, /cache, /repos, all files are owned by root. When restoring files, Backrest creates a folder with the original file inside. The original file retains its correct owner/permissions but the folder Backrest places the backup in is owned by root.

Describe the solution you'd like

  • Map my host user to a user inside the container with environment variables PUID and PGID so bind mounts (/data, /config, /cache, /repos) have the same owner as my host.
  • Run Backups on files/folders in /userdata regardless of USER:GROUP and permissions. This would need to run as root or by giving the mapped user elevated permissions (--privileged, --cap-add, etc ??).
  • Respect original file owner/permissions when restoring files regardless of USER:GROUP and permissions. This is currently the case but it would be good if the folder Backrest makes to write the restored file to is owned by the mapped user.
  • Run commands inside the container that require elevated privileges (e.g. docker <container-name> stop) without getting permission denied. Either run as root or add the mapped user to the Docker group inside the container or by giving the mapped user elevated privileges.

It's common for a container to have an entrypoint.sh script that includes something like;

PUID=${PUID:-1000}
PGID=${PGID:-1000}

USER=abc
GROUP=abc

if [ "$PUID" == "" -o "$PUID" == "0" ]; then
	USER=root
	GROUP=root
elif ! $(id abc&>/dev/null); then
	groupadd -g $PGID $USER
	useradd -m -u $PUID -g $GROUP $USER
fi

Additional context

Ultimately, most containers don't need to run as root but something like a backup tool is different. There will very often be situations where you're backing up files not owned by a specific user or with restrictive permissions. However, maybe there are lots of things the container can just run as non-root? It feels safe to assume that /data, /config, /cache, /repos should be owned by the host user (PUID:PGID) and not root. Also, any services that don't need to run as root, shouldn't. On the other hand, access to /userdata would require root access or privileged access unless you could guarantee all files are owned by a specific user (often not the case and would probably lead to user confusion with lots of permission issues).

I lack the knowledge to understand how I can both run the Backrest container as a specific non-root user whilst also letting the container read/write data owned by different users (including root) that may also have restrictive permissions (600). I also don't understand the impact of this on running commands like docker <container-name> stop etc.

Hopefully this is simple without requiring granting any extended capabilities or privileges but I'm afraid that's beyond my understanding.

@robflate robflate added the enhancement New feature or request label Sep 13, 2024
@robflate
Copy link
Author

I've updated by post with additional information. It would be great to hear thoughts on this.

@garethgeorge
Copy link
Owner

garethgeorge commented Sep 16, 2024

Thanks for converting this into an FR and the detailed discussion of what you're trying to get done -- I think it makes sense for Backrest to try to adopt the UID= and GID= env vars convention established by linuxservers.io , we can definitely do something like this in a future release.

This issue might be an easy starter PR if anyone has interest in adding an entrypoint wrapper.

@robflate
Copy link
Author

robflate commented Oct 8, 2024

I found the Restic docs for running full backups without root. They're hidden away in the examples section;

https://github.com/restic/restic/blob/master/doc/080_examples.rst#full-backup-without-root

It suggests adding the extended attribute setcap cap_dac_read_search=+ep to the restic binary. Backrest would still also need to map the local user to the container with UID/GID env vars.

@danktankk
Copy link

has this been implemented yet by chance?

@garethgeorge
Copy link
Owner

It hasn't -- most of the work here is in testing the docker build and validating that permissions work correctly in a variety of contexts.

@awnumar
Copy link

awnumar commented Dec 1, 2024

Just to add some context to this, I believe this is the reason I'm not able to restore any snapshots running the Docker container on Unraid. I get the error

error: restore failed: restore snapshot "...:/backup/shared" for repo ...: command "/bin/nice -n 10 ionice -c 2 -n 7 /bin/restic restore --json ..." failed: exit code 1: restore failed
processing command output: no summary event found
Output:
cannot create target directory: mkdir /backup/shared/.DS_Store-backrest-restore-65d8f743: read-only file system

The mounted /backup folder is owned (on the host) by nobody in the users group (PUID=99, PGID=100)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants