Verifying downloaded files using their PGP/ASC signatures in Docker

So far when I had been downloading source tarballs in my Dockerfiles I wasn’t verifying the signature. Today I decided to fix that.

Most tarbarlls give an .asc file along with it which is a PGP signature of the file (.asc stands for ASCII Armor – it is the text representation of a binary signature, and you can open it in any text editor to see the contents). To verify that though you need to also add the public key of the signer.

So the first step is to find the public key of the signer and import it into your GPG keyring. Here’s what I do. Let’s take the example of ISC’s Kea DHCP server. I downloaded it and the signature file to a machine which has GnuPG installed and try to verify it thus:

I run the gpg command with the --verify switch. The first argument to this is the .asc file, the second is the file whose signature I want to verify against the one in the .asc file.

This errors as you can see because I don’t have the public key of the signer in my keyring. Sometimes you can get the public key from the website where you downloaded the file but if that’s not the case what you need to do is note the RSA key in the output above and go search for it on a public keyserver such as https://keyserver.ubuntu.com. Put in the key as 0x<what you found above> and search. In my case I got the following:

This purports to be from someone with an @isc.org email address so is probably genuine, but there’s no guarantee. If the website gives a the key ID or a key you can download, stick with that. In the case of ISC they have a helpful document which does both and gives you instructions too, so I know the above key is valid.

I can import this public key into my keyring now:

And now the verification succeeds:

To verify this using a tool like grep its best to use the --status-fd switch. This outputs the status to the file description we specify (use 1 for STDOUT).

The warnings can be discarded by piping STDOUT to /dev/null. Thus something like the following can be used to silently confirm the signature:

When buiding from a Dockerfile I want it to fail if the key doesn’t match. Good thing is, if you send a non-zero exit code during a RUN command the build process exits.  So all I need to do is exit if the output of the grep in the previous command is non-zero.

Here’s what I do in my Dockerfile now: