Skip to content

How to check the authenticity of files downloaded from XCP mirrors

Samuel VERSCHELDE edited this page Oct 31, 2018 · 7 revisions

Context

When you download something from the internet, there is always a chance that the file you get has been corrupted by the transfer, or worse altered voluntarily by someone with malicious intentions.

So for important files, a good habit is to check the file against a cryptographic hash of the file. Usually the (quite weak) MD5 hash function, or something stronger like SHA256.

But what if someone also modified the hash file?

This is a valid concern: maybe you are downloading from a mirror whose owner you don't trust fully, or maybe the server you are downloading from has been hacked. If someone managed to modify the file you want to download, they probably also modified the hash file too. That's where we need cryptographic signatures. Files can be signed with a private key, and you can use the corresponding public key to check the validity of the signature.

In XCP-ng

Since XCP-ng 7.6, we use GPG to sign:

  • SHA256 sums for installation ISOs
  • SHA256 sums for repository configuration files (xcp-ng-X.Y.repo, downloaded as part of the upgrade process if you choose to use yum to upgrade)
  • Every RPM package. They are automatically checked by rpm on an installed XCP-ng.
  • Repository metadata. They are automatically checked by yum on an installed XCP-ng.

Import the public key

Before you can use our public key to verify the authenticity of a downloaded file, you need to import it.

Download the key

wget https://xcp-ng.org/RPM-GPG-KEY-xcpng

A key is of no use if you can't trust it. So check its fingerprint.

gpg --quiet --with-fingerprint RPM-GPG-KEY-xcpng

Expected output:

pub  2048R/3FD3AC9E 2018-10-03 XCP-ng Key (XCP-ng Official Signing Key) <security@xcp-ng.org>
      Key fingerprint = 34AC 2EB6 8248 FED6 D076  838A CD75 783A 3FD3 AC9E
sub  2048R/2EB0DF19 2018-10-03

Note: if you fear that someone altered this document as part of a sophisticated attack, you can also check that the fingerprint stored in our github repository is the same: https://github.com/xcp-ng/xcp-ng-release/blob/master/RPM-GPG-KEY-xcpng-info.txt (and in case you think someone might have altered the above link, check that the repository does actually belong to the XCP-ng project).

Now import the key with gpg:

gpg --import RPM-GPG-KEY-xcpng

Check a downloaded file

The signature for somefile is stored in somefile.asc. Download both, then:

gpg --verify somefile.asc somefile

Expected output:

# gpg: Signature made Wed 10 Oct 2018 12:50:06 PM CEST using RSA key ID 3FD3AC9E
# gpg: Good signature from "XCP-ng Key (XCP-ng Official Signing Key) <security@xcp-ng.org>"
# 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: 34AC 2EB6 8248 FED6 D076  838A CD75 783A 3FD3 AC9E

Only the date should change depending on the date of signature. Good Signature is what tells us that the verification is successful. The warning is also expected because the signing key itself is not signed and we've not setup a list of trusted sources on the computer, so there's no way for gpg to tell if the key is to be trusted or not.

Check an ISO image

In this example we will first check the authenticity of the SHA256SUMS file, then use it to check the integrity of the ISO image. We'll download xcp-ng-7.6.0.iso, SHA256SUMS and SHA256SUMS.asc from https://updates.xcp-ng.org/isos/7.6/ but you can transpose those steps to a newer ISO.

First: import the GPG key if not done already (see above).

Verify the authenticity of the SHA256SUMS file.

gpg --verify SHA256SUMS.asc SHA256SUMS

Now that we trust the authenticity of the SHA256SUMS file, let's check the integrity of the .iso file.

LC_ALL=C sha256sum -c SHA256SUMS 2>&1 | grep OK

It should display:

xcp-ng-7.6.0.iso: OK

Check a repository (.repo) file

This is exactly the same as for the .iso file above: we provided a SHA256SUMS and a SHA256SUMS.asc file.

First: import the GPG key if not done already. You can follow the steps above, but if you are on an XCP-ng 7.6 or newer, you can take a shortcut because the key file is already on your system: gpg --import /etc/pki/rpm-gpg/RPM-GPG-KEY-xcpng

Example with xcp-ng-7.6.repo:

wget https://updates.xcp-ng.org/7/xcp-ng-7.6.repo -O xcp-ng-7.6.repo
wget https://updates.xcp-ng.org/7/SHA256SUMS -O SHA256SUMS
wget https://updates.xcp-ng.org/7/SHA256SUMS.asc -O SHA256SUMS.asc

Verify the authenticity of the SHA256SUMS file.

gpg --verify SHA256SUMS.asc SHA256SUMS

Now that we trust the authenticity of the SHA256SUMS file, let's check the integrity of the .repo file.

LC_ALL=C sha256sum -c SHA256SUMS 2>&1 | grep OK

It should display:

xcp-ng-7.6.repo: OK

About repository metadata and RPMs

Those are signed with the same key, but you don't need to verify them manually: since XCP-ng 7.6, the key is installed directly on the system and used by yum and rpm each time you update or install packages from the repositories of XCP-ng.

This is defined for each subrepository (xcp-ng-base, xcp-ng-updates, xcp-ng-extras, etc.) by the following variables in /etc/yum.repos.d/xcp-ng.repo:

gpgcheck=1
repo_gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-xcpng
  • gpgcheck=1 means that the signature of every RPM that comes from this repository must be verified. Protects against malicious changes to the RPMs on the mirrors.
  • repo_gpgcheck=1 means that the signature of the repository's repomd.xml must be verified before using the repository. Protects against malicious changes to the repository metadata, such as replacing a recent RPM with an older, security-flawed, signed RPM.
  • gpgkey is the URL to the local file containing the GPG public key used for verifying the signatures.
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.