dogecoin / docker

Dogecoin Core on Docker
MIT License
27 stars 18 forks source link

Check gitian signatures in a verification stage #6

Closed patricklodder closed 2 years ago

patricklodder commented 2 years ago

Makes the Dockerfile multi-stage, verifies the binary against dogecoin/gitian.sigs, then builds the final image in a second stage.

Alternative to my proposal in #5 that does everything inside the Dockerfile, making the verification independent from GitHub, improving decentralization but also making the Dockerfile itself much more complex.

AbcSxyZ commented 2 years ago

Nice. I'm doing some research & test related to image portability to understand it more, I will test it after that.

xanimo commented 2 years ago

Looks good! Threw together something similar last night but yours is cleaner :P Will do a test run when I get back home.

patricklodder commented 2 years ago

Depending on the repository organization we will choose, it may need to deal with architecture for the base image using FROM ${ARCH}/ubuntu:bionic.

Yes. For the final stage. I think that for the intermediate verify stage, we should standardize on a stable, recent, actively maintained x86_64 (or old-school amd64 as OCI seems to call it) source image - debian:bullseye(-slim)?

On pgp verification, did you think about the scenario where a release has only new signers ? With the current release process, their key will be only available for the next tag and not for the current one, which may be a scenario where the verification fails.

That would be an epic fail, yes. I think that the public keys should be maintained with the signatures on dogecoin/gitian.sigs rather than with the source code. Let's file an issue on dogecoin/dogecoin and see what people think?

AbcSxyZ commented 2 years ago

I think that the public keys should be maintained with the signatures on dogecoin/gitian.sigs rather than with the source code.

Can make sense if keys are only used to verify gitian build. Looking at keys documentation, it says pgp can be used for git commits, depend on your usage.

patricklodder commented 2 years ago

With the latest release tag not being signed and no one raising that, I doubt people care. But yes, I agree that we could do different things with this. I'll raise it.

xanimo commented 2 years ago

I think that the public keys should be maintained with the signatures on dogecoin/gitian.sigs rather than with the source code.

Can make sense if keys are only used to verify gitian build. Looking at keys documentation, it says pgp can be used for git commits, depend on your usage.

Yeah so if you have gpg set up on your local dev env you can run:

gpg --list-keys --fingerprint #to find your key
git config --global user.signingKey #key...
git config --global commit.gpgSign true
# and then finally either enter manually every time you open a shell or put on last line of your ~/.bashrc:
export GPG_TTY=$(tty)

this will result in the commit showing that green 'verified' as shown here with pats commits (oops realized i didn't have any commits lol): Screenshot from 2021-11-15 15-46-11

:)

xanimo commented 2 years ago

forgot to mention you need to add your gpg key and tick 'verified commits' checkbox in your settings > ssh and gpg keys section in github: Screenshot from 2021-11-15 15-56-45

AbcSxyZ commented 2 years ago

@xanimo This process do not use public keys from contrib/gitian-keys and it's managed by GitHub. I suppose you can check the signature of a commit locally by importing public keys from a repo.

patricklodder commented 2 years ago

I'll rebase this after #14

AbcSxyZ commented 2 years ago

It was something that question me, but is the process of downloading PGP keys to check shasum secure ? If not embedded in the Dockerfile, someone who will get access to GitHub repositories for Dogecoin may be able to add his own key, his own signature and his own corrupted binary no ?

I found the following information in docker images documentation about security:

The Dockerfile should be written to help mitigate interception attacks during build. Our requirements focus on three main objectives: verifying the source, verifying author, and verifying the content; these are respectively accomplished by the following: using https where possible; importing PGP keys with the full fingerprint in the Dockerfile to check signatures; embedding checksums directly in the Dockerfile.

patricklodder commented 2 years ago

someone who will get access to GitHub repositories for Dogecoin may be able to add his own key, his own signature and his own corrupted binary no ?

Someone that maliciously gains access to dogecoin/dogecoin releases will likely also gain access to the Dockerfile here so it cannot be fully mitigated as long as we use GitHub as a source. We can do some pinning in the Dockerfile but that reduces decentralization. Docker standard procedures are built for authoritative software, not so much the kind of decentralized, liberal software releases that we do with Dogecoin.

There are numerous improvements to be made on top of this PR, I suggest we handle those independent from this.

AbcSxyZ commented 2 years ago

