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

Introduce a reproducible build system for Linux #6945

Closed
wants to merge 1 commit into from

Conversation

hackerbirds
Copy link
Contributor

@hackerbirds hackerbirds commented Jul 20, 2024

First time contributor checklist:

Contributor checklist:

  • My contribution is not related to translations.
  • My commits are in nice logical chunks with good commit messages
  • My changes are rebased on the latest main branch
  • A npm run ready run passes successfully (more about tests here)
  • My changes are ready to be shipped to users

Description

This PR attempts to introduces reproducible builds on Linux.

Motivation for reproducible builds

  • Reproducible builds are a guarantee that the open source code available to all users is the one used in the official builds
  • Reproducible builds help audit the source code a lot easily and confidently, since we can be use the official build is running the source code we're auditing.
  • Reproducible builds prevents developers introducing backdoors into the official builds, which is more than ever relevant given the recent XZ Utils incident
  • Reproducible builds any build more trustworthy. Delegating the official build process to a single developer is a lot more safe if builds are reproducible and can be built on any computer.
  • Telegram recently called out Signal for not having reproducible builds on iOS. Outside of the political reasons and obvious technical problems with reproducibility on iOS, I think that making reproducible builds wherever possible could increase public confidence in Signal and avoid callouts like that.
  • https://reproducible-builds.org/ go into more detail

What needs to be reproducible on Desktop

From what I gathered, there are three things making Signal Desktop non-reproducible:

  • Potential timestamps included in the packages themselves. In the case of .deb, FPM was inserting timestamps in the .deb files and tar archives (metadata). I have written more about it on Make release build's timestamp more deterministic #6940
  • Node dependency bindings built from C/C++. This includes for instance @signalapp/better-sqlite3 and @nodert-win10-rs4. This is why I decided to use Docker, to ensure the C compilers were identical for everyone.
  • DNS fallback configuration dynamically generated at build time. See Reproducible Builds regression: dns-fallback.json #6823

What has been done in this PR

  • Linux .deb builds on amd64
  • Windows .exe builds: not done by this PR. Windows builds have to be built on Windows, and the Docker image is Linux.
  • macOS .dmg builds: same issue as above.
  • I have temporarily disabled the DNS fallback configuration generation to prototype a reproducible build. Of course that's unacceptable for official builds, but I am planning in a later commit, if this idea goes forward, to remove build/dns-fallback.json from .gitignore to make it the same for everyone (though again there will need to be approval from the Desktop team because that would mean manually updating the file with say an npm command, as I had suggested in the issue above).

I have essentially repurposed Signal Android's reproducible build system to make Signal Desktop linux builds, for several reasons:

  • The infrastructure already exists and is already maintained by Signal.
  • This process is already well known by the Android team.
  • And honestly it was just way easier to modify something that already exists than to make it from scratch too.

I have written a quick guide in reproducible-builds/README.md, though it will need more work. Essentially, reproducible-builds/build.sh should do everything on its own, you just need Docker and git.

I understand that this PR only covers Linux, at least for now, but in my opinion it is better than nothing. This is something that can only be improved, and is parallel to the existing build CI so it won't break it.

How to verify the builds

I tried to make it so that the entire .deb file is reproducible. Currently, the resulting .deb build on my tree should have the SHA256 hash: 34441fec941c4cb2450e50f3b0a2ce9170d2ded6ae73a8812bdfc37c29805050. I invite more people to try building this themselves and verify that they are also getting the same hash. If you don't, let me know.

If that doesn't work out (perhaps because of post-build signatures in the .deb file, but I don't think that's the case), then the contents of signal-desktop...deb/control.tar.gz/md5sums can also be compared. That file contains the md5 hashes of all the files inside the .deb.

The downsides of this PR

