Skip to content
This repository has been archived by the owner on Jan 4, 2022. It is now read-only.

[WIP] Check GnuPG signature of CoreOS image #251

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

dongsupark
Copy link
Member

Verify GnuPG signature of downloaded CoreOS image. systemd-nspawn/machinectl doesn't have a functionality of checking downloaded images by GPG signatures. We need to download the image and validate it by ourselves and then import it by machinectl.

Also introduce a command line option --image-gpg-verify for kube-spawn create. This option is set to true by default. Any user who wants to disable gpg verification can set this option to false: --image-gpg-verify=false.

This PR is based on #131 by @nhlfr. First I rebased it on top of master, which needed a bit of work, as the project structure has changed a lot recently. After that I decided to simplify the openpgp logic. Please let me know if anything is wrong. A couple of test results looked good to me.

Supersedes #131
Fixes #107

Michal Rostecki and others added 4 commits December 9, 2017 10:25
systemd-nspawn/machinectl doesn't have a functionality of checking
downloaded images by GPG signatures. We need to download the image
and validate it by ourselves and then import it by machinectl.
Verify GnuPG signature of CoreOS image in a simpler way, based on the
default verification API from golang.org/x/crypto/openpgp.

Also introduce a new API `machinetool.ImportRaw()` to be able to import
a temporary raw image file into systemd-machined.
Introduce a command line option `--image-gpg-verify` for kube-spawn create.
This option is set to true by default. Any user who wants to disable
gpg verification can set this option to false: `--image-gpg-verify=false`.
Copy link
Contributor

@schu schu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To actually verify the integrity of an image, the public key must be verified. As-is, an attacker would need to do extra work (forge a key on the keyserver or MITM the network connection of the user), but she doesn't need to get hold of the private key, which should be the only remaining way.

Better import the public key as a const string into the code base and carefully verify it before. This would let you avoid a good chunk of code (import + export not needed; no need to touch my keyring, see below) plus allows you do actually verify the integrity (image signed by CoreOS).

But most importantly: like this, kube-spawn overwrites my $HOME/.gnupg with a new keyring, since it's run with sudo -E (i.e. $HOME points to /home/user).

So since I haven't looked at the code carefully before testing, this just wiped out my user's GPG keyring and setup and I need to recover it from backup :(

func ensureCoreosVersion() {
if err := checkCoreosVersion(); err != nil {
log.Println(err)
log.Fatalf("You will need to remove the image by 'sudo machinectl remove coreos' then the next run of kube-spawn will download version %s of coreos image automatically.", coreosStableVersion)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to stop here? Can we do the work for the user?

@@ -74,6 +74,11 @@ func Terminate(machine string) error {
return err
}

func ImportRaw(imagePath, imageName string) error {
_, err := machinectl(nil, nil, "--verify=no", "import-raw", imagePath, imageName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is machinectl's --verify not an option for verification?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is machinectl's --verify not an option for verification?

Because systemd only supports special name of GPG key files, which are not supported from CoreOS. AFAIK that was the whole point of writing this code in this place.

Quote from machinectl(1), in the section of pull-tar/pull-raw.

Verification is done via SHA256SUMS and SHA256SUMS.gpg files that need to be made available on the same web server, under the same URL as the .tar file, but with the same web server, under the same URL as the .tar file, but with the last component (the filename) of the URL replaced.

Maybe @nhlfr could give us more background.

// of executing gpg binary.
gpgCmdPath, err := exec.LookPath("gpg")
if err != nil {
gpgCmdPath = "/usr/bin/gpg"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some systems have both gpg and gpg2. Not sure picking /usr/bin/gpg is always right.

@dongsupark
Copy link
Member Author

But most importantly: like this, kube-spawn overwrites my $HOME/.gnupg with a new keyring, since it's run with sudo -E (i.e. $HOME points to /home/user).
So since I haven't looked at the code carefully before testing, this just wiped out my user's GPG keyring and setup and I need to recover it from backup :(

Whoa, sorry about that. :( We need to be able to avoid this case.

@dongsupark dongsupark changed the title Check GnuPG signature of CoreOS image [WIP] Check GnuPG signature of CoreOS image Feb 1, 2018
@dongsupark dongsupark modified the milestones: v0.3.0, v0.4.0 Sep 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants