AAA: Authentication, Authorization, and Accounting
A good way to become accustomed to using the Terminal is to just use it. Ideally for as much of your normal tool-chain as you can. In this article I will document how to use the Linux Terminal to download an Ubuntu OS image from Canonical and then check it’s SHA256 checksum to ensure it is authentic.
One thing that we all should do is verify that the images we are pulling from Canonical, Red Hat, Suse, Fedora, etc., are legitimately the images we think they are and not the image a hacker wants us to use? Well, looking for the lock symbol next to the URL at the top of the browser is a good start. But what if you don’t have access to a browser? Maybe you are on an instance in the cloud or on a headless Raspberry Pi and you realize you need a clean image so you don’t have access to a GUI!
In order to verify that the image we have is signed the correct author. In this case this is The Ubuntu Project. So we need the GPG public key for The Ubuntu Project and a signed list of checksums for the operating system images and other downloadable content that Canonical makes.
All the tools we need are present in the default install image of Ubuntu(other distributions will likely have these tools by default as well, but YMMV). We specifically need gpg
and sha256sum
. GPG is used to do the cryptographic math that verifies ownership of documents using a signature, and SHA256SUM creates a checksum from of the image we want to use that we are then going to verify against an authenticated list of such checksums.
This is a little complicated, so I will recap all the moving parts here:
We have three inputs.
- a list containing the checksums of authentic images (SHA256SUMS)
- the cryptographic signature file for the new list of checksums (SHA256SUMS.gpg)
- the image who’s authenticity we need to verify (as I write this ‘ubuntu-20.04-desktop-amd64.iso‘)
We need three tools.
wget
downloads a file from a website given a fully qualified URLgpg
does all the cryptographic math to check a signature file against a file that is supposed to be signedsha256sum
will create a checksum from a target file
The order of operation is as follows:
- Download the file we need to authenticate
wget "https://releases.ubuntu.com/20.04/ubuntu-20.04-desktop-amd64.iso"
- Download the current list of checksums for all authentic images
wget "https://releases.ubuntu.com/20.04/SHA256SUMS"
- Download the current PGP signature of the author the file
wget "https://releases.ubuntu.com/20.04/SHA256SUMS"
- Check the signature against the list
gpg --keyid-format long --verify SHA256SUMS.gpg SHA256SUMS
NOTE: the name of the key used to sign is buried inside the signature file. If gpg
does not know that key it will tell you via an error like this:
gpg: Signature made Thu 23 Apr 2020 06:46:21 AM PDT gpg: using RSA key D94AA3F0EFE21092 gpg: Can't check signature: No public key
We then need to install the required key from the keyserver of the author. This is actually the part where we can be more sure that the signature is really from who we think it is from. Because we are going to go the actual server belonging to the author and ask for the key in question. The error told us the key name. In this case it is D94AA3F0EFE21092.
- Ask the keyserver for the required key
gpg --keyid-format long --keyserver hkp://keyserver.ubuntu.com --recv-keys 0xD94AA3F0EFE21092
Hopefully you will get a response that looks like this:
gpg: key D94AA3F0EFE21092: public key "Ubuntu CD Image Automatic Signing Key (2012) cdimage@ubuntu.com" imported gpg: Total number processed: 1 gpg: imported: 1
This tells me that a key with the requested name was found on the right website and was imported to the crypto system in my computer. If you want to look into the key we just got to visually inspect the fields you can do so with:
gpg --keyid-format long --list-keys --with-fingerprint 0xD94AA3F0EFE21092
To continue with the procedure:
Therefore I can now verify that key and file. So, once more:
- Check the signature against the list
gpg --keyid-format long --verify SHA256SUMS.gpg SHA256SUMS
I got the following when I tried to verify the signature against the checksum list file:
gpg: Signature made Thu 23 Apr 2020 06:46:21 AM PDT gpg: using RSA key D94AA3F0EFE21092 gpg: Good signature from "Ubuntu CD Image Automatic Signing Key (2012) cdimage@ubuntu.com" [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: 8439 38DF 228D 22F7 B374 2BC0 D94A A3F0 EFE2 1092
You can pretty safely ignore that warning. It is because this key is not certified by any body in our list of trusted sources of truth. We know that we typed in the right address, for the key from keyserver.ubuntu.com but what if our request was misdirected to another source via tampering with DNS servers, or an actual website hack that altered the file on their server?
These two occurrences are pretty rare but they do occur. However if this signature included a ‘cosign’ reference to another certified body that was a trusted source of truth then we could almost totally ignore the possibility of DNS tampering or the webserver being hijacked in such a way as to allow arbitrary files being uploaded and then served because we trust the cosigner 100%.
Remember though that we still have not verified the original OS image we downloaded is authentic! We just verified that the list of hashes of the authentic images is itself legit. Therefore the hashes are legit. So we need to check the hash of the OS image file. We will ask sha256sum to look through the SHA256SUMS file and verify the checksums in it against other files in the same directory.
- Ask sha256sum to look at the SHA256SUMS file and verify the checksums in it against other files in the same directory.
sha256sum -c SHA256SUMS
In my case I got the following in response
ubuntu-20.04-desktop-amd64.iso: OK ubuntu-20.04-live-server-amd64.iso: OK
Earlier, before I started this blog, I had downloaded the live-server image in order to practice with KVM. Notice that above where we downloaded files we never changed our current directory so all the files we downloaded were placed into the same folder. So just now when we ran sha256sum against the hash list it was able to find the OS image to hash against the hash in the list.
Had I been trying to verify the hash of a file in some other directory than the one the hash list is in, I’d have had to tell sha256sum where to look for them with a FQN.
If you have any questions about what I did here, let me know in the comments section!