Maintaining the kernel's web of trust
Some history
As recently as 2011, there was no mechanism in place to verify the provenance of pull requests sent to kernel maintainers. If an emailed request looked legitimate, and the proposed code changes appeared to make sense, then the requested pull would generally be performed. That degree of openness makes for a low-friction development experience, but it also leaves the project open to at least a couple types of attacks. Email is easy to forge; an attacker could easily create an email that appeared to be from a known maintainer, but which requested a pull from a malicious repository.
The risk grows greater if an attacker somehow finds a way to modify a maintainer's repository (on kernel.org or elsewhere); then the malicious code would be coming from a trusted location. The chances of a forged pull request from a legitimate (but compromised) repository being acted on are discouragingly high.
The compromise of kernel.org in 2011 focused minds on this problem. By all accounts, the attackers had no idea of the importance of the machine they had taken over, so they did not even try to tamper with any of the repositories kept there. But they could have done such a thing. Git can help developers detect and recover from such attacks, but only to an extent. What the community really needs is a way to know that a specific branch or tag proposed for pulling was actually created by the maintainer for the relevant subsystem.
One action that was taken was to transform kernel.org from a machine managed by a small number of kernel developers in their spare time into a carefully thought-out system run by full-time administrators supported by the Linux Foundation. The provision of shell accounts to hundreds of kernel developers was belatedly understood to be something other than the best of ideas, so that is no longer done. No system is immune, but kernel.org has become a much harder target than before, so repositories stored there should be relatively safe.
The other thing that was done, though, was the establishment of a web of trust based on public-key encryption with GnuPG. When a subsystem maintainer readies a branch for pushing to a higher-level maintainer, they should apply a signed tag to the topmost commit. The receiving maintainer can then verify the signature and be sure that the series of commits they are pulling is what the maintainer had in mind. As can be seen from this article, not all maintainers are using signed tags, but their use has been growing over time. Adoption has been slowed a bit because Linus Torvalds does not require signed tags for pulls from kernel.org repositories.
A signed tag by itself does not mean much; the other half of the problem is that the pulling maintainer must be able to verify that the key used to sign that tag actually belongs to the developer it claims to. That is where the web of trust comes in. If Torvalds can be convinced that a given key belongs to a specific subsystem maintainer, he can sign that key; other maintainers can then trust that the key is as advertised (as long as they trust Torvalds, anyway). In the kernel community, all roads lead to Torvalds, but he does not have to personally sign every maintainer's key; as long as there is a path of trusted signatures leading to him, a key will be trusted within the community.
The kernel's web of trust was bootstrapped in a painful key-signing session at the 2011 Kernel Summit; thereafter, new developers have had to convince others to sign their keys at conferences or other gatherings. Until recently, PGP key servers were used to hold keys and any signatures attached to them. A given maintainer's key could be easily fetched and, if the signature chain checked out, trusted. The attacks on the signature mechanism, including the attachment of thousands of bogus signatures to public keys, have taken the key servers out of the picture, though, leaving the community without a way to maintain its web of trust.
pgpkeys.git
Konstantin Ryabitsev, the lead administrator for kernel.org, has stepped into this void. After investigating a number of key-server alternatives, he concluded that none of them were fit for the purpose; the code is unmaintained and there is little interest in the development of web-of-trust systems in general at this point. So the alternatives are to give up on the web of trust as well or to come up with a new solution. Dropping the web of trust is not an appealing option:
So Ryabitsev has created a new Git repository to hold keys for kernel developers. It has been populated with keys used in pull requests in the past, along with the signatures on those keys. But, to avoid signature attacks, only signatures made with other keys stored in the repository are retained; that is sufficient to build the web of trust while eliminating the results of any signature spamming that might have taken place. There is also a set of SVG files showing how each key fits into the web of trust; to take a random example:
There is also, naturally, a way to make updates to this repository. Keys can be sent to an email address; after verification, they will be added to (or updated in) the repository. Finally, there is a script that can be used to automatically load all of the keys in this repository into one's personal GnuPG keyring. By running this script periodically, any developer can keep a copy of the entire kernel web of trust at hand.
To some, this may seem like a rearguard action aimed at propping up the
web-of-trust concept when that idea is generally falling out of favor. It
may well be true that the web of trust, as originally conceived with PGP
many years ago, cannot scale to the Internet as a whole. It can still
work, though, for relatively small communities, as the Debian project (for
example) has shown for years. A Git repository full of keys will not solve
the world's authentication problems, but it may well prove sufficient for
the task of keeping kernel pull requests secure.
Index entries for this article | |
---|---|
Kernel | Security/Patch verification |
Security | Encryption/Key management |
Posted Sep 4, 2019 14:31 UTC (Wed)
by pabs (subscriber, #43278)
[Link] (1 responses)
Posted Sep 4, 2019 15:04 UTC (Wed)
by mricon (subscriber, #59252)
[Link]
Posted Sep 4, 2019 14:32 UTC (Wed)
by gwolf (subscriber, #14632)
[Link] (3 responses)
Posted Sep 4, 2019 15:21 UTC (Wed)
by mricon (subscriber, #59252)
[Link] (2 responses)
I *have* considered running a non-connected SKS instance, but at this point in time everyone seems to consider SKS as pretty much dead -- it's not maintained and nobody is willing to step up or so much as touch it due to any number of reasons (largely, because OCaml is just too esoteric). There were some discussions with Hagrid folks about introducing limited support for preserving third-party signatures, but it is not a priority for the project at this time, while we needed something more immediate. I am quite happy to learn from how other projects are doing it, but my goal was to come up with something that offers maximum transparency with minimal decision-making. Providing key data via a git repository was well-received by the maintainers, so that is what we ended up doing.
Posted Sep 5, 2019 8:54 UTC (Thu)
by nilsmeyer (guest, #122604)
[Link]
Posted Sep 6, 2019 18:18 UTC (Fri)
by anarcat (subscriber, #66354)
[Link]
https://salsa.debian.org/debian-keyring/website/blob/mast...
searching is not implemented, but you can fetch keys from the keyserver directly as well, through the lookup endpoint:
https://salsa.debian.org/debian-keyring/website/blob/mast...
That's basically the simplest possible implementation of HKP that you could come up with when you have a static keyring like this. It's pretty useful because you don't need to teach your users about pull requests or whatever weird process to submit key updates: they just do `gpg --keyserver keys.debian.org --send-keys FOO` and their new signatures show up on the keyring maintainer's queue.
What happens after, of course, is more magic: the keyring maintainers have a bunch of scripts to maintain those keyrings and check/import those keys, in the debian-keyring package:
https://salsa.debian.org/debian-keyring/keyring/tree/mast...
It works, but as someone who has to maintain keyrings elsewhere as well, I don't like that we are all reinventing the wheel on the side. I wish there was a better way to do *safe* operations on keyrings.
For example, I'd love if there was a command that would take a key fingerprint, and allow only "reasonable" updates to the associated OpenPGP certificate, where "reasonable" is:
1. key expiry updates
... and that might not be exhaustive. The way it works for debian-keyring now is that you need to manually look at the diff in the output of "gpg --list-packets" or "pgpdump" or "gpg --show-keys" and remember all your RFC4880 by heart to make sure everything is good. That is so error-prone I think it's actually dangerous...
But then again, it's one of *many* areas where we need to work much harder on the OpenPGP interfaces.
I think managing the keyring in a git repo is a good idea for the Linux kernel, that said: it matches other tools that already exist for linux and provides an auditable (and possibly signed!) trail of changes to the various keys. I do think it would be nice to standardize the tooling a little better, and I think the above tools might make your life easier...
Best of luck with the keyring maintenance!
Posted Sep 4, 2019 15:03 UTC (Wed)
by unixbhaskar (guest, #44758)
[Link]
Posted Sep 5, 2019 6:18 UTC (Thu)
by weberm (guest, #131630)
[Link] (14 responses)
Huh? Still scratching my head. If we cannot trust kernel.org, why should we trust kernel.org? In the end all roads lead back to the site, which isn't even trusted by Konstantin...
I must be missing something trivial, please fill in.
Posted Sep 5, 2019 8:54 UTC (Thu)
by nilsmeyer (guest, #122604)
[Link] (1 responses)
Posted Sep 5, 2019 9:12 UTC (Thu)
by weberm (guest, #131630)
[Link]
There's new data coming in from kernel.org and you have a new signature from a new contributor. How do you establish that you trust them? Your local copy doesn't help.
There is no trustworthy information authority, IMO, aside from, say Konstantin's local git repo copy (if he is the person to extend the git repo with new signatures). It's kind of a circular argument IMO once you involve kernel.org.
Posted Sep 5, 2019 9:56 UTC (Thu)
by grawity (subscriber, #80596)
[Link] (3 responses)
* The replacement solution is to add a repository on kernel.org.
As I understand it, the repository isn't a replacement for web-of-trust; it only acts as a key storage (similar to GnuPG's WKD) but regular WoT is still used to ensure their validity.
Posted Sep 5, 2019 10:44 UTC (Thu)
by weberm (guest, #131630)
[Link] (2 responses)
Posted Sep 5, 2019 10:58 UTC (Thu)
by farnz (subscriber, #17727)
[Link]
The idea, AIUI, of this repository, is that you use it to track from keys you trust for reasons outside kernel.org (e.g. because you met Linus and verified his key in person) to keys that you don't trust. While an attacker can replace the keys and the signature chains, they can't forge the roots of your personal web of trust because they do not have access to people's private keys, and without that, they cannot forge a signature from a key you trust due to external comms to a key under their control.
Posted Sep 5, 2019 21:20 UTC (Thu)
by Cyberax (✭ supporter ✭, #52523)
[Link]
Posted Sep 5, 2019 13:16 UTC (Thu)
by corbet (editor, #1)
[Link] (7 responses)
Posted Sep 5, 2019 13:52 UTC (Thu)
by weberm (guest, #131630)
[Link] (6 responses)
I still must be missing something so brutally obvious to you folks. Probably ... knowledge. Thanks for bearing with me.
Posted Sep 5, 2019 14:17 UTC (Thu)
by weberm (guest, #131630)
[Link] (3 responses)
Posted Sep 5, 2019 14:32 UTC (Thu)
by farnz (subscriber, #17727)
[Link]
This is the gotcha built-in to all trust systems - you need some form of external verification to ensure that you have a valid root of trust. In a web-of-trust system, that means that you need external validation of one of the keys in the web which you can then use to get to a point where you're confident that you trust all the people in the web. In a trusted third party system (like X.509), you need root CAs that you implicitly trust.
For this system, the goal is that you get a key for Linus, or Dave Miller, or AKPM, or Corbet, or someone else in the kernel WoT from them via another route (perhaps a page on lwn.net?). You can then use that to validate the keys for the entire repo, and can raise the alarm if a forged WoT repo contains the "wrong" key for your root of trust. Similar can happen if (e.g.) Linus discovers that he can't find a path from his key to the publicly known key for (say) Alan Cox - he knows that path should exist, but "Linus Torvalds" in the WoT repo is not the same key as his own key, and he can raise the alarm instead.
Posted Sep 5, 2019 18:35 UTC (Thu)
by naptastic (guest, #60139)
[Link] (1 responses)
It's not that the keys are being stored somewhere else, it's that they're being stored differently. Instead of being files on a key server, they are part of the repository itself. In order to successfully replace a legitimate key with a malicious one, you would have to compromise and alter every copy of the Linux git repository checked out anywhere. If the "canonical" git tree hosted on kernel.org gets tampered with, there are thousands of developers with pristine git histories who would immediately know something was wrong, and what to do about it.
Posted Sep 5, 2019 19:10 UTC (Thu)
by naptastic (guest, #60139)
[Link]
Posted Sep 5, 2019 14:27 UTC (Thu)
by corbet (editor, #1)
[Link] (1 responses)
The situation is no different than the public keyservers we had before, where anybody could upload a key claiming to belong to anybody. But those keys lacked the requisite signatures and would not be trusted.
Posted Sep 5, 2019 14:43 UTC (Thu)
by weberm (guest, #131630)
[Link]
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
We run a curated hkps server (*not* connected to the HKP pool), where people can directly send their updated key material, and the keyring-maint team will verify them (we have verified them for over a decade before the attacks were published ☺). And, yes, we do mirror the curated keyrings on a publicly accessible Git tree (https://salsa.debian.org/debian-keyring/keyring) and even package it in case you find it interesting (https://tracker.debian.org/pkg/debian-keyring)
I know Debian has many oddities (some would plainly call them "bureaucracy" or such) that make it very different from what happens in the kernel development. But we (keyring-maint) would be happy to interact with the kernel people (I guess it would mean Konstantin Ryabitsev) to give each other advice regarding our workflows.
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
2. new subkeys
3. revocations
4. third-party signatures from keys already present elsewhere in the keyring
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
* We have the problem that we cannot trust repositories on kernel.org
* So the solution is to sign, and pull in external verification of the signatures from keyservers before merging.
* This solution then dies given the attack on keyservers.
* The replacement solution is to add a repository on kernel.org.
* This is then used to determine the trust of potentially untrustworthy repositories on kernel.org
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
At some point in time Tx you get the initial clone, how do you know that T_attack is not < Tx ?
-> You gotta talk to someone else, not kernel.org
-> You gotta talk to someone else, not kernel.org
Maintaining the kernel's web of trust
* This is then used to determine the trust of potentially untrustworthy repositories on kernel.orgMaintaining the kernel's web of trust
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
You don't need to trust that repo, you just need to trust Linus's key; everything else leads back to that.
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Now if another user wants to verify the integrity of their fresh clone of linux from kernel.org, and if their source of the keys and the chains is also kernel.org, and they did not have a local trust anchor ... I guess I have to RTFM :shrug:
Developers, of course, will have their local cache, but even developers lose machines, and backups, and there may be points in time where they have to re-establish their own anchors.
It just seems fishy to me to store the thing you're securing and the thing you're securing it with on the same, potentially hostile infrastructure.
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust
Linus's public key is pretty well known at this point and, as far as we know, only he controls it. That is the key that you mark as trusted in your own keyring; it need not come from the pgpkeys.git repo. Any keys that are in that repo that are signed by Linus's key should be trustable, since only he could have done that. We know that he trusts those keys, anyway. And so continues the chain.
Maintaining the kernel's web of trust
Maintaining the kernel's web of trust