mviereck / dockerfile-x11docker-deepin

3D desktop deepin from China
MIT License
33 stars 11 forks source link

Can't disable the sudo's password. #20

Closed hongyi-zhao closed 4 years ago

hongyi-zhao commented 4 years ago

I try to disable the password for current user in invoking sudo command but failed. See the following info shown in the deepin container started by x11docker.

werner@X10DAi:~/Desktop$ cat /etc/sudoers.d/nopasswd 
werner ALL=(ALL:ALL) NOPASSWD:ALL

werner@X10DAi:~/Desktop$ stat -c "%a" /etc/sudoers.d/nopasswd 
644
werner@X10DAi:~/Desktop$ sudo -i
[sudo] password for werner: 

The screenshot is shown below:

image

As you can see, I've created the /etc/sudoers.d/nopasswd for the current user, why still I need to input password when running sudo command?

Regards, HY

mviereck commented 4 years ago

x11docker sets up a new /etc/sudoers and /etc/sudoers.d/* will not be used.

Instead, you can allow a passwordless sudo with:

echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\"  > /etc/sudoers"
echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"

Compare https://github.com/mviereck/x11docker/issues/27

(In general, could you please ask general x11docker question in the x11docker repo? In the deepin repo ask questions that directly target x11docker/deepin.)

hongyi-zhao commented 4 years ago

x11docker sets up a new /etc/sudoers and /etc/sudoers.d/* will not be used.

Why is it designed with this working mode? Can I let x11docker work with a normal way which respects the stuff resides in /etc/sudoers.d/ and don't change the default /etc/sudoers?

Instead, you can allow a passwordless sudo with:

echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\"  > /etc/sudoers"
echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"

This will flush the original content in /etc/sudoers. Why not put these settings in files located under /etc/sudoers.d/?

In addition, can I create the corresponding /etc/sudoers.d/nopasswd with Dockerfile during running the docker build command?

BTW, how to set an empty password for sudo via x11docker's option?

Compare mviereck/x11docker#27

(In general, could you please ask general x11docker question in the x11docker repo? In the deepin repo ask questions that directly target x11docker/deepin.)

Thanks for your suggestion. I will adopt it from now on.

mviereck commented 4 years ago

Why is it designed with this working mode?

This is part of the security concept of x11docker.

Can I let x11docker work with a normal way which respects the stuff resides in /etc/sudoers.d/ and don't change the default /etc/sudoers? In addition, can I create the corresponding /etc/sudoers.d/nopasswd with Dockerfile during running the docker build command?

This is possible with --user=RETAIN.

BTW, how to set an empty password for sudo via x11docker's option?

There is no direct option because I discourage passwordless sudo. However, you could execute the two commands with option --runasroot. Example:

x11docker --sudouser --desktop \
  --runasroot 'echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\"  > /etc/sudoers"'  \
  --runasroot 'echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"' \
  x11docker/xfce 

You can make a shortcut of this with option --preset.

hongyi-zhao commented 4 years ago
x11docker --sudouser --desktop \
  --runasroot 'echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\"  > /etc/sudoers"'  \
  --runasroot 'echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"' \
  x11docker/xfce 

You can make a shortcut of this with option --preset.

What content for this example should I use to obtain the predefined options stored in a file named as FILE?

mviereck commented 4 years ago

What content for this example should I use to obtain the predefined options stored in a file named as FILE?

Example:

lauscher@debianlaptop:~/.config/x11docker/preset$ cat nopasswd 
--runasroot 'echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\"  > /etc/sudoers"'  
--runasroot 'echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"' 

Please update x11docker first, just found a parsing bug in --preset. Is fixed now.

Use e.g. as

x11docker --sudouser --preset nopasswd --desktop x11docker/xfce
hongyi-zhao commented 4 years ago

Got it. Thanks for your concrete and clear example. Maybe tings like this should be added to the manual/document. Anyway, it seems to me that x11docker is not so easy to understanding, mastering and using.

hongyi-zhao commented 4 years ago

--runasroot 'echo x11docker | sudo --stdin su -c "echo \"$USER ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers"'
--runasroot 'echo x11docker | sudo --stdin su -c "echo \"root ALL=(ALL) ALL\" >> /etc/sudoers"'

Do you think the above two lines are enough? See for my case, I've the following contents in /etc/sudoers shipped with Ubuntu 20.04:

werner@X10DAi:~$ sudo grep -Ev '^[ ]*(#|$)' /etc/sudoers  
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
root    ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL
mviereck commented 4 years ago

Do you think the above two lines are enough?

They are enough to get it working. Only secure_path might be added because some distros do not provide the sbin pathes for regular users. E.g. an sudo ifconfig could fail because it is stored in /sbin/ifconfig.

mviereck commented 4 years ago

I've made a mistake: With option --runasroot we don't need sudo in the preset commands. So the file should look like:

lauscher@debianlaptop:~/.config/x11docker/preset$ cat nopasswd
--runasroot 'echo "$USER ALL=(ALL) NOPASSWD:ALL"  > /etc/sudoers'  
--runasroot 'echo "root ALL=(ALL) ALL" >> /etc/sudoers'
hongyi-zhao commented 4 years ago

I tried this method, but find that the $USER variable can't be expanded. This can be confirmed, in the container, by checking the content of /etc/sudoers as shown below:

werner@5071d5849c98:~/Desktop$ cat /etc/sudoers 
 ALL=(ALL) NOPASSWD:ALL
root ALL=(ALL) ALL

The content of the preset FILE, i.e., nopasswd, need to be rewritten as below:

--runasroot "echo "\""$USER ALL=(ALL) NOPASSWD:ALL"\""  > /etc/sudoers"  
--runasroot "echo "\""root ALL=(ALL) ALL"\"" >> /etc/sudoers"

Or directly run x11docker with the following command:

$ x11docker --runasroot "cat <<-EOF > /etc/sudoers
$USER ALL=(ALL) NOPASSWD:ALL
root ALL=(ALL) ALL
EOF" --home --share=$HOME/Documents/x11docker --sudouser -c --desktop --init=systemd -- --cap-add=ALL --security-opt seccomp=unconfined -- hongyi-zhao/deepin-wine startdde

But I still don't know how to directly use the here-doc based method in the preset FILE, i.e., nopasswd used for this case.

Regards HY

mviereck commented 4 years ago

I tried this method, but find that the $USER can't be expanded.

Just found this happened if using --init=systemd, variable USER was not set. Without this it worked. I've uploaded a fix yet, now it works with --init=systemd, too.

The content of nopasswd need to be rewritten as below:

This introduces an issue: $USER is resolved on host, not in container. So if you run an image with a different user name, e.g. --user=someoneelse, the entry would be wrong.

But i still don't know how to directly use the here-doc based method in the preset FILE

This is not possible because x11docker removes newlines in the preset file. I did this for convenience and did not thought of possible heredocs. You would have to specify a --runasroot for each line of the file.

hongyi-zhao commented 4 years ago

If we want to add many lines into /etc/sudoers, the here doc based method is more convenient, for example, the following:

x11docker_share=$HOME/x11docker-share
if [ ! -d $x11docker_share ]; then
  mkdir -p $x11docker_share
fi

$ x11docker --runasroot 'cat <<-EOF > /etc/sudoers
#$ sudo grep -Ev '\''^[ ]*(#|$)'\'' /etc/sudoers  
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
root    ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL

$USER ALL=(ALL) NOPASSWD:ALL
EOF' --share=$x11docker_share --sudouser -c --hostdisplay --init=systemd -- --cap-add=ALL --security-opt seccomp=unconfined -- hongyi-zhao/deepin-wine sh -c '/opt/deepinwine/apps/Deepin-WeChat/run.sh; sleep 5; while pgrep WeChat; do sleep 1; done'
mviereck commented 4 years ago

If we want to add many lines into /etc/sudoers, the here doc based method is more convenient,

Yes, of course. But I cannot change the behaviour of option --preset without breaking backwards compatibility.

hongyi-zhao commented 4 years ago

By saying backwards compatibility, do you mean compatible with previous versions of x11docker or docker itself? Anyway, you can set the different behaviors, based on version checking, for the same option, if you want to do so.

mviereck commented 4 years ago

By saying backwards compatibility, do you mean compatible with previous versions of x11docker or docker itself?

I mean previous versions of x11docker.

Anyway, you can set the different behaviors, based on version checking, for the same option, if you want to do so.

It would require a major version bump to 7.0. A heredoc in a preset file is a very special use case that is likely rarely needed. I won't break compatibility for this.