Yeah, the Dockerfile would be compromised too, still some potential issues. But hard coding the pgp keys may be something to consider, everything rely on potentially compromised download.

patricklodder commented 2 years ago

But hard coding the pgp keys may be something to consider, everything rely on potentially compromised download.

Pinning the PGP keys of individual developers will give a subset of developers power. This is extremely dangerous for a software that controls billions worth of assets, because no developer should be trusted like that, including you or me. It's more likely that a single person gets compromised than a group. Like I said, this PR should either be rejected or not be blocked by further improvements.

patricklodder commented 2 years ago

Rebased on top of #14, ready for review.

patricklodder commented 2 years ago

What about the previous issue when there are only new signers to a release ?

Then the CI must fail on PR and we solve it if that happens.

In overall, from a security point of view, I'm not sure about the risks of downloading PGP keys to verify files integrity.

I think this meets the most authenticity criteria, given that there is no way (by design) to have an official Dogecoin Core - there is no authority. The only thing you can have is an auditable Dogecoin Core binary, and we store a sample of audit logs in the gitian.sigs repository, so the iteration over multiple published build audits are imho the best we can do. Your or my signature is meaningless on anything else than the code we wrote or a process we ourselves executed.

Besides having this build-time check, we can create a script that shasums the binaries inside the container image at runtime and have a way that verifies those independently. So you would docker run dogecoin:latest getshasums and then compare that output against an independent script or website that verifies it, citing matching gitian.sigs sources... or of course do the gitian build yourself and then validate it against that.

If the download is compromised, everything seems compromised.

If the uploaded binaries and the gitian.sigs repository are compromised, yes. Which means it all depends on GitHub security. Since however binaries published on dogecoin.com have even less security than the Dockerfile we create with this PR, I think we're improving it. We could use IPFS instead of GitHub for the build audits, but that needs peers that pin things or it'll just be another single point of failure.

breaking this Dockerfile idea of "verifying the source, verifying the author, and verifying the content".

We can pin a shasum. But the reason we are doing a lot of work and a lot of discussion is because you didn't want to pin the shasum... so this is becoming a bit circular.

AbcSxyZ commented 2 years ago

Then the CI must fail on PR and we solve it if that happens.

Fine. I think those public key only available for the next release is still an improvable design (for here but not only).

The idea was to follow Docker security recommendation, and they are saying checking only checksum is the "Less Secure Alternate". Also, I thought it could be a way to facilitate the management of different versions/Dockerfile, it seems I was wrong for this and it may be a bad idea.

I went back to the documentation, and they are suggesting to use PGP verification + hard coded checksum :) This way, everyone could be happy !

patricklodder commented 2 years ago

Alright, so let's do it step by step then from the guide:

[..] verifying the source, verifying author, and verifying the content; these are respectively accomplished by the following: using https where possible; importing PGP keys with the full fingerprint in the Dockerfile to check signatures; embedding checksums directly in the Dockerfile

  1. Verifying the source (authenticity). Suggested method: https downloads. This is to prevent mitm attacks on the outgoing connections. We do this.
  2. Verifying the author (authenticity). Suggested method: PGP signing. This is to prevent someone hijacking the server and injecting a false binary. We do this with the gitian process introduced here, but with the note that there is no real authoritative version.
  3. Verifying the content (integrity). Suggested method: sha256sum of the download. We do this intrinsically with the gitian process per the first example they give as python does it, but I agree that pinning will help further due to the decentralized nature of our authenticity check.

Adding the pinning today, then we should be good, I think!

patricklodder commented 2 years ago

Added pinning, rebased and squashed.

xanimo commented 2 years ago

linux/arm64, linux/arm, linux/amd64, linux/686 buildx confirmed on:

Architecture:                    aarch64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
CPU(s):                          4
On-line CPU(s) list:             0-3
Thread(s) per core:              1
Core(s) per socket:              4
Socket(s):                       1
Vendor ID:                       ARM
Model:                           3
Model name:                      Cortex-A72
Stepping:                        r0p3
CPU max MHz:                     1500.0000
CPU min MHz:                     600.0000
BogoMIPS:                        108.00
Flags:                           fp asimd evtstrm crc32 cpuid

https://hub.docker.com/repository/docker/xanimo/1.14.4-dogecoin/tags?page=1&ordering=last_updated