Giving the user inside a container permission on a device - linux

I have a container that's based on the matspfeiffer/flutter image. I'm trying to forward some of my devices present on my host to the container so eventually I can run an android emulator from inside it.
I'm providing the following options to the docker run command:
--device /dev/kvm
--device /dev/dri:/dev/dri
-v /tmp/.X11-unix:/tmp/.X11-unix
-e DISPLAY
This renders the /dev/kvm device accessible from within the container.
However, the permissions for the /dev/kvm device on my host are the following:
crw-rw----+ 1 root kvm 10, 232 oct. 5 19:12 /dev/kvm
So from within the container I'm unable to interact with the device properly because of insufficient permissions.
My best shot at fixing the issue so far has been to alter the permissions of the device on my host machine like so:
sudo chmod 777 /dev/klm
It fixes the issue but it goes without saying that it is not in any case an appropriate solution.
I was wondering if there was a way to grant the container permission to interact with that specific device without altering the permissions on my host.
I am open to giving --privileged access to my host to my container.
I also wish to be able to create files from within the container without the permissions being messed up (I was once root inside a Docker container which made it so every file I would create in a shared volume from within the container inaccessible from my host).
For reference, I'm using VS Code remote containers to build and run the container so the complete docker run command as provided by VS Code is the following
docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/home/diego/Code/Epitech/B5/redditech,target=/workspaces/redditech --mount type=volume,src=vscode,dst=/vscode -l vsch.local.folder=/home/diego/Code/Epitech/B5/redditech -l vsch.quality=stable -l vsch.remote.devPort=0 --device /dev/kvm --device /dev/dri:/dev/dri -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY --fifheri --entrypoint /bin/sh vsc-redditech-850ec704cd6ff6a7a247e31da931a3fb-uid -c echo Container started

Related

`/var/run/docker.sock` is _sometimes_ owned by `nobody:nogroup` when mounted into a JupyterHub container