Of course, this PR only makes sense if the Desktop team agrees to start building the official apps on this kind of build system. I am pretty sure this can be done automatically in CI (I don't know how Desktop is actually built/where the build comes from though), but this still adds extra complexity and effort, notably because of the DNS fallback issue.

I also understand that this is unfortunately not a high priority issue, which makes justifying drastic changes to the build process a lot harder, but I hope this PR will get the ball rolling.

@afro-systems
Copy link

Thank you for doing this! I need a arm64 linux build.

@hackerbirds
Copy link
Contributor Author

Thank you for doing this! I need a arm64 linux build.

Sorry that was a typo, I only managed to build amd64. Building arm64 isn't officially supported so this PR won't help you, but maybe you can achieve it if you're building Desktop yourself manually on an arm64 Linux machine

@trevor-signal trevor-signal self-assigned this Jul 23, 2024
@trevor-signal
Copy link
Contributor

@hackerbirds thank you very much for this investigation!

@hackerbirds
Copy link
Contributor Author

hackerbirds commented Jul 24, 2024

@hackerbirds thank you very much for this investigation!

No problem. When possible, could any of you please let me know if this idea/PR will go forward or not? Otherwise I'll close this PR and open a GitHub issue instead. I'm asking (no pressure though) because without approval and involvement from the devs, there isn't much users can do to reproduce 100% of an official build.

@ayumi-signal
Copy link
Contributor

@hackerbirds We've discussed reproducible builds and want to move forward with this plan, to use Docker similarly to the Android builds and to start with reproducible builds on Linux.

We need to integrate it with the build process, and it's possible we'll need to make small adjustments to the PR, so please bear with us while we do that. Our hope and plan is to merge this PR. Thanks for your help!

@hackerbirds
Copy link
Contributor Author

@hackerbirds We've discussed reproducible builds and want to move forward with this plan, to use Docker similarly to the Android builds and to start with reproducible builds on Linux.

We need to integrate it with the build process, and it's possible we'll need to make small adjustments to the PR, so please bear with us while we do that. Our hope and plan is to merge this PR. Thanks for your help!

Thank you so much that's great news!! I'm really glad to see reproducible builds getting attention. Of course Debian is the least used supported OS but it's a step in the right direction.

Let me know if you need help or want me to change/add anything. Currently this PR breaks dns-fallback.json, so it can't be merged as-is. I'd be happy to fix that, though I'll prolly need feedback on how you me want to accomplish that since it has to work with the current build process without breaking it.

@ayumi-signal
Copy link
Contributor

ayumi-signal commented Aug 9, 2024

We have merged this internally and are beginning to use this build system for our development builds!

Some changes were needed to work with our build pipeline, so you will see that as a follow-on when the merge releases around next week.

It's a work on progress, and we're looking forward to getting things working well enough so beta and prod builds can use this system as well. Thanks so much for your help!

@hackerbirds
Copy link
Contributor Author

hackerbirds commented Aug 9, 2024

That's awesome, thank you for the updates and for putting the work into completing this PR! I'm guessing reproducibility has been successful on your machines (outside of CI/CD)?

EDIT: I have (nearly) successfully reproduced the staging version signal-desktop-staging_7.22.0~staging.20240814.12~d70aa55a7_amd64.deb. The only issues/difference in the binary is because I built it on 20240815 instead of 20240814, so the package name is different (this affects .../app.asar/package.json and changelog.gz again). Other than that, every other file was identical. This package name issue is probably not worth worrying about because it's just a staging build and beta/prod releases don't have dates in their package name. tysm for working on this!!

@hackerbirds
Copy link
Contributor Author

I realized I have made a typo in the following section of reproducible-builds/README.md:

[...] For instance, if you are trying to build 7.18.0, then do:

$ cd Signal-Desktop/
$ git checkout tags/7.18.0

I wrote tags/7.18.0, but this should be tags/v7.18.0. It might also be a good idea to include a link to https://github.com/signalapp/Signal-Desktop/tags so users can find the relevant tag name and write the relevant one instead.

I would add a commit to this PR to fix it, but since it was merged internally, I don't think I can do that anymore.

@indutny-signal
Copy link
Contributor

@hackerbirds the md file is already in the public repo https://github.com/signalapp/Signal-Desktop/tree/main/reproducible-builds#building . Let me know if you'd like to open a PR, it sounds like a great change!

@ayumi-signal
Copy link
Contributor

This PR was merged with d9baaa3 and ec36ae7. Thank you again!

@hackerbirds
Copy link
Contributor Author

This PR was merged with d9baaa3 and ec36ae7. Thank you again!

Thank you so much again. I think the change at ec36ae7#diff-0968de0f82c073ea664db3244836eef7626ce26e2cdb4b431a4c2dfc9894f292R8 may cause reproducibility problems with the .gz metadata though. I forgot to explain it in this PR but I explained it here: #6940, and this is why I had set the value to 1 instead of 0:

Note however that the value 0 [for SOURCE_DATE_EPOCH] won't work: fpm's ZLib library treats the timestamp 0 as "no timestamp available", and in that case will generate a fresh timestamp for the .gz file.

If you got it working like that though that's cool. I guess I'll just wait for this week's merges to see if I can reproduce the build or not and let you know if I can and make another PR for the fix if needed

@ayumi-signal
Copy link
Contributor

Ah thanks for pointing out the timestamp detail and sorry for missing it! It shouldn't affect reproducibility of builds as the build script will use the latest git commit timestamp: https://github.com/signalapp/Signal-Desktop/blob/main/reproducible-builds/build.sh#L22, but we can update the default so builds without git can also be reproducible.

@hackerbirds
Copy link
Contributor Author

Oh yeah, I forgot about that bit. Guess it shouldn't matter too much then

@hackerbirds
Copy link
Contributor Author

Hopefully the last message I'll send here: I just wanted to confirm I have successfully reproduced signal-desktop-beta_7.22.0~beta.1_amd64.deb (for the record, the hash is 39981ca9376509eefec6ce607cf4c192e21793e5af1d66d8425c688dc5e1c7cb)! This is super exciting!!

Now we need more users trying it on their own computers... time will tell if this new build mechanism is stable enough for release builds and all.

Thank you again for working on this (and the other related PRs and fixes) so quickly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants