[sf-lug] How to check distro checksums and signatures

Michael Paoli Michael.Paoli at cal.berkeley.edu
Fri Feb 26 08:48:54 PST 2016


Bit more examples, etc.

So, I'll grab the relevant file(s) and data.  This will vary a fair bit
by distribution.  I typically start with the relevant signature and
hash file(s), and any relevant metadata about the ISO I want to
collect.  I often find this more/most convenient, for two reasons.
First of all, if I can't find what I consider some reasonably
sufficient trust path to the ISO, I may not even bother to download it.
Secondly, if I grab the smaller bits and metadata first, that's often
a bit more convenient, as to the extent relevant and feasible, I can
check those before grabbing/assembling the ISO, and also, while I'm not
yet in the process of grabbing/updating the ISO, I'm generally not
pushing the bandwidth on my connection nearly so hard, so latencies are
typically much lower, and speed for getting these smaller files and
bits of metadata is typically fair bit faster at that time (mostly
saves human time, not necessarily overall process time).

Anyway, quite recent example.  Some of these files I'd already
grabbed, so I may not repeat showing all of those steps, but I'll show
the steps to validate the ISO, once one has downloaded/assembled the
ISO, and also has the relevant file(s) and data to validate the ISO.

I'll use fairly typical conventions, with PS1='$ ' for non-superuser
(non-root) users, including mere mortal users (e.g. individual user(s)
login account(s), and PS2='> ' - the latter essentially being a
continuation prompt (shell is prompting for more input to complete
the command).  Sorry if that PS2 doesn't play quite so nice with
some email clients - should be reasonablely clear what's PS2 vs. quoted
text - at least by context.

I'll start with one I just completed updating via zsync:

$ (cd .. && multisum ubuntu-14.04.4-desktop-i386.iso) > multisum.out

Here multisum is a utility I wrote (in Perl) that computes multiple
hashes in a single read pass.  By default it does those that Debian uses
to sign most of its ISOs - Ubuntu generally does 3 of those 4 for most
of their releases.  If one wants to snag a copy of multisum, one can
find it here:
http://www.rawbw.com/~mp/perl/multisum
And there's a bit more information about it here:
http://www.rawbw.com/~mp/perl/
Of course one can use individual utilities to compute the hash(es),
notably:
sha512sum(1)
sha256sum(1)
sha1sum(1)
md5sum(1)
One should generally use the strongest hashes available.
At this point in time, md5 is considered rather weak, and sha1 also
kind'a weak, and sha512 would be the strongest among those 4.
So, if multiple hashes are used with the signing, best to check at least
the strongest.  And generally doesn't hurt to also check additional ones
if those are also provided.

It also possible to use multiple of those individual hash commands in a
single read pass, e.g. via named pipes (I probably show one or more
examples of that somewhere on 'da Interwebs).  I used to do that, but
eventually got tired of doing so, so wrote handy utility to yet more
efficiently do what I wanted anyway.

But I often compute the hashes later, starting first with checking
signatures - at least if that can be done first - which applies in this
case, as the signature files are detached signature files of files
containing secure hashes.

What's a secure hash?  What's a detached signature file? ... etc.
I'm not going to answer all that - it's been answered a few zillion
times or so on 'da Interwebs ... and/or maybe some other(s) will want to
jump in and reexplain those bits.  I'm going to show more of the basic
how.

So, ... showing rechecking of the signature files.  For Ubuntu, we have
a set of secure hash files and corresponding detached signature files:

$ ls -d *SUM*
MD5SUMS           MD5SUMS-metalink.gpg  SHA1SUMS      SHA256SUMS
MD5SUMS-metalink  MD5SUMS.gpg           SHA1SUMS.gpg  SHA256SUMS.gpg
$

The ones with .gpg on the end are the detached signature files,
those without are the secure hash files.

Rather than check each pair one-by one, or just one pair, I check 'em
all at once:

$ (for s in *.gpg; do b=$(basename "$s" .gpg) && 2>&1 gpg --verify \
> "$s" "$b"; done) | sort | uniq -c | sort -bnr
       8 gpg: WARNING: This key is not certified with a trusted signature!
       8 gpg:          There is no indication that the signature  
belongs to the owner.
       4 gpg: please do a --check-trustdb
       4 gpg: Good signature from "Ubuntu CD Image Automatic Signing  
Key <cdimage at ubuntu.com>"
       4 gpg: Good signature from "Ubuntu CD Image Automatic Signing  
Key (2012) <cdimage at ubuntu.com>"
       4 Primary key fingerprint: C598 6B4F 1257 FFA8 6632  CBA7 4618  
1433 FBB7 5451
       4 Primary key fingerprint: 8439 38DF 228D 22F7 B374  2BC0 D94A  
A3F0 EFE2 1092
       2 gpg: Signature made Thu Feb 18 12:15:24 2016 PST using RSA  
key ID EFE21092
       2 gpg: Signature made Thu Feb 18 12:15:24 2016 PST using DSA  
key ID FBB75451
       1 gpg: Signature made Thu Feb 18 12:15:25 2016 PST using RSA  
key ID EFE21092
       1 gpg: Signature made Thu Feb 18 12:15:25 2016 PST using DSA  
key ID FBB75451
       1 gpg: Signature made Thu Feb 18 12:15:23 2016 PST using RSA  
key ID EFE21092
       1 gpg: Signature made Thu Feb 18 12:15:23 2016 PST using DSA  
key ID FBB75451
$

The "WARNING: This key is not certified with a trusted signature!" ...
I'm not particularly concerned about in this case.  It just means I've
not assigned any trust value to that key on my keyring.  The reason I'm
not particularly concerned about that in this case, is I don't
willy-nilly add keys to my keyring.  Generally if I add a key to my
keyring, I generally have at least fairly good reason to believe the
key belongs to who/what the key claims to be.

Likewise I can ignore the "gpg: please do a --check-trustdb" - not
important nor critical for what and how I'm checking presently.

The key bit I'm looking for is "Good signature" - I'm checking 4 pairs
of files, so I expect 4 such "Good signature" results - and from a key
I expect to be signing the ISO.  In this case, I get a bonus, an extra
set of such - so Ubuntu signed each, not with a single key, but with two
keys.  A bit earlier, I didn't have that additional key on my keyring
but I earlier found it and added it, using:

$ gpg --search-keys

... with suitable key identifier also supplied as additional option
argument to that command (I forget which was the one I more newly
added), and found sufficient means/reason to reasonably trust it (in
this case, one of the signatures to the new key was a key already on my
keyring, and also the files were signed with both keys together), so I
accepted adding it to my keyring.

Note also various distributions will have additional ways to help you
validate that the key is in fact appropriate for that distribution.
E.g. they may have package(s) for one's distribution that includes such
key(s).  (Not sure if Ubuntu does that, but Debian definitely does).
If the means of obtaining/updating the software (e.g. signed packages)
is already secure, that can be a convenient way to get the key(s) and be
reasonably well assured they're the proper keys.  Some distributions may
well publicize it on their web page(s) - https would be at least
slightly preferable in such cases, but probably more important is
determining that it's a reasonably well established key for the
distribution - e.g. key has been in use for a fair while by the
distribution (didn't just appear overnight or quite recently by someone
cracking the web pages), or key is signed by such a key (most distributions
will generally sign their newer key(s) with their older keys, to aid in
determining trust relationship in transitioning to newer keys).

So, that check tells me the secure hash files have been suitable signed.
I then just need compare the data in those files to my computed hash of
the ISOs.

$ (for h in $(awk '{print $1;}' multisum.out); do grep -h "^$h " *SUMS
> done)
51b53fa15c0b89948bbaba311d64a962 *ubuntu-14.04.4-desktop-i386.iso
25faa868dafb22fb040707a5dfe865cb8a3d7412 *ubuntu-14.04.4-desktop-i386.iso
8283440880dd2ac4c6d07ee9b8ccf2df57637cb07ebe830ccd9f7b0da9e919b2  
*ubuntu-14.04.4-desktop-i386.iso
$

And there we see 3 of my 4 computed hashes match - which is what I
expect in this case, as Ubuntu only uses 3 of the 4.

At that point have ISO and we've verified it's been effectively signed
(secure hashes signed) by key(s) we expect and sufficiently trust as
appropriate key(s) to be signing such an ISO.

Some other ISO related comments:

To reduce redundant downloading and ease loads on distribution's
sites/mirrors, I generally, where I have somewhat earlier version of
similar ISO, will make reasonable attempts, as available, to update the
earlier version without need to download all the data from the newer
ISO.  To do so, and in my generally preference order, I'll use one of
these mechanisms:
o jigdo
o zsync
o rsync
o bittorrent
The last of those generally doesn't reduce total data I download, but does
generally remove most load burdens from the distribution's servers.

I typically also grab and preserve timestamp data for the ISO.
For http/https, I'll generally use:

$ curl -I

And supplying the URL, and if it's a redirect, I'll generally follow
that as necessary to get an HTTP 200 response, and then note and save the
Last-Modified:
header data.
For FTP, I'll get and use the MDTM, e.g.:

ftp> quote MDTM debian-8.3.0-amd64-i386-netinst.iso
213 20160123222038
ftp>

I've written utilities:
Last-Modified_touch
mdtmtouch
which handily take timestamp data in the Last-Modified: header and MDTM
formats, and use those to suitably set mtime on target file.
Have a peek on:
http://www.rawbw.com/~mp/unix/sh/examples/
if one may be interested in mdtmtouch
I may eventually get around to putting Last-Modified_touch on:
http://www.rawbw.com/~mp/perl/

Good to give back.  I typically seed and upload via bittorrent 1x to 4x
or more of however much data I downloaded to grab or update the ISO
image(s).  Some of the below have just gotten started on the bittorrent
"upload"/seeding, as I just got the images a bit earlier.

   
------------------------------------------------------------------------------
| Filename                                          Size   Download     
  Upload |
| debian-8.3.0-amd64-CD-1.iso                   627.0  M   0    B/s    
0    B/s |
| ^---  download succeeded!                                0.0  M      
1.4  G   |
| debian-8.3.0-amd64-i386-netinst.iso           556.0  M   0    B/s    
0    B/s |
| ^---  download succeeded!                                0.0  M    
346.6  M   |
| debian-8.3.0-i386-CD-1.iso                    647.0  M   0    B/s    
0    B/s |
| ^---  download succeeded!                                0.0  M      
1.3  G   |
...
| ubuntu-14.04.4-desktop-amd64.iso                1.0  G   0    B/s   
15.3  K/s |
| ^---  download succeeded!                                0.0  M     
90.5  M   |
| ubuntu-14.04.4-desktop-i386.iso                 1.0  G   0    B/s   
15.5  K/s |
| ^---  download succeeded!                                0.0  M     
15.4  M   |
| ubuntu-14.04.4-server-amd64.iso               579.0  M   0    B/s   
41    B/s |
| ^---  download succeeded!                                0.0  M    
764.1  M   |

After I've also created at least one backup copy, I then also update my
inventory of ISOs I generally make available (e.g. at [L]UG meetings):
https://www.wiki.balug.org/wiki/doku.php?id=balug:cds_and_images_etc

references:
http://linuxmafia.com/pipermail/sf-lug/2016q1/011729.html
http://linuxmafia.com/pipermail/sf-lug/2016q1/011733.html





More information about the sf-lug mailing list