So far when I had been downloading source tarballs in my Dockerfile
s 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:
1 2 3 4 |
$ gpg --verify kea-1.8.2.tar.gz.asc kea-1.8.2.tar.gz gpg: Signature made Wed Dec 16 12:21:06 2020 UTC gpg: using RSA key 156890685EA0DF6A1371EF2017CC5DB1F0088407 gpg: Can't check signature: No public key |
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:
1 |
$ gpg --recv-keys 0x156890685EA0DF6A1371EF2017CC5DB1F0088407 |
And now the verification succeeds:
1 2 3 4 5 6 7 8 |
$ gpg --verify kea-1.8.2.tar.gz.asc kea-1.8.2.tar.gz gpg: Signature made Wed Dec 16 12:21:06 2020 UTC gpg: using RSA key 156890685EA0DF6A1371EF2017CC5DB1F0088407 gpg: Good signature from "Internet Systems Consortium, Inc. (Signing key, 2019-2020) <codesign@isc.org>" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: AE3F AC79 6711 EC59 FC00 7AA4 74BB 6B9A 4CBB 3D38 Subkey fingerprint: 1568 9068 5EA0 DF6A 1371 EF20 17CC 5DB1 F008 8407 |
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).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ gpg --status-fd 1 --verify kea-1.8.2.tar.gz.asc kea-1.8.2.tar.gz [GNUPG:] NEWSIG gpg: Signature made Wed Dec 16 12:21:06 2020 UTC gpg: using RSA key 156890685EA0DF6A1371EF2017CC5DB1F0088407 [GNUPG:] KEY_CONSIDERED AE3FAC796711EC59FC007AA474BB6B9A4CBB3D38 0 [GNUPG:] SIG_ID 5bVFGMOyueMB8QxRvTmJGgJfCxI 2020-12-16 1608121266 [GNUPG:] KEY_CONSIDERED AE3FAC796711EC59FC007AA474BB6B9A4CBB3D38 0 [GNUPG:] GOODSIG 17CC5DB1F0088407 Internet Systems Consortium, Inc. (Signing key, 2019-2020) <codesign@isc.org> gpg: Good signature from "Internet Systems Consortium, Inc. (Signing key, 2019-2020) <codesign@isc.org>" [unknown] [GNUPG:] VALIDSIG 156890685EA0DF6A1371EF2017CC5DB1F0088407 2020-12-16 1608121266 0 4 0 1 2 00 AE3FAC796711EC59FC007AA474BB6B9A4CBB3D38 [GNUPG:] KEY_CONSIDERED AE3FAC796711EC59FC007AA474BB6B9A4CBB3D38 0 [GNUPG:] KEY_CONSIDERED AE3FAC796711EC59FC007AA474BB6B9A4CBB3D38 0 [GNUPG:] TRUST_UNDEFINED 0 pgp gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: AE3F AC79 6711 EC59 FC00 7AA4 74BB 6B9A 4CBB 3D38 Subkey fingerprint: 1568 9068 5EA0 DF6A 1371 EF20 17CC 5DB1 F008 8407 |
The warnings can be discarded by piping STDOUT to /dev/null
. Thus something like the following can be used to silently confirm the signature:
1 |
gpg --status-fd 1 --verify kea-1.8.2.tar.gz.asc kea-1.8.2.tar.gz 2>/dev/null | grep -q "GOODSIG 17CC5DB1F0088407" |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ENV KEA_VERSION 1.8.2 RUN apk add gnupg RUN rm -rf /var/cache/apk/* # Download the tarball and signature ADD https://downloads.isc.org/isc/kea/${KEA_VERSION}/kea-${KEA_VERSION}.tar.gz /tmp/ ADD https://downloads.isc.org/isc/kea/${KEA_VERSION}/kea-${KEA_VERSION}.tar.gz.asc /tmp/ # Import ISC's PGP key RUN gpg --recv-keys 0x156890685EA0DF6A1371EF2017CC5DB1F0088407 # Verify the download (exit if it fails) RUN gpg --status-fd 1 --verify /tmp/kea-${KEA_VERSION}.tar.gz.asc /tmp/kea-${KEA_VERSION}.tar.gz 2>/dev/null | grep -q "GOODSIG 17CC5DB1F0088407" \ || exit 1 |