globalcitizen / lxc-gentoo

lxc-gentoo: Linux Containers Gentoo Guest Template Script
http://globalcitizen.github.com/lxc-gentoo
GNU General Public License v3.0
86 stars 32 forks source link

GPG-based signature validation #38

Closed globalcitizen closed 9 years ago

globalcitizen commented 11 years ago

Due to the use of HTTP(S) (from 2012, it is best to treat global SSL infrastructure as essentially globally compromised), we should use GPG-based signature validation as an additional and important step within our deployment process.

globalcitizen commented 11 years ago

Validation process described @ http://www.gentoo.org/doc/en/handbook/handbook-amd64.xml?full=1#book_part1_chap2__chap3

globalcitizen commented 11 years ago

Key IDs provided @ http://www.gentoo.org/proj/en/releng/#doc_chap5

globalcitizen commented 11 years ago

Key IDs from the above (HTTP only) URL must be validated with those listed on the 'subkeys.pgp.net' keyserver.

globalcitizen commented 11 years ago

I have implemented an interim solution elsewhere.

However, I am not going to port it in to the project just yet. Why?

Unfortunately there are bugs with Gentoo's key distribution preventing an optimum solution. These are discussed in my bug report here: https://bugs.gentoo.org/show_bug.cgi?id=453620

People are working on them, and lxc-gentoo will get support when the new solution is available.

specing commented 10 years ago

Should I just push GPG support and let the user deal with it or what?

Afterall, GPG support is better than no GPG support.

globalcitizen commented 10 years ago

What's your proposed solution with respect to the discussions at https://bugs.gentoo.org/show_bug.cgi?id=453620 ?

Hard-coding a keyID is not a good idea.

specing commented 10 years ago

Plain gpg --verify followed by a checksum check

the user should worry about recording the needed keys into the GPG system (what emerge-webrsync does)

specing commented 10 years ago

I've also noticed the automated release signing key is being renewed after expiry under the same keyid, so we could still mention it in the sauce.

globalcitizen commented 10 years ago

Looking at this a little now... expiry issues...

gpg --verify stage3-amd64-hardened+nomultilib-20140904.tar.bz2.DIGESTS.asc
gpg: Signature made Fri Sep  5 03:41:16 2014 CST using RSA key ID 2D182910
gpg: Good signature from "Gentoo Linux Release Engineering (Automated Weekly Release Key) <releng@gentoo.org>"
gpg: Note: This key has expired!
Primary key fingerprint: 13EB BDBE DE7A 1277 5DFD  B1BA BB57 2E0E 2D18 2910
globalcitizen commented 10 years ago

Posted https://bugs.gentoo.org/show_bug.cgi?id=523084

globalcitizen commented 10 years ago

They closed that citing the same manual process bug as outlined in the original issue I linked to above, which is waiting on someone to get LDAP integration finished (could take forever!).

In the mean time, I also posted https://bugs.gentoo.org/show_bug.cgi?id=523086

globalcitizen commented 10 years ago

On balance, since there is no really automated way to parse the right key from the releng page at http://www.gentoo.org/proj/en/releng/ with certainty, I think waiting for the original issue I quoted to be closed is still the correct 'external block' handling of this feature.

specing commented 10 years ago

pub 4096R/2D182910 2009-08-25 [expires: 2015-08-24] uid [ unknown] Gentoo Linux Release Engineering (Automated Weekly Release Key) releng@gentoo.org

When you fetch it again, you get the renewed version.

Look at how emerge-webrsync handles PGP. IMHO we shouldn't be forcing the key upon whoever uses this script.

this is my working draft:

diff --git a/lxc-gentoo b/lxc-gentoo
index c7884e0..fd94729 100755
--- a/lxc-gentoo
+++ b/lxc-gentoo
@@ -484,6 +484,33 @@ set_guest_root_password()
        echo "done."
 }

+verify_image()
+{
+       local digest_file="$1"
+       local image_file_absolute="$2"
+       local image_file="${image_file_absolute##*/}"
+       local image_dir="${image_file_absolute%/*}"
+
+       # verify it
+       command -v gpg > /dev/null \
+               || die 2 "gpg program is not installed, unable to verify digest.\n"
+
+       gpg --verify "$digest_file" \
+               || die 7 "Error: Unable to verify PGP signature!\n"
+
+       # verify sha512 checksum
+       command -v sha512sum > /dev/null \
+               || die 2 "sha512sum program is not installed, unable to verify checksum.\n"
+
+       # eh eh
+       # if there is no OK line we fail. I don't know how else to make sha*sum -c
+       # behave properly. Maybe ditch it and compare checksums directly?
+       (
+               cd "$image_dir" \
+                       && sha512sum -c "$digest_file" 2>/dev/null | grep "$image_file" | grep OK
+       ) || die 7 "Error: Checksum mismatch or other error!\n"
+}
+
 fetch_stage3()
 {
        # base stage3 URL
@@ -523,6 +550,19 @@ fetch_stage3()
                ${WGET} -O "$output_file" "$input_url" \
                        || die 6 "Error: unable to fetch\n"
                printf " => saved to: %s\n" "$output_file"
+
+
+               # Download the signature file
+               printf " => Downloading the signature file\n"
+
+               local input_url="$stage3url/$latest_stage3_subpath.DIGESTS.asc"
+               local digest_file="$output_file.DIGESTS.asc"
+               printf " => %s ...\n" "$input_url"
+
+               wget -O "$digest_file" "$input_url" \
+                       || die 6 "Error: unable to fetch\n"
+
+               printf " => saved to: %s\n" "$digest_file"
        fi

        # used by calling function
@@ -712,6 +752,8 @@ create()
                fi
        fi

+       verify_image "$STAGE3_TARBALL.DIGESTS.asc" "$STAGE3_TARBALL"
+
        # variable is nonzero, try to unpack
        printf "\nUnpacking filesystem from %s to %s ... " "$STAGE3_TARBALL" "$ROOTFS"
        mkdir -p "$ROOTFS"
globalcitizen commented 10 years ago

Without fetching the key this is likely to fail on the vast majority of systems, so I'm not sure it's a good idea to push it right now as a default. It could be pushed as an optional feature though.

Regarding the code, after a quick look only it looks reasonable but to me it makes sense to try to fall back to busybox sha512sum ... if regular sha512sum is not present, since busybox might be present on many systems (particularly Gentoo-family distributions).

specing commented 10 years ago

Again, look at how emerge-webrsync does PGP.

sha512sum is part of Coreutils. If someone uses busybox then sha512sum is probably symlinked to busybox. Doubt anyone hosts virtual machines on those.