vn971 / rua

Build tool for Arch Linux providing control, review and jailed build options
GNU General Public License v3.0
424 stars 42 forks source link

Package signing does not work due to security isolation #136

Open yellowsquid opened 3 years ago

yellowsquid commented 3 years ago

I have makepkg configured to sign packages. I expected rua to be able to sign packages it builds.

Command used:

rua install rua

Output:

==> Signing package(s)...
==> WARNING: Failed to sign package file rua-0.17.12-1-x86_64.pkg.tar.zst.
Build failed with exit code 16 in /var/lib/aurutils/.cache/rua/build/rua

This happens when the signing key both does and does not have a passphrase.

vn971 commented 3 years ago

@yellowsquid strange that there are no more logs available. Do you know where the signing key is located at? It is possible (and quite probable) that rua doesn't have access to this part of the filesystem: https://github.com/vn971/rua#safety

I wonder how to easily make makepkg more verbose to explain the reason of the failure.. It doesn't seem to have a --verbose flag that one could pass. Any ideas?

yellowsquid commented 3 years ago

Signing key is in ~/.gnupg/pubring.kbx.

GPG has a --verbose option. I'll try and add it and report my findings.

vn971 commented 3 years ago

@yellowsquid maybe some other files in ~/.gnupg are needed for makepkg signing as well. You can try adding wrap_args+=(--bind-try ~/.gnupg ~/.gnupg) to ~/.config/rua/wrap_args.d , which will effectively give makepkg full access to ~. Or even give the insecure access to everything for testing, wrap_args+=(--bind ~ ~) , and then shrink it to only the required minimum

yellowsquid commented 3 years ago

GPG has a --verbose option. I'll try and add it and report my findings.

I've got a little more output now.

gpg: using pgp trust model
gpg: no default secret key: No secret key
gpg: signing failed: No secret key

It definitely seems that some directories are missing for package signing. In fact, just looking at the man-page for gpg, you find this option:

 --secret-keyring file
              This is an obsolete option and ignored.  All secret keys are stored in the 
              ‘private-keys-v1.d’ directory below the GnuPG home directory.

Looks like the problem can be resolved with the following:

wrap_args+=(--bind-try ~/.gnupg/private-keys-v1.d ~/.gnupg/private-keys-v1.d)
vn971 commented 3 years ago

@yellowsquid it would be nice to solve the problem for other people as well though.

Do you have ideas on how to do that? Alternatives I see so far:

Any thoughts or ideas are welcome

yellowsquid commented 3 years ago
* always allow access to private GPG keys. This sucks security-wise and I won't really use that, mentioning just to see the alternatives

Personally I think that read-only access is sufficient, behind a command-line flag.

I doubt this will be a common issue if I am the first person to report it. In that case, the majority of people will benefit by never exposing the private keys.

For people who do want to sign packages, the private keys should definitely be read-only. When creating keys, GPG gives plenty of warnings if they're not given a passphrase. This means packages should only be exposed to encrypted, read-only private keys, which the user will explicitly opt-in to.

* split the full build into non-signing part that executes arbitrary build-time code of PKGBUILD, and the signing part which only involves `makepkg` and is safe to read the private keys. Maybe it's a bit paranoid, but I'd really like to go security/isolation-first

You can run makepkg with the --nosign flag. Then separately sign the package with gpg. A problem with this approach is parsing makepkg.conf to get the user-specified signing key. It might be possible to run makepkg to only sign the package using the --noxxx options. I couldn't work out how after playing around for 5-10 minutes though.

vn971 commented 3 years ago

@yellowsquid not related to this issue but just a small personal comment: if you want to make those keys read-only, bind them with --ro-bind or --ro-bind-try