Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFE: automatically sign packages on build #2678

Open
pmatilai opened this issue Sep 27, 2023 · 11 comments
Open

RFE: automatically sign packages on build #2678

pmatilai opened this issue Sep 27, 2023 · 11 comments
Labels
crypto Signatures, keys, hashes and their verification handsfree Packaging automation and convenience
Milestone

Comments

@pmatilai
Copy link
Member

pmatilai commented Sep 27, 2023

If we automatically signed all built packages, enabling enforcing signature checking by default (#1573) would be much less of an issue because it would no longer require --nosignature in common use-cases.

The gpg-agent stuff seems ill-suited for builds in non-interactive environments. I think rpm5 did something with keyutils(7), that may be something to look into.

@pmatilai pmatilai added handsfree Packaging automation and convenience crypto Signatures, keys, hashes and their verification labels Sep 27, 2023
@pmatilai pmatilai added this to RPM Sep 27, 2023
@github-project-automation github-project-automation bot moved this to Backlog in RPM Sep 27, 2023
@nwalfield
Copy link
Collaborator

A couple of thoughts:

  • In non-interactive environments, the secret key material should probably not be made available to the build infrastructure. That means exactly something like gpg-agent (a daemon that provides a smartcard like interface) is needed.
  • How does rpm figure out what key to use for signing?

@pmatilai
Copy link
Member Author

pmatilai commented Sep 28, 2023

Yup, rpm used to have --sign option to rpmbuild but I removed it for that very reason: back then it asked for the password at the very beginning of a build and then used it to sign any built packages.

Note that the actual use-case here is essentially to "allow locally built packages to be installed without --nosignature", rather than something distributors would use. That "install freshly built local packages" case exists even inside buildsystems like koji/copr/mock when chain-building that will eventually sign the packages even now. The security requirements for this kind of thing are quite different from your "real" signing keys.

Rpm (currently) uses the key set in %_gpg_name macro, in the form of "whatever gpg will recognize as a key identifier".

Also probably not obvious from this ticket is that we're considering adding some real isolation to how builds run even with plain rpmbuild, which would change the landscape a bit.

@pmatilai
Copy link
Member Author

Oh, and part of the this "automation vision" here would be automatically generating that "local builds" key so that a person just wanting to build and install rpms for their own use basically doesn't need to learn the damnest thing about PGP as the first thing. And not finger-memorize --nosignature as something you normally use (against the background that rpm really, really needs to start requiring signatures by default)

@nwalfield
Copy link
Collaborator

Oh, and part of the this "automation vision" here would be automatically generating that "local builds" key so that a person just wanting to build and install rpms for their own use basically doesn't need to learn the damnest thing about PGP as the first thing. And not finger-memorize --nosignature as something you normally use (against the background that rpm really, really needs to start requiring signatures by default)

Now I understand better, thanks.

For the case where the rpms are only going to be installed locally, it would be enough to have a local, user-specific rpm-specific key that is used for this type of thing. If the key does not exist, then it is first created. When the user wants to install the rpm, they first need to install the local, user-specific key, which could be done by rpmkeys. rpm could even detect that the signature is from a local, user-specific key (perhaps by way of a notation added to the signature), and print a message telling the user how to install the key. What do you think?

@pmatilai
Copy link
Member Author

Yes, something along those lines. From the user POV, ideally one wouldn't even need the manual import (think something like auto-generated host-specific key on first boot), but that's likely too much of a sacrifice from other perspectives.

@nwalfield
Copy link
Collaborator

From the user POV, ideally one wouldn't even need the manual import (think something like auto-generated host-specific key on first boot), but that's likely too much of a sacrifice from other perspectives.

But only root should have access to that key. That's why I was thinking "user-specific". In which case, I think rpm can't automatically import the key safely.

@pmatilai
Copy link
Member Author

But, in this scenario the user is (or rather, has) root anyway, otherwise they wouldn't be able to install their packages in the first place. So it's this funny dance around how to best serve that case without sacrifing other scenarios. User-specific keys are the most obvious route of course, a host-specific key would solve something but be cumbersome/problematic in other ways.
I'm just trying to think outside the box a bit, I don't have any concrete plan here.

@pmatilai
Copy link
Member Author

And yes, because the user is likely root and expected to run rpm/dnf as such, expecting them to run one 'rpmkeys --import' command is not exactly unreasonable. It's largely about finding the right slot(s) to do stuff (such as print meaningful "do this" messages)

@pmatilai pmatilai added this to the 6.0.0 milestone Mar 7, 2024
@pmatilai pmatilai moved this from Backlog to Priority in RPM Sep 3, 2024
@stewartsmith
Copy link

I'll add some context on how we think about / do package signing in Amazon Linux (and for brevity, I'm going to just focus on AL2023 and beyond, and simplify things along the way) which may help inform decisions here.

Builders do not have access to the private signing keys. Nothing does. It's all in KMS. The keys were created in KMS, and nobody has ever seen the private key.

A (one to N instances of) a separate system to Koji works out what it should sign and with what key. This helps with things such as having an external audit log, and a simpler system to do an in-depth security review on. It also makes it impossible for any Koji deployment to accidentally go and do something incredibly undesirable to the keys.

We haven't solved the scratch/local build signing problem, nor currently looked to. If I were to posit or review such a design for us doing it, I'd ensure the following constraints were true:

  1. Anything not a final build in Koji is signed with a different key than what that final build would be signed for if it was queued for release. i.e. there is no way to have a random scratch/mock build to make it into any production system with a valid signature from the production keys.
  2. Keys need to be clearly marked as for test and throwaway builds, and in such a way that it is possible for systems to alarm on any of these builds or keys making their way onto any production system.

In a previous work life, I worked on firmware that had the ability to do secure boot of the firmware stack. So that test keys were obvious, there was a standard set of test keys where the private keys were in the public git repository so that everyone knew what the test keys were.

@pmatilai pmatilai modified the milestones: 6.0.0, 6.0.0 alpha Nov 25, 2024
@pmatilai
Copy link
Member Author

Yup, "industry grade" secure signing is a whole different ballgame. This feature is aimed towards the shallow end of the pool - casual local builders, and driving wholly unsigned packages to extinction in that space. One should keep in mind that the driving force for this change is enabling the enforcing signature check mode by default in rpm: how to keep local builds convenient in that setup without pushing users to --nosignature on everything.

What follows is more or less a braindump of what I've been thinking about, if it seems half mad, I have the excuse of poor nights sleep 😅 Thoughts and comments very welcome, this is all very much subject to change:

  • rpmbuild always signs the packages it builds (unless explicitly disabled by config/cli switch)
  • if a pre-existing key is configured it will use that
  • if no key is configured for signing
    • rpm will create one for you automatically
    • a passwordless sign-only key with something like rpmbuild-${USER}@${HOSTNAME} as the userid/email
    • configure this as the signing key for future builds
    • export the ascii-armored pubkey to a suitable location in home, with a message explaining how to import it to rpm

Of course the "casual local builder" is a somewhat extinct use-case to begin with, mock and such replacing most of the direct rpmbuild uses. The copr/koji/obs etc all manage their own signing, so mock (and similar other tools) are perhaps the bigger question mark in this.

The above logic would presumably create a key per each mock buildroot, I don't know that's sensible. Mock has its own signing plugin too, but you need to specifically configure and enable it. But, it'll merrily use rpm's configured signing key if told to, so one can use the one on the "host" for that. So maybe, the key generation should only occur on interactive (think isatty()) builds. Automated build + install cycles will need some updating anyhow: either they need to import keys, or use --nosignature for installing. Mock configs could default to enable signing plugin by default on rpm >= 6.0 distros.

With all that said, I find myself wondering whether the rpmbuild-level automation is worth it at all. Could we instead maybe ship a helper script that sets it up for you, including creating a key if needed and including mock autosign config if mock is present?

@pmatilai
Copy link
Member Author

  • rpmbuild always signs the packages it builds (unless explicitly disabled by config/cli switch)

On a related note, something @DemiMarie brought up in another ticket: perhaps a signature be actually a mandatory part of a v6 package. That seems like an attractive idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crypto Signatures, keys, hashes and their verification handsfree Packaging automation and convenience
Projects
Status: Priority
Development

No branches or pull requests

3 participants