#506 Enable Option to Sign Repodata With a Given Key Upon Repo Creation
Opened 7 years ago by rhartman. Modified 2 years ago

As part of the requirements for: https://pagure.io/releng/issue/133 we need pungi to be able to sign the metadata in the repositories it generates. This could happen right after the createrepo phase, but should be optional.


Reading the code, it looks like the createrepo phase is the only one that calls modifyrepo_c, so we could do this at the very end of the createrepo phase.

There are many ways to sign something, so it's complicated for Pungi or any tool that does this.

The simplest way to implement this would be to shell out to GPG2 directly, for example gpg --armor --detach-sig --output repomd.xml.asc repomd.xml

Red Hat's internal signing tool ("rpm-sign") would effectively require each user account that runs Pungi to have permissions on the keyserver. Maybe that's ok? Alternatively, we could delegate to robosignatory, (https://pagure.io/robosignatory/issue/14), but that does mean an extra dependency for Pungi, and that feels like it's just moving the ACL problem.

Note that adding this to pungi would I think break Fedora updates.

In Fedora bodhi gathers information about security updates and adds it into the updatesinfo file in the repository... I fear if pungi signed it, bodhi editing that file would break the signatures.

Oh, thanks Kevin. I see that metadata manipulation with the createrepo_c library now in bodhi/server/metadata.py.

Maybe we could abstract "repo signing" out into a separate Pungi phase or tool that would scan through a compose's repomd.xml files and sign all of them. Bodhi could use that utility after it has made its repomd modifications, and Pungi could also use the same utility before moving onto the ISOs phase etc (where it's harder to modify the artifacts that embed repomd.xml.) In Ceph we use https://github.com/alfredodeza/merfi that works like that.

@ktdreyer what if we moved the ACL check to upload? That is, whenever an RPM is signed by robosigner, a new repomd.xml file is generated and signed. I believe this is how Debian implements this.

@demiobenour The challenge here is that repomd.xml contains cryptographic references to everything else in the Yum repository, see https://dl.fedoraproject.org/pub/fedora/linux/releases/33/Everything/x86_64/os/repodata/repomd.xml . When we change one file anywhere in the repository, the contents of repomd.xml must change. If I'm signing repomd.xml with GPG, I have to re-sign the entire file each time I change anything.

We only know the final contents of that repomd.xml file until all the RPM files are put together ("composed") with Pungi. And Kevin pointed out that Bodhi actually does some post-processing of Pungi's output even after Pungi completes a compose.

It's not really possible to sign "parts" of the repo metadata and then combine those later. On the other hand, RPM signatures are per-RPM, and robosignatory already signs those (the "TagSigner" feature).

As far as Debian or Ubuntu goes, I'm pretty sure they regenerate the entire repo metadata and then GPG-sign that output every time they change any build. It's similar to Yum's repomd.xml, in that Apt reads a top-level "Release" text file that is GPG-signed as "InRelease", and that file has sha256 checksums to everything else in the repo, eg. http://us.archive.ubuntu.com/ubuntu/dists/focal/InRelease

@demiobenour The challenge here is that repomd.xml contains cryptographic references to everything else in the Yum repository, see https://dl.fedoraproject.org/pub/fedora/linux/releases/33/Everything/x86_64/os/repodata/repomd.xml . When we change one file anywhere in the repository, the contents of repomd.xml must change. If I'm signing repomd.xml with GPG, I have to re-sign the entire file each time I change anything.

Yes, that is what I am proposing we do. There have been vulnerabilities in metadata processing before, and I would not at all be surprised if there will be again. So metadata signing is critical for security.

@ktdreyer how much work would be involved in this?

Pungi should not be bound to a particular implementation of signing, nor should it have to deal with it by itself. If the repodata is supposed to be signed, it should be handled by an external system.

Here's how signing works for ostree commits:

  • when the repo is updated, a message is sent
  • this message triggers robosignatory to sign the ostree repo
  • a handler in Pungi waits until the signature appears on the disk

A similar implementation could work for rpm repos as well. Once a repo is created, a message would announce that. This will simultaneously start waiting for the signature. It could send individual messages for each repository.

This would work for Fedora Rawhide (and branched), not for updates.

I've written an initial proof-of-concept here that only supports shelling out to /usr/bin/gpg. I have not tested this yet. There is room to write other backend classes, like for sigul or robosignatory, etc.

https://pagure.io/fork/ktdreyer/pungi/commits/sign-repo-metadata

My idea is to make it work in two ways: A) as a final step in the createrepo phase, or b) as a standalone utility for Bodhi (or anything else) to run after merging updateinfo.xml into repomd.xml.

@ktdreyer Corresponding robosignatory PR made here.

This would work for Fedora Rawhide (and branched), not for updates.

This would work for updates too, provided that the needed changes were made to bodhi.

@ktdreyer Robosignatory PR is now

@demiobenour The challenge here is that repomd.xml contains cryptographic references to everything else in the Yum repository, see https://dl.fedoraproject.org/pub/fedora/linux/releases/33/Everything/x86_64/os/repodata/repomd.xml . When we change one file anywhere in the repository, the contents of repomd.xml must change. If I'm signing repomd.xml with GPG, I have to re-sign the entire file each time I change anything.

To elaborate: this is the very reason that metadata signing provides a security benefit.

Frequent signing will be necessary. It is also not a problem, since the signing process is automated.

There's a difference between how robosignatory#51 signs XML versus what exists for ostree now. In the ostree case Pungi just announces that new commit exists and signing service knows where to find the files and where to put the signature.

XML signing expects to receive the XML in the message directly, and sends the signature in another message.

I'm not sure why what is essentially point-to-point communication is implemented by broadcasting messages on a bus, nor how robosignatory will decide what key to use when all info it has is the data itself. But neither is an issue from Pungi point of view.

To integrate with that, a new executable is needed similar to this one. It needs to activate when createrepo phases finishes, find all repomd.xml files to sign, send each one to message bus, and wait for the signature to be announced.

Login to comment on this ticket.

Metadata