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
Permission issue with rootless containers #1243
Comments
sounds like podman is doing an non-compliant thing without I'm inclined to close this as wontfix, thoughts? |
No - actually it is quite compliant. Rootless containers map UID zero to
a user namespace UID. This means that’s UID 0 in the container corresponds
to UID of the person running the container. So, if the files are owned by
the same user running the container, then there appears to be no problem.
…On Mon, Dec 16, 2019 at 3:47 PM Anthony Sottile ***@***.***> wrote:
sounds like podman is doing an non-compliant thing
without -u the files become owned by root which isn't really ok
I'm inclined to close this as wontfix, thoughts?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1243?email_source=notifications&email_token=ACNM5MKMHL2HIGFRVI4WJPTQY7SOJA5CNFSM4J3PEU42YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHABIDY#issuecomment-566236175>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNM5MLDWHGNSZXYKJNUZ7LQY7SOJANCNFSM4J3PEU4Q>
.
|
Does pre-commit have a config file, that the library could read, to decide
if it should leave out the “-u” option?
…On Mon, Dec 16, 2019 at 5:13 PM Dan Kolepp ***@***.***> wrote:
No - actually it is quite compliant. Rootless containers map UID zero to
a user namespace UID. This means that’s UID 0 in the container corresponds
to UID of the person running the container. So, if the files are owned by
the same user running the container, then there appears to be no problem.
On Mon, Dec 16, 2019 at 3:47 PM Anthony Sottile ***@***.***>
wrote:
> sounds like podman is doing an non-compliant thing
>
> without -u the files become owned by root which isn't really ok
>
> I'm inclined to close this as wontfix, thoughts?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <#1243?email_source=notifications&email_token=ACNM5MKMHL2HIGFRVI4WJPTQY7SOJA5CNFSM4J3PEU42YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHABIDY#issuecomment-566236175>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ACNM5MLDWHGNSZXYKJNUZ7LQY7SOJANCNFSM4J3PEU4Q>
> .
>
|
Right, that's not how |
What about if the local docker daemon is setup as so: https://docs.docker.com/engine/security/rootless/ Pretty sure the above approach by docker is using the same set of linux kernel features that podman is using. Rootless containers are a must for any one that is security-minded. |
no idea, can you try it and report back? |
Yep - I'll give it go! |
Update: I installed docker 19.03 on Centos 7.7 using the instructions found here: https://docs.docker.com/engine/security/rootless/#prerequiresites This allows the docker daemon to run as a non-root user. This mode allows the docker daemon to be installed in user space, and does not require privileges to install or run the docker daemon, as long as certain prerequisites are satisfied. With this type of install, the exact same issue is observed as with (rootless) podman. |
do you have a suggestion as to how to detect / avoid this then? and would you be willing to submit a PR addressing it? |
I'm happy to submit a PR. Would like some ideas about what is "acceptable" for a contribution. As you say, ideally there is some way to detect rootless vs privileged, and then adjust the associated docker command accordingly. If that's not the case (that there's not an easy way to detect rootless mode), are there other options available? Environment variables? user configuration file for the pre-commit executable itself? |
Update: |
ideally just detect and adjust, if that's not an option this is probably wontfix -- there is currently no configuration and I'd like to keep it that way and perhaps document putting a this does seem like a bug in docker though, |
This is intentional moving forward with containers - that all containers are set to UID 0 inside the container, and the container runtime takes care of security and sandoxing the "root" user of the container. By applying a context, you limit the privileges of the container to the context in which that container is run: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ Also, docker has a similar interface: |
I'm not sure how kubernetes design decisions are "this is how containers are from now on", could you elaborate? I'm afraid you're making unsubstantiated claims or projecting one project's decisions on the entire concept of containers. |
@dkolepp did you have any interest in working on this? |
@asottile - yes I do! I try and find some time to tackle it. |
Hey folks. I stumbled on this today as well. I'm testing an environment with docker configured with namespacing and while finding rootless flag will work for @dkolepp it won't work for the user namespace remapping. It seems that in both events we are trying to undo the There is really no easy way to check for the "right" user to pass to docker, for rootless mode @dkolepp mentioned a possible flag in the docker info, for user namespacing the only thing I found was a reference to Wondering if there is an approach that's the other way, where we don't assume how someone has docker and permissions setup given that there are multiple ways of configuring docker and that things will change. Is there some way we can pass |
Hi, I am also using podman and installed I really would like to contribute on this issue, unfortunately my python development skills are not sufficient to provide an useful PR :(. As a quick fix, I edited the installed file ~/.local/lib/python3.8/site-packages/pre_commit/languages/docker.py
by:
With that very ugly hack I can use docker_image hooks. |
@themr0c does podman-docker just replace/alias the You can contribute adding something like ver_cmd = 'docker', '--version'
if subprocess.check_output(ver_cmd).startswith(b'podman version '):
return () right before try/except block in @asottile FTR this is the difference in the output: $ podman --version
podman version 1.9.0
$ docker --version
Docker version 19.03.8, build afacb8b7f0 |
The
|
Podman supports the In verbose mode the
Indeed:
I will investigate further to find which options would be suitable when using podman. I believe the |
Probably need to add a check whether the current user is not root. Or if they have capabilities to set uid/gid. |
Looking at last comments in containers/podman#6431, my problem is that my user has id 105971, which is greater than the max of 65536, so the |
Does docker has this option as well? I'll try to test, but I will use podman to install an old Fedora to install actual docker into it. That might blow up. |
Not really :/
|
How to detect a rootless container daemon:
Installed a rootless docker with:
Then:
|
A non rootless installation of docker doesn't have the rootless keyword at all, So if the command |
what about: rootless = False
output = subprocess.check_output(('docker', 'system', 'info'), text=True)
for line in output.splitlines():
# rootless docker has "rootless"
# rootless podman has "rootless: true"
if line.strip().startswith('rootless'):
if not 'false' in line:
rootless = True
break |
The complete code would be like that? def get_docker_user() -> Tuple[str, ...]: # pragma: win32 no cover
try:
rootless = False
output = subprocess.check_output(('docker', 'system', 'info'), text=True)
for line in output.splitlines():
# rootless docker has "rootless"
# rootless podman has "rootless: true"
if line.strip().startswith('rootless'):
if not 'false' in line:
rootless = True
break
if not rootless:
return ('-u', f'{os.getuid()}:{os.getgid()}')
except AttributeError:
return () And then it will need a test ... |
I don't understand the AttributeError check. Also, this function can actually return def get_docker_user():
output = subprocess.check_output(('docker', 'system', 'info'), text=True)
for line in output.splitlines():
# rootless docker has "rootless"
# rootless podman has "rootless: true"
if line.strip().startswith('rootless'):
if not 'false' in line:
return () # no -u for rootless
break
return ('-u', f'{os.getuid()}:{os.getgid()}') |
Thank you @hroncok, I take yours :) |
@hroncok the AttributeError check was probably to overcome these errors: https://asottile.visualstudio.com/asottile/_build/results?buildId=3829&view=logs&j=ae542f9d-96d9-59d2-9a06-a2a85a17a811&t=6deecb4d-4f67-5e8d-1829-1f5cd5833176 |
I will need even more help to write a test for the coverage: :/
But let's see first if the implementation is acceptable. |
run-in-node-container is used for javascript "rollup", so the tools running in the container produce files which must be owned by the user on the host. To achieve this, the docker run --user option is used to ensure that the tools in the container are run as host user. However, with rootless mode - apparently in both docker and podman, but I'm using podman - a user namespace is used and users in the container are mapped to a range of users on the host. This means that if we run a command as root in the container, this corresponds to the host user. When we specify --user, this results in a different host user being used. There are apparently two ways of achieving what we want - not using --user so that the commands run as root in the container, which is mapped to the desired host user. Or we can use --userns keep-id which means a 1:1 user mapping is used, and the user specified by --user corresponds to the same user on the host. The former seems more like how you'd typically use this mode. And so we detect rootless mode using "docker system info", and avoid the --user flag in this case. Podman reports "rootless: (true|false)", whereas docker just includes a "rootless" keyword. For more on this, see: https://www.redhat.com/sysadmin/user-flag-rootless-containers https://docs.docker.com/engine/security/rootless pre-commit/pre-commit#1243 pre-commit/pre-commit#1484 (Note: all of the above applies even without SELinux and was tested with "setenforce 0")
Why does pre-commit pass a -u with the current userid to docker_container? |
because things can write and then you'd have to deal with root owned files on the host |
I tried to use a
docker_image
hook on a RHEL7.7 system usingpodman
with thepodman-docker
package installed [This setup allows for rootless containers]. The hook attempts to modify the file, but gets a "permission denied" error. From looking at the source code, I see thatpre-commit
is roughly trying to execute:The hook does try to run, but results in permission error.
If, however, I remove the
-u
option from the source code (locally, languages/docker.py, docker_cmd()), then the hook runs fine:The text was updated successfully, but these errors were encountered: