tianon / gosu

Simple Go-based setuid+setgid+setgroups+exec
Apache License 2.0
4.71k stars 320 forks source link

I am having some issue with gosu #63

Closed quanghnn closed 5 years ago

quanghnn commented 5 years ago

I get this error

failed switching to "root": operation not permitted

When I use command

gosu mysql or gosu root

to edit file in docker-entrypoint.sh

tianon commented 5 years ago

This tool is for switching from root to less privileges -- you want su or sudo.

BooleanType commented 2 weeks ago

I use gosu to switch from user with less privileges to root too. My container is launched as api user (no way to change it), the same user in entrypoint, but in this entrypoint I need to perform some operations like chown or supervisor restarting (which requires root level). When I try to use something instead of gosu, I see "Permission denied" or "Operation not permitted" in my php container log.

Neither su, nor su-exec, nor sudo, nor setpriv is suitable, because all these approaches require root password. Of course, I could write something like RUN echo 'root:Docker!' | chpasswd in Dockerfile, and then pass it in entrypoint, but I'm not sure, that it is better idea, then use gosu for switching to root.

Maybe, I do something wrong, when try to use alternatives like su, but only gosu works like a charm for switching to root! This doesn't work in my entrypoint:

su -c 'chown -R api:api .' root
# or
su-exec root:root bash -c 'chown -R api:api .'
# or
setpriv --reuid 0 --regid 0 --keep-groups bash -c 'chown -R api:api .'

And only this works:

gosu root:root bash -c 'chown -R api:api .'

And yes, I'm a hostage of version 1.13 because it's the last version that allows gosu to be installed with the 'setuid' bit set. If I try to install the latest version without chmod +s /usr/local/bin/gosu;, I get error: failed switching to "root:root": operation not permitted, when my php container is launched.

I'm not very experienced in this all, and see no other solution...

tianon commented 2 weeks ago

The correct solution for that use case is sudo, configured with NOPASSWD: in the configuration.

BooleanType commented 2 weeks ago

@tianon Yes, looks like it works, thanks!

Here is new command in my Dockerfile:

RUN echo 'api ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/api && \
    chmod 440 /etc/sudoers.d/api

And in my entrypoint file I do this:

sudo chown -R api:api .

... instead of this:

gosu root:root bash -c 'chown -R api:api .'

And my question is: with this change I allow my api user to run commands as root without password. Is it really more safe, then using gosu, which is installed with the 'setuid' bit set and which switches api user to root?

tianon commented 2 weeks ago

With that configuration, it's roughly the same (although scoped to JUST your user, not all users), and sudo has other protective measures in it for this use case that gosu does not. For example, you can now adjust that configuration to ONLY allow chown (and even with only the exact parameters you expect to use), and lock it down even further.