Given a container bind mound, i.e. -v <host bind>:<container bind> with the default docker userns remapping, I also had an access denied type of error with the key details being:
mounting "<host bind>" to rootfs at "<container bind>" caused: stat <host bind>: permission denied: unknown.
Clearly docker is attempting to stat <host bind> but lacked permission and the "unknown" account name part is because the docker remapped uid has not entry setup in /etc/passwd.
I resolved my issue by ensuring the parent dir of <host bind> allowed directory execute permission. E.g. in the parent directory of the dir intended for the bind mount:
setfacl -m u:<userns-remap-uid>:X,g:<userns-remap-gid>:X .
Where . is the parent of `./.
See Container with mounts fails to start with --userns-remap=default option #28859.
An often overlooked issue is the meaning of the unix execute permission for a directory, which provides "search" permissions, better explained by as (wikipedia: File-system permissions):
the ability to access file contents and meta-information if its name is known
Most installs with a weaker umask of 0002 won't run into this problem because other has execution rights by default, but I ran a more secure setup where I don't let every account on the system have access to my home dir, and other did not have exec or read. Anyhow, the docker container bind mount code could not stat the host's bind dir source because it lacked permission to get the metadata due to the missing access on the parent folder. Arguably, docker could rather perform bind mounts and then only switch to the remapped uid later on during container init to avoid needing parent dir execute access.
As a larger example, suppose you want to bind mount a dir into a container try this. E.g. given docker-root as the host bind dir:
mkdir /tmp/test-dock-userns-remap
chmod o-rwx /tmp/test-dock-userns-remap
mkdir /tmp/test-dock-userns-remap/docker-root
chmod o-rwx /tmp/test-dock-userns-remap/docker-root
Note, the docker-root parent dir perm bits are 770:
$ cd /tmp/test-dock-userns-remap
$ stat --format='type=%F perm=%A(%a)' .
type=directory perm=drwxrwx---(770)
And with a default setting of "userns-remap": "default" in /etc/docker/daemon.json. Then the following will make docker-root bind mountable and usable by container processes run either as root or a lesser privileged user (e.g. uid 1000 in the container):
# Get the base/root rempped UID and GID
dockremap_root_uid=$(grep dockremap /etc/subuid | cut -d ':' -f 2)
dockremap_root_gid=$(grep dockremap /etc/subgid | cut -d ':' -f 2)
# Calculate the remapped standard normal user
user_uid=1000
user_gid=1000
dockremap_user_uid=$((dockremap_root_uid + user_uid))
dockremap_user_gid=$((dockremap_root_gid + user_gid))
# Ensure the parent dir premits the remapped root UID with rX access or else a mounting rootfs "permission denied: unknown." issue can occur
setfacl --modify "u:$dockremap_root_uid:rX,g:$dockremap_root_gid:X" .
# Set ACL to permit read and/or write access where needed
setfacl --recursive --modify "u:$dockremap_root_uid:rwX,g:$dockremap_root_gid:rwX" ./docker-root
setfacl --recursive --default --modify "u:$dockremap_root_uid:rwX,g:$dockremap_root_gid:rwX" ./docker-root
# Allow non-priv uid 1000 in container to have access
setfacl --recursive --modify "u:$dockremap_user_uid:rwX,g:$dockremap_user_gid:rwX" ./docker-root
setfacl --recursive --default --modify "u:$dockremap_user_uid:rwX,g:$dockremap_user_gid:rwX" ./docker-root
# Ensure own user has access
setfacl --recursive --modify "u:$(id -u):rwX,g:$(id -u):rwX" ./docker-root
setfacl --recursive --default --modify "u:$(id -u):rwX,g:$(id -u):rwX" ./docker-root
# Set ownership to the remapped docker root UID
sudo chown --recursive "$dockremap_root_uid:$dockremap_root_gid" ./docker-root
Note, most people likely want the extended ACL set as a default ACL. This ensures that files created within the directory, either by a host process, or by a container process, will have the same default ACLs propagated.
Once I did something like the above, the following works without error, with the container seeing root access from it's own perspective:
$ sudo docker container run --rm --volume $(pwd)/docker-root:/root alpine sh -c "touch /root/test; stat -c 'name=%n inode=%i user=%U(%u) group=%G(%g) perm=%A(%a)' /root/test"
name=/root/test inode=262164 user=root(0) group=root(0) perm=-rw-rw----(660)
But on the host, the directory was owned by the remapped docker root ID and still accessible under my normal user thanks to extended ACLs:
$ stat -c 'name=%n inode=%i user=%U(%u) group=%G(%g) perm=%A(%a)' docker-root/test
name=docker-root/test inode=262164 user=UNKNOWN(165536) group=UNKNOWN(165536) perm=-rw-rw----(660)
$ getfacl docker-root/test
# file: docker-root/test
# owner: 165536
# group: 165536
user::rw-
user:myuser:rwx #effective:rw-
user:165536:rwx #effective:rw-
user:166536:rwx #effective:rw-
group::rwx #effective:rw-
group:myuser:rwx #effective:rw-
group:165536:rwx #effective:rw-
group:166536:rwx #effective:rw-
mask::rw-
other::---
Which makes sense, given, in my case:
$ grep dockremap /etc/sub{u,g}id
/etc/subuid:dockremap:165536:65536
/etc/subgid:dockremap:165536:65536
And to have remapped users named on the host, create entries in /etc/passwd and /etc/group. E.g.:
if ! getent passwd dockremap-root; then
sudo groupadd --system --gid "$dockremap_root_gid" dockremap-root
sudo useradd --system --no-create-home --home-dir "/var/lib/docker/$dockremap_root_uid.$dockremap_root_gid" --shell /bin/false --uid "$dockremap_root_uid" --gid "$dockremap_root_gid" --comment 'userns remap for docker root' dockremap-root
fi
if ! getent passwd dockremap-user; then
sudo groupadd --system --gid "$dockremap_user_gid" dockremap-user
sudo useradd --system --no-create-home --home-dir "/var/lib/docker/$dockremap_root_uid.$dockremap_root_gid" --shell /bin/false --uid "$dockremap_user_uid" --gid "$dockremap_user_gid" --comment 'userns remap for docker user' dockremap-user
fi
However, the whole point of the docker userns remap is to make the container's accounts not map to any valid account on the OS, so the above could be counterproductive and increase exposure.