I have performed the following experiment on two Docker hosts, "Host A" and "Host B": pulled a certain JupyterHub image, started it with /var/run/docker.sock mounted, then exec-ed into the running container and checked the ownership/permissions of /var/run/docker.sock inside the container. Details:
docker pull jupyterhub/jupyterhub:1.3
docker run -d --name jhub -v /var/run/docker.sock:/var/run/docker.sock jupyterhub/jupyterhub:1.3
docker exec -it jhub /bin/bash
Now in the container: ls -l /var/run/docker.sock
On "Host A" I get something unexpected:
srw-rw---- 1 nobody nogroup 0 Jun 24 08:22 /var/run/docker.sock
whereas on "Host B" I get what I should:
srw-rw---- 1 root 998 0 May 27 12:30 /var/run/docker.sock
(note that the GID 998 is the docker group ID on the host, so this is OK). It does not matter whether I explicitly mount /var/run/docker.sock read-write or read-only.
Both "Host A" and "Host B"...
...run Ubuntu 20.04.2 LTS,
...have Docker version 20.10.6, build 370c289 installed,
...the /var/run/docker.sock socket is owned by root:docker on both hosts as it should,
...the JupyterHub image is exactly the same, ID=c9d26511309a,
...the containers' users are root so there's no reason to map docker.sock to the nobody:nogroup user in one of them.
The only difference is that "Host A" is an Azure VM and "Host B" is a physical machine. I set up both and installed Docker on them exactly the same way (or so I think), carefully following the instructions on the Docker website.
Why this matters? Because I get "Permission denied" errors if I try and spawn a notebook container from the JupyterHub container on "Host A" (the Azure VM). The DockerSpawner class needs to access /var/run/docker.sock and if it's not owned by root it can't perform its job.
Diligent Googling turned up several discussions on having a similar problem in a Jenkins container but the solutions offered usually revolve around adding a user to the docker group which does not apply to my case. Help is therefore desperately needed :-) Thanks.
Update:
After a complete uninstall/purge and reinstall cycle the problem disappeared, as it so often happens.... :-(
I don't know if this solves your problem, but in my case I found that docker is running "rootless". You can check by docker info, under Security Options Therefore instead of mounting /var/run/docker.sock apparently I need to mount /run/user/$USERID/docker.sock
docker run --rm -it -v /run/user/1118/docker.sock:/var/run/docker.sock docker sh
So in your case,
docker pull jupyterhub/jupyterhub:1.3
docker run -d --name jhub -v /run/user/"$(id -u)"/docker.sock:/var/run/docker.sock jupyterhub/jupyterhub:1.3
docker exec -it jhub /bin/bash

Docker Access to Raspberry Pi GPIO Pins --privileged does not work

I know similar question had already been answered, and I studied dilligently.
I believe, I have tried nearly all possible combinations, without success:
sudo docker run --device /dev/ttyAMA0:/dev/ttyAMA0 --device /dev/mem:/dev/mem --device /dev/gpiomem:/dev/gpiomem --privileged my_image_name /bin/bash
I have also refered to the docker manual and tried also with --cap-add=SYS_ADMIN
sudo docker run --cap-add=SYS_ADMIN --device /dev/ttyAMA0:/dev/ttyAMA0 --device /dev/mem:/dev/mem --device /dev/gpiomem:/dev/gpiomem --privileged my_image_name /bin/bash
I also tried combintions with volumes: -v /sys:/sys
But I still get failed access to devices, due to Permission denied:
I have checked that those devices possibly needed exist and I can read them:
I am wasted. What am I still doing wrong ? Is it that I must run my app inside container as root ? How in the world ? :D
You're running commands in the container as appuser, while the device files are owned by root with various group permissions and no world access (crw-rw--- and crw-r-----). Those groups may look off because /etc/groups inside the container won't match the host, and what passes through to the container is the uid/gid, not the user/group name. The app itself appears to expect you are running as root and even suggests sudo. That sudo is not on the docker command itself (though you may need that if your user on the host is not a member of the docker group) but on the process started inside the container:
docker run --user root --privileged my_image_name /bin/bash
Realize that this is very insecure, so make sure you trust the process inside the container as if it was running as root on the host outside of the container, because it has all the same access.

Mount volume to docker to which sudo does not have access

I am trying to mount a volume into docker on a compute cluster running ubuntu 18.04. This volume is on a mounted filesystem to which my user has access, but sudo does not. I do have sudo permissions on this cluster. I use this command:
docker run -it --mount type=bind,source="$(pwd)"/logs,target=/workspace/logs tmp:latest bash
The result is this error:
docker: Error response from daemon: invalid mount config for type "bind": stat /home/logs: permission denied.
See 'docker run --help'.
Mounting the volume works fine on my local machine where both sudo and I have access to the drive I want to mount, which makes me believe that the problem is indeed that on the server sudo does not have permissions to the drive I want to mount into docker.
What I have tried:
running the post-install steps $ sudo groupadd docker && sudo usermod -aG docker $USER
running docker with sudo
running docker with --privileged
running docker with --user $(id -u):$(id -g)
setting the user inside the dockerfile with USER $(id -u):$(id -g) (plugging in the actual values)
Is there a way to mount the volume in this setup or to change the dockerfile to correctly access the drive with my personal user? Any help would be much appreciated.
On a sidenote, within docker I would only require readaccess to the volume in case that changes anything.
The container is created by the Docker daemon, which runs as root. That's why it still doesn't work even if you run the container or the docker command as your own user.
You might be able to run the daemon as your own user (rootless mode).
You could also look at changing the mount options (on the host system) so that the root user on the host does have access. How to do this depends on the type of filesystem.

Docker run - User group not working as expected?

I have a script that communicates over serial port (/dev/ttyUSB0). I want to run it from within a Docker image. However I don't seem to have permissions to do it from within the image. I follow these steps:
On my host, if I run ln -l /dev/ttyUSB0 I get:
crw-rw---- 1 root dialout 188, 0 jul 2 14:34 /dev/ttyUSB0
Good, it means that in order to read/write to it, I need to be either root, or part of the dialout group.
I become member of this group in my host:
$ sudo usermod -aG dialout $(whoami)
Then I log out and log in again to make this effective.
After that, I verify that I can communicate perfectly with /dev/ttyUSB0 from my host. However if I run the docker image:
docker run --user=1000:1000 --rm=true --tty=true --privileged=true --device=/dev/ttyUSB0 --volume=<my_dir>:<my_dir> --workdir=<my_dir> <my_docker_image> <my_script>
Then it complains:
can't open device "/dev/ttyUSB0": Permission denied
However if I use: --user=1000:20, then it works fine. The group 20 is the dialout group.
Now my question:
Why does Docker not understand that my user (1000) and group (1000) is part of the dialout group?
This was working when I used the old docker (apt-get install docker-io, docker-engine), but after updating to the new Docker CE this stopped working.
Setup:
Ubuntu 16.04.2 LTS Kernel 4.4.0-83-generic.
Docker version: Docker version 17.06.0-ce, build 02c1d87.
Thanks!
As stated in a comment, The solution was to pass --group-add=dialout to the docker run call. However, be aware that when using docker images that provides a way to specify the user and group using an environment variable (usually -e PUID=<UID> -e PGID=<GID>) it overwrites that setting.

Why does docker container prompt "Permission denied"?

I use following command to run a docker container, and map a directory from host(/root/database) to container(/tmp/install/database):
# docker run -it --name oracle_install -v /root/database:/tmp/install/database bofm/oracle12c:preinstall bash
But in container, I find I can't use ls to list contents in /tmp/install/database/ though I am root and have all privileges:
[root#77eb235aceac /]# cd /tmp/install/database/
[root#77eb235aceac database]# ls
ls: cannot open directory .: Permission denied
[root#77eb235aceac database]# id
uid=0(root) gid=0(root) groups=0(root)
[root#77eb235aceac database]# cd ..
[root#77eb235aceac install]# ls -alt
......
drwxr-xr-x. 7 root root 4096 Jul 7 2014 database
I check /root/database in host, and all things seem OK:
[root#localhost ~]# ls -lt
......
drwxr-xr-x. 7 root root 4096 Jul 7 2014 database
Why does docker container prompt "Permission denied"?
Update:
The root cause is related to SELinux. Actually, I met similar issue last year.
A permission denied within a container for a shared directory could be due to the fact that this shared directory is stored on a device. By default containers cannot access any devices. Adding the option $docker run --privileged allows the container to access all devices and performs Kernel calls. This is not considered as secure.
A cleaner way to share device is to use the option docker run --device=/dev/sdb (if /dev/sdb is the device you want to share).
From the man page:
--device=[]
Add a host device to the container (e.g. --device=/dev/sdc:/dev/xvdc:rwm)
--privileged=true|false
Give extended privileges to this container. The default is false.
By default, Docker containers are “unprivileged” (=false) and cannot, for example, run a Docker daemon inside the Docker container. This is because by default a container is not allowed to access any devices. A “privileged” container is given access to all devices.
When the operator executes docker run --privileged, Docker will enable access to all devices on the host as well as set some configuration in AppArmor to allow the container nearly all the same access to the host as processes running outside of a container on the host.
I had a similar issue when sharing an nfs mount point as a volume using docker-compose. I was able to resolve the issue with:
docker-compose up --force-recreate
Eventhough you found the issue, this may help someone else.
Another reason is a mismatch with the UID/GID. This often shows up as being able to modify a mount as root but not as the containers user
You can set the UID, so for an ubuntu container running as ubuntu you may need to append :uid=1000 (check with id -u) or set the UID locally depending on your use case.
uid=value and gid=value
Set the owner and group of the files in the filesystem (default: uid=gid=0)
There is a good blog about it here with this tmpfs example
docker run \
--rm \
--read-only \
--tmpfs=/var/run/prosody:uid=100 \
-it learning/tmpfs
http://www.dendeer.com/post/docker-tmpfs/
I got answer from a comment under: Why does docker container prompt Permission denied?
man docker-run gives the proper answer:
Labeling systems like SELinux require that proper labels are placed on volume content mounted into a container. Without a label, the security system might prevent the processes running
inside the container from using the content. By default, Docker does not change the labels set by the OS.
To change a label in the container context, you can add either of two suffixes :z or :Z to the volume mount. These suffixes tell Docker to relabel file objects on the shared volumes. The z option tells Docker that two containers share the volume content. As a result, Docker labels the content with a shared content label. Shared volume labels allow all containers to
read/write content. The Z option tells Docker to label the content with a private unshared label. Only the current container can use a private volume.
For example:
docker run -it --name oracle_install -v /root/database:/tmp/install/database:z ...
So I was trying to run a C file using Python os.system in the container but the I was getting the same error my fix was while creating the image add this line RUN chmod -R 777 app it worked for me

Resources