[CentOS-devel] False statement about insecurity made on Wiki

Wed Feb 10 09:20:19 UTC 2021
Peter Meier <peter.meier at immerda.ch>

> From what I can tell, the repo metadata is hashed by sha256 but that
> is not the same a cryptographically signed.
> 
> What are you finding is performing a verification of the repomd.xml
> against the CentOS public key before parsing it with libxml2?

There are two kinds of signatures:

gpg signatures on rpms (option gpgcheck) == verify source and integrity
of the RPM

gpg signatures on yum metadata (option repo_gpgcheck) == verifies the
metadata and thus what you see in the repository.

This verifies that nobody tampered with what has been published and thus
the list of packages you get is what was published.

while the first is enabled
(https://git.centos.org/rpms/centos-release/blob/c8s/f/SOURCES/CentOS-Base.repo
or
https://git.centos.org/rpms/centos-repos/blob/c8/f/SOURCES/CentOS-Linux-BaseOS.repo)
the second is not.

It would also be great to do the second by default, especially since the
mirrorlist keeps being pure http.

More on background:
https://blog.packagecloud.io/eng/2014/11/24/howto-gpg-sign-verify-rpm-packages-yum-repositories/

What is important with http as a pure transport for mirrors is what
Julien pointed out:

Even if you have gpgcheck and repo_gpgcheck enabled and there is a 0day
in libxml2 an active attacker can keep serving you the outdated
repository information and you won't get any updates. But all seems
fine, since you verify signature of both.
If you don't verify metadata (as it is now) an active attacker can even
serve you updated content for all the other packages except for libxml2
and while keeping you thinking that you have your system up2date (since
it runs and installs updates) your system can be kept vulnerable.

If the source from where you are fetching the content is using https and
you are validating the certificate it is much harder (or nearly
impossible) to deliver you an outdated (or tampered) view on the repository.

Now what is the state of how you get your content using dnf:

you fetch the mirrorlist

curl
"http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=AppStream&infra=centos-devel"

=> you get a list of mirrors with their own hostname

and you fetch the current metadata from one of these mirrors.

Since you are redirected to mirrors using their own hostname, they can
likely use LE (or whatever they want) to get a certificate signed by a
well known CA.

And it looks like nearly all of the mirrors I get back do that:

tldr; one does not answer on 443  and one has a certificate not signed
by a well known CA.

# curl -s
"http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=AppStream&infra=centos-devel"
| while read -r repo; do echo -n  "${repo} "; curl -s -o /dev/null
--connect-timeout 2  -I $(echo $repo | sed "s at http://@https://@") &&
echo OK || echo FAILED; done
http://pkg.adfinis.com/centos/8-stream/AppStream/x86_64/os/ OK
http://mirror.init7.net/centos/8-stream/AppStream/x86_64/os/ OK
http://linuxsoft.cern.ch/centos/8-stream/AppStream/x86_64/os/ OK
http://centos.mirror.net-d-sign.de/8-stream/AppStream/x86_64/os/ FAILED
http://artfiles.org/centos.org/8-stream/AppStream/x86_64/os/ OK
http://mirror.infonline.de/centos/8-stream/AppStream/x86_64/os/ OK
http://mirror.netzwerge.de/centos/8-stream/AppStream/x86_64/os/ OK
http://ftp.plusline.net/centos/8-stream/AppStream/x86_64/os/ OK
http://ftp.rz.uni-frankfurt.de/pub/mirrors/centos/8-stream/AppStream/x86_64/os/
FAILED
http://mirror.imt-systems.com/centos/8-stream/AppStream/x86_64/os/ OK

So the hard thing is to get mirrorlist behind https and nagging the few
mirrors not yet arrived in 2021 to enable proper https.

Now if we look at what Fedora does (e.g. for EPEL):

 curl -s
"https://mirrors.fedoraproject.org/metalink?repo=epel-source-8&arch=x86_64&infra=centos-devel"
| grep protocol= | sed 's/.*protocol="\(.*\)" type=.*/\1/' | sort | uniq -c
     64 http
     36 https
     50 rsync

=> there is a reasonable amount of https mirrors out there, but still
quite a lot http - don't know how dnf selects them...

Same picture for Fedora repos, since it's the same infra.

Anyway how it could make work, so that folks could hop into a more
secure delivery is:

1. serve mirrorlist under http (default as by now) & https (new!)
2. server mirrorlist as xml with more metadata per mirror (protocol &
type) as for epel (new!)
3. make it possible that dnf can prefer/enable/disable protocols (new!)

then with CentOS 9 Stream one could switch to

1. have mirrorlist by default over https (http variant still available)
2. enable repo_gpgcheck by default
3. let https be the preferred method for dnf (can be downgraded to http
for folks behind ssl terminating proxies without local mirrors)

However, I guess since things are intervened with Fedora and Fedora also
has:

1. repo_gpgcheck not enabled by default :(
2. a mixed list of http, https and rsync mirrors
3. no way on dnf (afaik) to prefer https

it's probably a good starting point over there.

~pete