I want a Docker container which has a storage volume which is inaccessible by the host machine.
I have followed this guide, which uses the docker-lvm-plugin
plugin to mount a LUKS crypt volume. With some amendments to the approach I ended up doing this:
apt install lvm2
apt install xfsprogs
pvcreate /dev/sdb
vgcreate docker /dev/sdb
lvcreate -L 15G -T docker/internal
lvcreate -L 30G -T docker/volumes
mkdir -p /var/run/key
mount -t ramfs -o size=4M ramfs /var/run/key
dd if=/dev/urandom of=/var/run/key/key.bin bs=1024 count=16
apt install cryptsetup
docker volume create --driver lvm --name cryptvol --opt size=100M --opt crypt=luks --opt keyfile=/var/run/key/key.bin
docker run -d --name container -v cryptvol:/home alpine tail -f /dev/null
However I can then do this:
$ docker exec -it container sh -c 'echo hello > /home/hello.txt'
$ # hello.txt is readable inside container
$ docker exec -it container -c 'cat /home/hello.txt'
hello
$ # hello.txt ALSO readable outside container
$ cat /var/lib/docker-lvm-plugin/cryptvol/hello.txt
hello
It seems the contents of the crypt volume are visible to the host machine.
Is it possible to have an encrypted volume inside a Docker container that is inaccessible by the host?
No.
Docker is not traditionally a VM tool. Instead it runs an application with isolation (namespaces) and resource limits (cgroups) applied. The host processes, running on the same kernel, do not run with these limits, and can therefore see the contents of the container. And even if limited from view somehow on the host, root on the host (along with any user in the docker group) can enter the namespace of the container.
With a VM, you would at least have a separate kernel running in a separate memory space. Compromising it would require an attacker to inspect or compromise the hypervisor, the VM kernel or applications, or reverse engineer the contents of the memory.
For organizations that really want to harden access on an untrusted host, the direction they are looking today is Trusted Execution Environments that use encryption keys burned into the CPU to ensure the processes outside of the TEE cannot access or inspect the content being processed.