I am trying to understand the functioning of docker well enough to come to reasonable confidence I am using it securely. One advice for this is to always use a USER
statement in a Dockerfile. In trying to understand the effect of this I run into some trouble.
Concrete questions:
testuser
but doesn't allow the ls
when in the directory?testuser
?Version information at the bottom of this question.
I have the following Dockerfile
FROM alpine@sha256:1354db23ff5478120c980eca1611a51c9f2b88b61f24283ee8200bf9a54f2e5c
LABEL version 2.0
LABEL description "Test image for setting user"
RUN adduser -D testuser1 ## sometimes removed
RUN adduser -D testuser2 ## sometimes removed
RUN adduser -D testuser
USER testuser
CMD sh
I build this with
docker build -t kasterma/testuser:1 .
Then run with
docker run -ti -v /home/kasterma/test-user/:/test-home kasterma/testuser:1
The directory /home/kasterma/test-user/
is the directory that contains the Dockerfile.
##sometimes removed
in the Dockerfile.[root@datalocal01 test-user]# docker run -ti -v /home/kasterma/test-user/:/test-home kasterma/testuser:1
/ $ ls -lh
...
drwx------ 2 1001 1001 40 Dec 30 14:08 test-home
...
Here is shows user and group both as being 1001; which is the user and groupid of kasterma
in the host. In this context testuser
has uid and gid 1000.
Also
/ $ cd test-home
sh: cd: can't cd to test-home
##sometimes removed
in the Dockerfile./ $ ls -lh
...
drwx------ 2 testuser testuser 40 Dec 30 14:12 test-home
...
and
/ $ cd test-home
/test-home $ ls
ls: can't open '.': Permission denied
Now testuser
and kasterma
have the same uid and gid (though the one has them in the container, and the other on the host). Why can I cd
, but not ls
?
##sometimes removed
in the Dockerfile./ $ ls -lh
...
drwx------ 2 testuser testuser 40 Dec 30 14:15 test-home
...
and
/ $ cd test-home
sh: cd: can't cd to test-home
Now testuser
has uid and gid 1002, so not the same as kasterma
. But the listing shows it as testuser, but the cd
command fails.
the OS version (running on a VM in VirtualBox)
[root@datalocal01 test-user]# uname -a
Linux datalocal01 3.10.0-514.2.2.el7.x86_64 #1 SMP Tue Dec 6 23:06:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
and for docker
[root@datalocal01 test-user]# docker version
Client:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-59.el7.centos.x86_64
Go version: go1.6.3
Git commit: 3999ccb-unsupported
Built: Thu Dec 15 17:24:43 2016
OS/Arch: linux/amd64
Server:
Version: 1.10.3
API version: 1.22
Package version: docker-common-1.10.3-59.el7.centos.x86_64
Go version: go1.6.3
Git commit: 3999ccb-unsupported
Built: Thu Dec 15 17:24:43 2016
OS/Arch: linux/amd64
When the host is running SELinux it's possible you can't access the file system content if it isn't labeled. From man docker-run
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.
So, instead of disabling SELinux you could try
docker run -ti -v /home/kasterma/test-user/:/test-home:Z kasterma/testuser:1
See Using Volumes with Docker can Cause Problems with SELinux for more details.
I tried your use cases on my box (without SELinux and having Docker version 1.12.5): I always get the right "testuser" ownership and I'm able to change directory and list its content (my local uid is 1000 and I haven't more users above it). So, may be your problem is due to the older Docker version.
If not related to SELinux neither old Docker version, the behavior you described seems related to User Namespaces.
Check if your host's kernel enables User Namespace (CentOS 7, that seems the distro you are using, doesn't enable it by default.
Look at Using User Namespaces on Docker that describes how to enable User namespaces on CentOS 7 and how to check the correct behavior.
About User Namespace details, look at several sites like:
Introduction to User Namespaces in Docker Engine
Docker Security
User namespaces have arrived in Docker!
Docker for your users - Introducing user namespace
You can find a clear description about permissions in Docker volumes before introduction of User Namespaces (before Docker 1.10) at Deni Bertovic blog - Handling Permissions with Docker Volumes.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With