How to use GnuPG inside Docker containers, as it i

2020-06-12 03:04发布

问题:

I need to dockerize an apt repository. The packages in it need to be signed, which is currently done by aptly publish snapshot -distribution="stable" -gpg-key="<key id>" my-snapshot

Before that a key needs to be created using gpg --gen-key.

But this way the private key will be crated inside the docker image, which doesn't seem to be a good practice. Besides, id doesn't even work; running gpg --gen-key --batch <gpg.in gets stuck:

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 284 more bytes)

I don't know if it's even possible to generate a gpg key inside a docker container, and even if it is, it may not be a good idea.

Is there a way to sign the contents of the repo by an external key?

回答1:

Missing Entropy

Docker does not provide a virtual /dev/[u]random devices. If you haven't got enough entropy in the container, you haven't got enough entropy on the host.

Check the contents of /proc/sys/kernel/random/entropy_avail, they should be pretty much the same on both the Docker host and container (if the number is slightly different, it just changes very frequently, otherwise recheck a few times).

Possible reasons:

  • Running the docker host in a virtual machine, for example because of boot2docker or a self-constructed virtual machine. Just make sure to get more entropy inside your virtual machine, havegd is a very easy solution for a developer machine, but might not be appropriate for production.
  • Another container/application is using up all entropy. Realize which one and interrupt/terminate it, or generate more entropy.
  • You're generally not having enough entropy. Do some work (mouse/keyboard movements, (hard) disk I/O).

Externally Generating a Key Pair

Anyway, it might be more reasonable to generate a key on a real machine, and only move a (private) subkey to the server. This way, you can exchange the subkey every now and then (and in case it was compromised). Read What is a good general purpose GnuPG key setup? for an introduction to different things to consider while setting up OpenPGP keys.

While building the Docker image, use COPY to get the file into the machine, and then gpg --import it in the Dockerfile. Afterwards, it is available exactly the same way it would've been if you generated it inside the container using gpg --gen-key.



回答2:

I managed to speed the entropy generation greatly by pinging some websites while connected to the docker container where the gpg key was being generated.

$ docker exec -it blimp_mailpilekermit_1 bash
mailpile@mailpile-kermit:~$ ping google.com &
mailpile@mailpile-kermit:~$ ping cloudfleet.io &
mailpile@mailpile-kermit:~$ cat /proc/sys/kernel/random/entropy_avail
757

This got the gpg process to finish generating a 2048 bit key relatively quickly.



回答3:

Generate the key outside of docker build, inside the same directory tree as your Dockerfile. Then you can ADD the key to the image and it'll be available to aptly. Remember that this image now contains a private GPG key, so it needs to be kept just as private as you would that key.

If you want to use the key inside a running container (rather than while building an image), use the -v flag to mount the key file inside the image. (This allows you to publish your image without publishing your private key.



回答4:

Flood pinging the external interface (from another host) will also add entropy to the pool.

eg. ping -f $EXTERNALIP

Need to be root, and best not to do this across a network you care about.