6

for documentation purposes on our project I am looking for the following information:

We are using Docker to deploy various applications which require entropy for SSL/TLS and other stuff. These applications may use /dev/random, /dev/random, getrandom(2), etc.. I would like to know how these requests are handled in Docker containers as opposed to one virtual machine running all services (and accessing one shared entropy source).

So far I have (cursorily) looked into libcontainer and runC. Unfortunately I have not found any answers to my question, although I do have a gut feeling that these requests are passed through to the equivalent call on the host.

Can you lead me to any documentation supporting this claim, or did I get it wrong and these requests are actually handled differently?

Thomas
  • 63
  • 1
  • 7

1 Answers1

6

A docker container is "chroot on steroids". Anyway, the kernel is the same between all docker containers and the host system. So all the kernel calls share the same kernel.

So we can do on our host (in any folder, as root):

mknod -m 444 urandom_host c 1 9

and in some linux chroot:

wget <alpine chroot> | tar -x <some folder>
chroot <some folder>
mknod -m 444 urandom_in_chroot c 1 9

and we can do

docker run -ti --rm alpine sh -l
mknod -m 444 urandom_in_docker c 1 9

Then all calls open(2) and read(2) by any program to any urandom_in_docker and urandom_in_chroot and urandom_host will go into the same kernel into the same kernel urandom module binded to special character file with major number 1 and minor number 9, which is according to this list the random number generator.

As for virtual machine, the kernel is different (if there is any kernel at all). So all the calls to any block/special character files are translated by different kernel (also maybe using different, virtualized architecture and different set of instructions). From the host the virtualmachine is visible as a single process (implementation depended) which may/or may not call the hosts /dev/urandom if the virtualized system/program calls /dev/urandom. In virtualization anything can happen, and that is dependent on particular implementation.

So, the requests to /dev/urandom in docker are handled the same way as on the host machine. As how urandom is handled in kernel, maybe here is a good start.

If you require entropy, be sure to use and install haveged.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    I think this answered would be better if you clearly stated if the chroot used the host's `/dev/random` and `/dev/urandom` (and friends). I find the `urandom_host` thing confusing at best. What is that demonstrating? – jww Oct 08 '18 at 10:16
  • Maybe your're right. I wanted to show, that the path and filename does not matter. Docker daemon recreates the /dev structure using mknod calls. The thing that matters is file type, minor and major number. I thought once you get that, you will see that the `/dev/urandom` file is just a special way of communicating your intention with the kernel. As the kernel is the same, such intention is parsed by the same entity/same kernel. – KamilCuk Oct 08 '18 at 10:25
  • Thanks for your detailed answer! So you say that `/dev/(u)random` from a Docker container is treated equally by the kernel as a request on the host. Can you point me to any documentation describing this behaviour? – Thomas Oct 08 '18 at 12:02
  • 2
    No. And I don't think you will find everything in any documentation. I think the best would be to go through libcontainerd source and see if it intercept and how it intercepts the calls to /dev/urandom. I say that it doesn't. Inspecting `strace -f dockerd` and then calling `strace -f docker run alpine` yields on my OS the line: `mknodat(AT_FDCWD, "/var/lib/docker/overlay2/f bla bla/merged/dev/urandom", S_IFCHR|0666, makedev(1, 9)) = 0`. The urandom is created the same way as on host. – KamilCuk Oct 08 '18 at 12:47