85
How to make your software build reproducibly Provide a verifiable path from source to binary Lunar [email protected] Chaos Communication Camp 2015-08-13 Lunar (Debian) Reproducible builds HOWTO CCCamp15 1 / 59

Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar [email protected]

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

How to make your software build reproduciblyProvide a verifiable path from source to binary

[email protected]

Chaos Communication Camp2015-08-13

Lunar (Debian) Reproducible builds HOWTO CCCamp15 1 / 59

Page 2: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 3: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The problem

source binarybuild

free softwarefreedomto study

freedomto run

can be verified can be used

could I get a proof?

Lunar (Debian) Reproducible builds HOWTO CCCamp15 3 / 59

Page 4: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The problem

source binarybuild

free softwarefreedomto study

freedomto run

can be verified can be used

could I get a proof?

Lunar (Debian) Reproducible builds HOWTO CCCamp15 3 / 59

Page 5: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The problem

source binarybuild

free softwarefreedomto study

freedomto run

can be verified can be used

could I get a proof?

Lunar (Debian) Reproducible builds HOWTO CCCamp15 3 / 59

Page 6: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The problem

source binarybuild

free softwarefreedomto study

freedomto run

can be verified can be used

could I get a proof?

Lunar (Debian) Reproducible builds HOWTO CCCamp15 3 / 59

Page 7: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Why does it matter?

Available on media.ccc.de, 31c3Lunar (Debian) Reproducible builds HOWTO CCCamp15 4 / 59

Page 8: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Just one exampleAt a CIA conference in 2012:

firstlook.org/theintercept/2015/03/10/ispy-cia-campaign-steal-apples-secrets/Lunar (Debian) Reproducible builds HOWTO CCCamp15 5 / 59

Page 9: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The solution

enable anyone to reproduceidentical binary packages

from a given source

Lunar (Debian) Reproducible builds HOWTO CCCamp15 6 / 59

Page 10: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

The solution

We call this:

“reproducible builds”

Lunar (Debian) Reproducible builds HOWTO CCCamp15 7 / 59

Page 11: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

It’s trendy!

Bitcoin (done)Tor (done)Debian (in progress)FreeBSD (in progress)NetBSD (in progress)Coreboot (done)OpenWrt (in progress)…

Lunar (Debian) Reproducible builds HOWTO CCCamp15 8 / 59

Page 12: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

It should become the norm.

Page 13: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Multiple aspects

Deterministic build systemfor those who write source codeReproducible build environmentfor those who create binaries for othersDistributing the build environmentfor those who distribute binaries to the worldPerforming a rebuild and checking the resultsfor every one of us

Lunar (Debian) Reproducible builds HOWTO CCCamp15 10 / 59

Page 14: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 15: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Deterministic build system

In a nutshell:

Stable inputsStable outputsCapture as little as possible from the environment

Lunar (Debian) Reproducible builds HOWTO CCCamp15 12 / 59

Page 16: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Common problemsTimestamps (recording current time)File order(Pseudo-)randomness:

I Temporary file pathsI UUIDI Protection against complexity attacks

CPU and memory related:I Code optimizations for current CPU classI Recording of memory addresses

Build pathLocale and timezone settings

Lunar (Debian) Reproducible builds HOWTO CCCamp15 13 / 59

Page 17: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 18: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Volatile inputs can disappearDon’t rely on the networkIf you do:

I Verify content using checksumsI Have a backup

The binary distributor should provide a fallback

FreeBSD does it right$ grep MASTER_SITES MakefileMASTER_SITES= http://gondor.apana.org.au/~herbert/dash/files/$ cat distinfoSHA256 (dash-0.5.8.tar.gz) = c6db3a237747b02d20382a761397563d813b306c020ae28ce25…SIZE (dash-0.5.8.tar.gz) = 223028$ wget http://distcache.freebsd.org/ports-distfiles/distfiles/dash-0.5.8.tar.gz

Lunar (Debian) Reproducible builds HOWTO CCCamp15 15 / 59

Page 19: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 20: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for inputs

Always process multiple inputs in the same orderDirectory listings are not stable!

Solutions:I List inputs explicitely

I Use sortingI But watch out for difference between locales.

Exampletar -cf archive.tar src

Lunar (Debian) Reproducible builds HOWTO CCCamp15 17 / 59

Page 21: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for inputs

Always process multiple inputs in the same orderDirectory listings are not stable!Solutions:

I List inputs explicitely

I Use sortingI But watch out for difference between locales.

Exampletar -cf archive.tar \src/util.c src/helper.c src/main.c

Lunar (Debian) Reproducible builds HOWTO CCCamp15 17 / 59

Page 22: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for inputs

Always process multiple inputs in the same orderDirectory listings are not stable!Solutions:

I List inputs explicitelyI Use sorting

I But watch out for difference between locales.

Examplefind src -print0 | sort -z |tar --null -T - --no-recursion -cf archive.tar

Lunar (Debian) Reproducible builds HOWTO CCCamp15 17 / 59

Page 23: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for inputs

Always process multiple inputs in the same orderDirectory listings are not stable!Solutions:

I List inputs explicitelyI Use sortingI But watch out for difference between locales.

Examplefind src -print0 | LC_ALL=C sort -z |tar --null -T - --no-recursion -cf archive.tar

Lunar (Debian) Reproducible builds HOWTO CCCamp15 17 / 59

Page 24: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 25: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Controlled value initializationDon’t record memory by accident

Always initialize to a known value

Examplestatic int write_binary(FILE *out, FILE *in, struct bimg_header *hdr){

static uint8_t file_buf[MAX_RECORD_BYTES];struct bimg_data_header data_hdr;size_t n_written;

data_hdr.dest_addr = hdr->entry_addr;…

Lunar (Debian) Reproducible builds HOWTO CCCamp15 19 / 59

Page 26: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Controlled value initializationDon’t record memory by accidentAlways initialize to a known value

Examplestatic int write_binary(FILE *out, FILE *in, struct bimg_header *hdr){

static uint8_t file_buf[MAX_RECORD_BYTES];struct bimg_data_header data_hdr = { 0 };size_t n_written;

data_hdr.dest_addr = hdr->entry_addr;…

Lunar (Debian) Reproducible builds HOWTO CCCamp15 19 / 59

Page 27: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 28: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Use deterministic version informationDon’t generate a version number on each build

Instead extract information from the source:I Version control system revisionI Hash of the source codeI Changelog entry

ExampleVERSION=$(shell dpkg-parsechangelog | sed -n 's/^Version: *//p')

SCONSOPTS = $(SCONSFLAGS) VERSION=$(VERSION) \PREFIX=$(PREFIX) PREFIX_CONF=$(SYSCONF) CHMDOCS=0 \STRIP_CP=no \$(if $(findstring nostripfull,$(DEB_BUILD_OPTIONS)),STRIP_W32=no,)

Lunar (Debian) Reproducible builds HOWTO CCCamp15 21 / 59

Page 29: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Use deterministic version informationDon’t generate a version number on each buildInstead extract information from the source:

I Version control system revisionI Hash of the source codeI Changelog entry

ExampleVERSION=$(shell dpkg-parsechangelog | sed -n 's/^Version: *//p')

SCONSOPTS = $(SCONSFLAGS) VERSION=$(VERSION) \PREFIX=$(PREFIX) PREFIX_CONF=$(SYSCONF) CHMDOCS=0 \STRIP_CP=no \$(if $(findstring nostripfull,$(DEB_BUILD_OPTIONS)),STRIP_W32=no,)

Lunar (Debian) Reproducible builds HOWTO CCCamp15 21 / 59

Page 30: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 31: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record the current date and time

Avoid timestamps

If you need one:I Use date of last commit in VCSI Extract from changelog

I Don’t forget the timezone

faketime is an option but has serious drawbackshttps://bugs.torproject.org/12240

Implement SOURCE_DATE_EPOCH

Lunar (Debian) Reproducible builds HOWTO CCCamp15 23 / 59

Page 32: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record the current date and time

Avoid timestampsIf you need one:

I Use date of last commit in VCSI Extract from changelog

I Don’t forget the timezonefaketime is an option but has serious drawbackshttps://bugs.torproject.org/12240

Implement SOURCE_DATE_EPOCH

Lunar (Debian) Reproducible builds HOWTO CCCamp15 23 / 59

Page 33: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record the current date and time

Avoid timestampsIf you need one:

I Use date of last commit in VCSI Extract from changelogI Don’t forget the timezone

faketime is an option but has serious drawbackshttps://bugs.torproject.org/12240

Implement SOURCE_DATE_EPOCH

Lunar (Debian) Reproducible builds HOWTO CCCamp15 23 / 59

Page 34: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record the current date and time

Avoid timestampsIf you need one:

I Use date of last commit in VCSI Extract from changelogI Don’t forget the timezone

faketime is an option but has serious drawbackshttps://bugs.torproject.org/12240

Implement SOURCE_DATE_EPOCH

Lunar (Debian) Reproducible builds HOWTO CCCamp15 23 / 59

Page 35: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record the current date and time

Avoid timestampsIf you need one:

I Use date of last commit in VCSI Extract from changelogI Don’t forget the timezone

faketime is an option but has serious drawbackshttps://bugs.torproject.org/12240

Implement SOURCE_DATE_EPOCH

Lunar (Debian) Reproducible builds HOWTO CCCamp15 23 / 59

Page 36: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

SOURCE_DATE_EPOCH

What is it?I Environment variable with a reference timeI Number of seconds since the Epoch (1970-01-01 00:00:00 +0000 UTC)I If set, replace “current time of day”I Implemented by help2man, Epydoc, Doxygen, Ghostscript (in Debian)I Patches ready for GCC, txt2man, libxslt, Gettext…

Set SOURCE_DATE_EPOCH in your build systemPlease add support in any tool writing timestamps

https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal

Lunar (Debian) Reproducible builds HOWTO CCCamp15 24 / 59

Page 37: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

SOURCE_DATE_EPOCH

What is it?I Environment variable with a reference timeI Number of seconds since the Epoch (1970-01-01 00:00:00 +0000 UTC)I If set, replace “current time of day”I Implemented by help2man, Epydoc, Doxygen, Ghostscript (in Debian)I Patches ready for GCC, txt2man, libxslt, Gettext…

Set SOURCE_DATE_EPOCH in your build system

Please add support in any tool writing timestamps

https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal

Lunar (Debian) Reproducible builds HOWTO CCCamp15 24 / 59

Page 38: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

SOURCE_DATE_EPOCH

What is it?I Environment variable with a reference timeI Number of seconds since the Epoch (1970-01-01 00:00:00 +0000 UTC)I If set, replace “current time of day”I Implemented by help2man, Epydoc, Doxygen, Ghostscript (in Debian)I Patches ready for GCC, txt2man, libxslt, Gettext…

Set SOURCE_DATE_EPOCH in your build systemPlease add support in any tool writing timestamps

https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal

Lunar (Debian) Reproducible builds HOWTO CCCamp15 24 / 59

Page 39: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 40: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record current time (really)Archives keep modification times in metadataStoring a file can record build time

Solutions:I Store an arbitrary value

I Pre-process file modification timeI Post-process archive

Example

touch --date="2015-08-13 00:00Z" build/*

tar -cf product.tar build

Lunar (Debian) Reproducible builds HOWTO CCCamp15 26 / 59

Page 41: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record current time (really)Archives keep modification times in metadataStoring a file can record build timeSolutions:

I Store an arbitrary value

I Pre-process file modification timeI Post-process archive

Example

touch --date="2015-08-13 00:00Z" build/*

tar --mtime='2015-08-13 00:00Z' -cf product.tar build

Lunar (Debian) Reproducible builds HOWTO CCCamp15 26 / 59

Page 42: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record current time (really)Archives keep modification times in metadataStoring a file can record build timeSolutions:

I Store an arbitrary valueI Pre-process file modification time

I Post-process archive

Exampletouch --date="2015-08-13 00:00Z" build/*tar -cf product.tar build

Lunar (Debian) Reproducible builds HOWTO CCCamp15 26 / 59

Page 43: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Don’t record current time (really)Archives keep modification times in metadataStoring a file can record build timeSolutions:

I Store an arbitrary valueI Pre-process file modification timeI Post-process archive

Example# zip has no equivalent of --mtimezip product.zip buildstrip-nondeterminism product.zip

Lunar (Debian) Reproducible builds HOWTO CCCamp15 26 / 59

Page 44: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 45: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for outputs

Always output lists in the same orderTypical issue: key order with hash tablesperldoc.perl.org/perlsec.html#Algorithmic-Complexity-Attacks

Sort!

Examplefor module in dependencies.keys():

version = dependencies[module]print('%s (>= %s)' % (module, version))

Lunar (Debian) Reproducible builds HOWTO CCCamp15 28 / 59

Page 46: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stable order for outputs

Always output lists in the same orderTypical issue: key order with hash tablesperldoc.perl.org/perlsec.html#Algorithmic-Complexity-Attacks

Sort!

Examplefor module in sorted(dependencies.keys()):

version = dependencies[module]print('%s (>= %s)' % (module, version))

Lunar (Debian) Reproducible builds HOWTO CCCamp15 28 / 59

Page 47: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

XKCD #221

Avoid (true) randomness

Randomness is not deterministic

Seed your PRNG from known valueI Use a fixed value

I Extract from source code (filename, content hash)

Example$ gcc -flto -c utils.c$ nm -a utils.o | grep inline0000000000000000 n .gnu.lto_.inline.381a277a0b6d2a35

Lunar (Debian) Reproducible builds HOWTO CCCamp15 29 / 59

Page 48: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

XKCD #221

Avoid (true) randomness

Randomness is not deterministicSeed your PRNG from known value

I Use a fixed value

I Extract from source code (filename, content hash)

Example$ gcc -flto -c -frandom-seed=0 utils.c$ nm -a utils.o | grep inline0000000000000000 n .gnu.lto_.inline.0

Lunar (Debian) Reproducible builds HOWTO CCCamp15 29 / 59

Page 49: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

XKCD #221

Avoid (true) randomness

Randomness is not deterministicSeed your PRNG from known value

I Use a fixed valueI Extract from source code (filename, content hash)

Example$ gcc -flto -c -frandom-seed=utils.o utils.c$ nm -a utils.o | grep inline0000000000000000 n .gnu.lto_.inline.a108e942

Lunar (Debian) Reproducible builds HOWTO CCCamp15 29 / 59

Page 50: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Define environment variable affecting outputs

Some environment variables will affect software outputs. E.g:I LC_CTIME for time stringsI LC_CTYPE for text encodingI TZ for times

Set them to a controlled valuePlease don’t force the language

Lunar (Debian) Reproducible builds HOWTO CCCamp15 30 / 59

Page 51: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Define environment variable affecting outputs

Some environment variables will affect software outputs. E.g:I LC_CTIME for time stringsI LC_CTYPE for text encodingI TZ for times

Set them to a controlled value

Please don’t force the language

Lunar (Debian) Reproducible builds HOWTO CCCamp15 30 / 59

Page 52: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Define environment variable affecting outputs

Some environment variables will affect software outputs. E.g:I LC_CTIME for time stringsI LC_CTYPE for text encodingI TZ for times

Set them to a controlled valuePlease don’t force the language

Lunar (Debian) Reproducible builds HOWTO CCCamp15 30 / 59

Page 53: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stop recording build system information

Don’t record information about the build system, like:I date and time of the buildI hostnameI pathI network configurationI CPUI environment variablesI …

If you really want to record them, do it outside the binaries

Lunar (Debian) Reproducible builds HOWTO CCCamp15 31 / 59

Page 54: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Stop recording build system information

Don’t record information about the build system, like:I date and time of the buildI hostnameI pathI network configurationI CPUI environment variablesI …

If you really want to record them, do it outside the binaries

Lunar (Debian) Reproducible builds HOWTO CCCamp15 31 / 59

Page 55: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 56: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

What’s in a build environment?

At least: build tools and their specific versions

Up to you, depending on the build system:I build architectureI operating systemI build pathI build date and timeI …

Lunar (Debian) Reproducible builds HOWTO CCCamp15 33 / 59

Page 57: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

What’s in a build environment?

At least: build tools and their specific versionsUp to you, depending on the build system:

I build architectureI operating systemI build pathI build date and timeI …

Lunar (Debian) Reproducible builds HOWTO CCCamp15 33 / 59

Page 58: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Build from source

Build tools affecting the output from sourceRecord version / tag / git commitApproach used by Coreboot, OpenWrt, Tor Browser

Lunar (Debian) Reproducible builds HOWTO CCCamp15 34 / 59

Page 59: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Reference distribution

Use a stable distribution (e.g. Debian, CentOS)Record package versionHope the old package will stay available / recordApproach used by Bitcoin, Tor Browser

Lunar (Debian) Reproducible builds HOWTO CCCamp15 35 / 59

Page 60: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Virtual machines / containers

Using a VM saves some problems:I Same userI Same hostnameI Same network configurationI Same CPUI …

Introduce new things that need to be trusted

Lunar (Debian) Reproducible builds HOWTO CCCamp15 36 / 59

Page 61: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Proprietary operating systems

Cross-compiling to the rescue!For Windows:

I mingw-w64: build Windows binaries on *nixI NSIS (Nullsoft Scriptable Install System)

For Mac OS X:I Used to be quite complicated

https://github.com/bitcoin/bitcoin/blob/master/doc/README_osx.txtI Now pretty straightforward with crosstool-ng

https://bugs.torproject.org/9711#comment:73I Need a non-redistributable SDK extracted from XCodeI .dmg are a bit tricky

Lunar (Debian) Reproducible builds HOWTO CCCamp15 37 / 59

Page 62: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 63: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Good ol’Makefile

Download known toolchain archivesCompare reference checksumsBuild and setupCoreboot: make crossgcc

Lunar (Debian) Reproducible builds HOWTO CCCamp15 39 / 59

Page 64: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Check-in everything

Check-in all the toolchain source code in VCSApproach used for the base system in *BSD, and GoogleMake sure everything is checked in (use sandbox on Linux)Recently open-sourced: Bazelhttp://bazel.io/Can be hard to ask everyone to download everything all the time

Lunar (Debian) Reproducible builds HOWTO CCCamp15 40 / 59

Page 65: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Ship the toolchain as a build product

Make the toolchain as a build productOpenWrt:http://wiki.openwrt.org/doc/howto/obtain.firmware.sdk

Example$ wget https://downloads.openwrt.org/…/14.07/…OpenWrt-SDK-atheros-….tar.bz2$ svn export svn://…/branches/packages_14.07/utils/xz package/xz$ make package/xz/compile

Lunar (Debian) Reproducible builds HOWTO CCCamp15 41 / 59

Page 66: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

GitianUsed by Bitcoin, Tor BrowserDrives LXC or KVM“Descriptors” describing the build using:

I Base distributionI PackagesI Git remotesI Other input filesI Build script

Resourceshttps://gitian.org/https://github.com/bitcoin/bitcoin/blob/master/doc/gitian-building.mdhttps://github.com/bitcoin/bitcoin/blob/master/contrib/gitian-descriptors/

Lunar (Debian) Reproducible builds HOWTO CCCamp15 42 / 59

Page 67: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

DockerProvide a way to describe specialized Linux container imagesBuild in a controlled environmentDocker images can be addressed with a hash of their contentBazel has support to build Docker images reproducibly

https://github.com/tianon/gosu/blob/master/DockerfileFROM golang:1.4-cross[…]# disable CGO for ALL THE THINGS (to help ensure no libc)ENV CGO_ENABLED 0COPY *.go /go/src/github.com/tianon/gosu/WORKDIR /go/src/github.com/tianon/gosuRUN GOARCH=amd64 go build -v -ldflags -d -o /go/bin/gosu-amd64

Lunar (Debian) Reproducible builds HOWTO CCCamp15 43 / 59

Page 68: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Vagrant

Drive VirtualBox using Ruby and other scriptsBuild in a controlled environmentAlso works under OS X and Windows

https://www.vagrantup.com/

Lunar (Debian) Reproducible builds HOWTO CCCamp15 44 / 59

Page 69: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Debian .buildinfo

Tie in the same file:I SourcesI Generated binariesI Packages used to build (with specific version)

Can be later processed to reinstall environmentAll versions are available from snapshot.debian.org

Lunar (Debian) Reproducible builds HOWTO CCCamp15 45 / 59

Page 70: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Example .buildinfoFormat: 1.9Build-Architecture: amd64Source: txtorconBinary: python-txtorconArchitecture: allVersion: 0.11.0-1Build-Path: /usr/src/debian/txtorcon-0.11.0-1Checksums-Sha256:a26549d9…7b 125910 python-txtorcon_0.11.0-1_all.deb28f6bcbe…69 2039 txtorcon_0.11.0-1.dsc

Build-Environment:base-files (= 8),base-passwd (= 3.5.37),bash (= 4.3-11+b1),…

Lunar (Debian) Reproducible builds HOWTO CCCamp15 46 / 59

Page 71: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 72: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Testing for variations

Build a first timeSave the resultPerform change(s) to the environmentBuild a second timeCompare results

Lunar (Debian) Reproducible builds HOWTO CCCamp15 48 / 59

Page 73: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

reproducible.debian.netContinuous test system driven by JenkinsBad-ass hardware sponsored by ProfitBricksTests about 1300 Debian source packages per day on averageResults are visible on a websiteOther projects: Coreboot, OpenWrt, yours?

Lunar (Debian) Reproducible builds HOWTO CCCamp15 49 / 59

Page 74: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Variations on reproducible.debian.netvariation first build second buildhostname jenkins i-capture-the-hostnamedomainname debian.net i-capture-the-domainnameenv TZ GMT+12 GMT-14env LANG en_GB.UTF-8 fr_CH.UTF-8env LC_ALL not set fr_CH.UTF-8env USER pbuilder1 pbuilder2uid 1111 2222gid 1111 2222UTS namespace shared with the host modified using /usr/bin/unshare --utskernel version Linux 3.16.0-4-amd64 Linux 2.6.56-4-amd64umask 0022 0002CPU type same for both builds (work in progress)year, month, date same for both builds (work in progress)hour, minute hour is usually the same… usually, the minute differs… (work in progress)everything else is likely the same…

Lunar (Debian) Reproducible builds HOWTO CCCamp15 50 / 59

Page 75: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org
Page 76: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

2014

-10-

1420

14-1

0-24

2014

-11-

0320

14-1

1-13

2014

-11-

2320

14-1

2-03

2014

-12-

1320

14-1

2-23

2015

-01-

0220

15-0

1-12

2015

-01-

2220

15-0

2-01

2015

-02-

1120

15-0

2-21

2015

-03-

0320

15-0

3-13

2015

-03-

2320

15-0

4-02

2015

-04-

1220

15-0

4-22

2015

-05-

0220

15-0

5-12

2015

-05-

2220

15-0

6-01

2015

-06-

1120

15-0

6-21

2015

-07-

0120

15-0

7-11

2015

-07-

2120

15-0

7-31

0

100

200

300

400

500

600

700

800

Done

Open

Page 77: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Debugging problems: diffoscopeExamines differences in depthOutputs HTML or plain text showing the differencesRecursively unpacks archivesSeeks human readability:

I uncompresses PDFI disassembles binariesI unpacks Gettext filesI … easy to extend to new file formats

Falls back to binary comparison

http://diffoscope.org/(formely known as debbindiff)

Lunar (Debian) Reproducible builds HOWTO CCCamp15 53 / 59

Page 78: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

diffoscope example (HTML output)

Lunar (Debian) Reproducible builds HOWTO CCCamp15 54 / 59

Page 79: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

diffoscope example (text output)

Lunar (Debian) Reproducible builds HOWTO CCCamp15 55 / 59

Page 80: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

strip-nondeterminismNormalizes various file formatsCurrently handles:

I ar archives (.a)I gzipI Java jarI Javadoc HTMLI Maven pom.propertiesI PNGI ZIP archivesI … extensible to new formats

Written in Perl (like dpkg-dev)

git://git.debian.org/reproducible/strip-nondeterminism.git

Lunar (Debian) Reproducible builds HOWTO CCCamp15 56 / 59

Page 81: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Resources

Reproducible Builds HOWTO (work in progress)https://reproducible.debian.net/howto/

Debian “Reproducible Builds” wikihttps://wiki.debian.org/ReproducibleBuildsDiverse Double-Compilationhttp://www.dwheeler.com/trusting-trust/

Lunar (Debian) Reproducible builds HOWTO CCCamp15 57 / 59

Page 82: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Resources

Reproducible Builds HOWTO (work in progress)https://reproducible.debian.net/howto/Debian “Reproducible Builds” wikihttps://wiki.debian.org/ReproducibleBuilds

Diverse Double-Compilationhttp://www.dwheeler.com/trusting-trust/

Lunar (Debian) Reproducible builds HOWTO CCCamp15 57 / 59

Page 83: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Resources

Reproducible Builds HOWTO (work in progress)https://reproducible.debian.net/howto/Debian “Reproducible Builds” wikihttps://wiki.debian.org/ReproducibleBuildsDiverse Double-Compilationhttp://www.dwheeler.com/trusting-trust/

Lunar (Debian) Reproducible builds HOWTO CCCamp15 57 / 59

Page 84: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

1 Introduction

2 Deterministic build system

3 Reproducible build environment

4 Distributing the build environment

5 Tips

6 Questions?

Page 85: Provideaverifiablepathfromsourcetobinary Lunar lunar@debian · 2018-05-27 · Howtomakeyoursoftwarebuildreproducibly Provideaverifiablepathfromsourcetobinary Lunar lunar@debian.org

Thanks!Debian “Reproducible Builds” team(you are just so awesome!)Mike Perry, Georg Koppen, David A. WheelerLinux Foundation and the Core Infrastructure Initiative

[email protected] 0603 CCFD 9186 5C17 E88D4C79 8382 C95C 2902 3DF9

clothes: Elhonna Sombrefeuille — hair: igor

Lunar (Debian) Reproducible builds HOWTO CCCamp15 59 / 59