Reproducibility
Posted on January 21, 2024 • 2 minutes • 369 words
What is reproducibility?
Reproducible builds are a set of software development practices that create an independently-verifiable path from source to binary code.
as defined by reproducible-builds.org
Why does it matter?
The motivation behind the Reproducible Builds project is therefore to allow verification that no vulnerabilities or backdoors have been introduced during this compilation process
So assume reproducibility can be achieved and attested, and if we trust the published source, this artifact can be trusted too.
There are 2 concepts here:
- “achieved” means reproducible.
- “attested” means verified reproducible.
This is very crucial in the software supply chain security.
How to produce a reproducible container image
Let’s take an go:1.21-bookwarm
image for example. Source for Dockerfile is available here
.
FROM buildpack-deps:bookworm-scm
# install cgo-related dependencies
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
g++ \
gcc \
libc6-dev \
make \
pkg-config \
; \
rm -rf /var/lib/apt/lists/*
Let’s try to make this image reproducible.
By default, the official debian
image use ftp.debian.org
. Packages in this repository get updated and old packages get dumped all the time. So reproducibility is pretty much gone.
Thanksfully, there’s http://snapshot.debian.org
which provides access to old packages based on dates & version numbers. You can also use http://snapshot-cloudflare.debian.org/archive/
as alternative.
So how do we get reproducible build with this? By locking down the snapshot of the repository as the build time.
By default, the content of default repo at /etc/apt/sources.list.d/debian.sources
looks like this
Types: deb
# http://snapshot.debian.org/archive/debian/20240110T000000Z
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
# http://snapshot.debian.org/archive/debian-security/20240110T000000Z
URIs: http://deb.debian.org/debian-security
Suites: bookworm-security
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Notice the commented line http://snapshot.debian.org/archive/debian-security/20240110T000000Z
. This is the snapshot URL. If we use this URL, we can lock down the version of all the packages we want to install.
But how do we get that URL? It’s simple.
SOURCE_DATE_EPOCH=$(stat --format=%Y /etc/apt/sources.list.d/debian.sources)
# => 1704844800
printf "%(%Y%m%dT%H%M%SZ)T\n" "$SOURCE_DATE_EPOCH"
# => 20240110T000000Z
# => http://snapshot.debian.org/archive/debian-security/20240110T000000Z
Now if you run apt update
, you will get the sth like this instead
apt update
Get:1 http://snapshot-cloudflare.debian.org/archive/debian/20240110T000000Z bookworm InRelease [151 kB]
Get:2 http://snapshot-cloudflare.debian.org/archive/debian-security/20240110T000000Z bookworm-security InRelease [48.0 kB]
And now, you can reliably reproduce this image because the rest of the go’s Dockerfile is already reproducible (downloading go with shasum check).