From fd608ad49a4b14f5344daea672dccb541b47f19d Mon Sep 17 00:00:00 2001 From: peg Date: Mon, 5 Jan 2026 10:31:37 +0100 Subject: [PATCH 1/6] Add makefile and dockerfile for release builds --- Cargo.toml | 29 +++++++++++ Dockerfile.build-deb | 18 +++++++ Makefile | 119 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 Dockerfile.build-deb create mode 100644 Makefile diff --git a/Cargo.toml b/Cargo.toml index 3233bdc..926d895 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,9 +3,11 @@ members = [".", "dummy-attestation-server"] [package] name = "attested-tls-proxy" +description = "An HTTP attested TLS proxy server and client for secure communication with CVM services" version = "0.1.0" edition = "2024" license = "MIT" +repository = "https://github.com/flashbots/attested-tls-proxy" [dependencies] tokio = { version = "1.48.0", features = ["full"] } @@ -56,3 +58,30 @@ tdx-quote = { version = "0.0.4", features = ["mock"] } [features] default = ["azure"] azure = ["tss-esapi", "az-tdx-vtpm"] + +[package.metadata.deb] +maintainer = "Flashbots Team " +depends = "$auto" +section = "network" +priority = "optional" +maintainer-scripts = "pkg/debian" +assets = [ + [ + "target/release/**/attested-tls-proxy", + "usr/bin/", + "755", + ], + [ + "LICENSE", + "usr/share/doc/attested-tls-proxy/", + "644", + ], +] +systemd-units = { enable = false, start = false, unit-name = "attested-tls-proxy" } + +[profile.reproducible] +inherits = "release" +lto = "thin" +panic = "abort" +codegen-units = 1 +incremental = false diff --git a/Dockerfile.build-deb b/Dockerfile.build-deb new file mode 100644 index 0000000..70e83ac --- /dev/null +++ b/Dockerfile.build-deb @@ -0,0 +1,18 @@ +ARG RUST_TOOLCHAIN=1.89.0 +FROM docker.io/rust:$RUST_TOOLCHAIN-trixie AS builder + +ARG FEATURES VERSION +# Switch to snapshot repository +RUN sed -i '/^# http/{N;s|^# \(http[^ ]*\)\nURIs: .*|# \1\nURIs: \1|}' /etc/apt/sources.list.d/debian.sources +RUN apt-get -o Acquire::Check-Valid-Until=false update && \ + apt-get install -y \ + pkg-config clang libclang-dev \ + openssl libssl-dev libtss2-dev \ + cmake + +WORKDIR /build +COPY . . +RUN SOURCE_DATE=1730000000 make build && make build-deb + +FROM scratch AS artifacts +COPY --from=builder /build/target/x86_64-unknown-linux-gnu/ / diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e90a22a --- /dev/null +++ b/Makefile @@ -0,0 +1,119 @@ +# Heavily inspired by Lighthouse: https://github.com/sigp/lighthouse/blob/stable/Makefile +# and Reth: https://github.com/paradigmxyz/reth/blob/main/Makefile +.DEFAULT_GOAL := help + +GIT_VER ?= $(shell git describe --tags --always --dirty="-dev") +GIT_TAG ?= $(shell git describe --tags --abbrev=0) + +FEATURES ?= + +##@ Help + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +.PHONY: v +v: ## Show the current version + @echo "Version: ${GIT_VER}" + +##@ Build + +.PHONY: clean +clean: ## Clean up + cargo clean + +# Detect the current architecture +ARCH := $(shell uname -m) + +# Determine if we're on x86_64 +ifeq ($(ARCH),x86_64) + IS_X86_64 = 1 +else + IS_X86_64 = 0 +endif + +# Set build profile and flags based on architecture +ifeq ($(IS_X86_64),1) + # x86_64: Use reproducible profile with reproducible build flags + BUILD_PROFILE = reproducible + BUILD_TARGET = x86_64-unknown-linux-gnu + + # Environment variables for reproducible builds + # Initialize RUSTFLAGS + RUST_BUILD_FLAGS = + # Optimize for modern CPUs + RUST_BUILD_FLAGS += -C target-cpu=x86-64-v3 + # Remove build ID from the binary to ensure reproducibility across builds + RUST_BUILD_FLAGS += -C link-arg=-Wl,--build-id=none + # Remove metadata hash from symbol names to ensure reproducible builds + RUST_BUILD_FLAGS += -C metadata='' + # Remap paths to ensure reproducible builds + RUST_BUILD_FLAGS += --remap-path-prefix $(shell pwd)=. + # Set timestamp from last git commit for reproducible builds + SOURCE_DATE ?= $(shell git log -1 --pretty=%ct) + # Set C locale for consistent string handling and sorting + LOCALE_VAL = C + # Set UTC timezone for consistent time handling across builds + TZ_VAL = UTC + + # Environment setup for reproducible builds + BUILD_ENV = SOURCE_DATE_EPOCH=$(SOURCE_DATE) \ + RUSTFLAGS="${RUST_BUILD_FLAGS}" \ + LC_ALL=${LOCALE_VAL} \ + TZ=${TZ_VAL} \ + JEMALLOC_OVERRIDE=/usr/lib/x86_64-linux-gnu/libjemalloc.a +else + # Non-x86_64: Use release profile without reproducible build flags + BUILD_PROFILE = release + BUILD_TARGET = + RUST_BUILD_FLAGS = + BUILD_ENV = +endif + +.PHONY: build +build: ## Build (release version) + $(BUILD_ENV) cargo build --features "$(FEATURES)" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --profile $(BUILD_PROFILE) + +.PHONY: build-dev +build-dev: ## Build (debug version) + cargo build --features "$(FEATURES)" + +##@ Debian Packages + +.PHONY: install-cargo-deb +install-cargo-deb: + @command -v cargo-deb >/dev/null 2>&1 || cargo install cargo-deb@3.6.0 --locked + +.PHONY: build-deb +build-deb: install-cargo-deb ## Build Debian package + cargo deb --profile $(BUILD_PROFILE) --no-build --no-dbgsym --no-strip \ + -p attested-tls-proxy \ + $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) \ + $(if $(VERSION),--deb-version "1~$(VERSION)") + +##@ Dev + +.PHONY: lint +lint: ## Run the linters + cargo fmt -- --check + cargo clippy --workspace --features "$(FEATURES)" -- -D warnings + +.PHONY: test +test: + cargo test --verbose --features "$(FEATURES)" + +.PHONY: lt +lt: lint test ## Run "lint" and "test" + +.PHONY: fmt +fmt: ## Format the code + cargo fmt + cargo fix --allow-staged + cargo clippy --features "$(FEATURES)" --fix --allow-staged + +.PHONY: validate-config +validate-config: ## Validate the correctness of the configuration files + @for CONFIG in $(shell ls config-*.toml); do \ + cargo run --bin validate-config -- --config $$CONFIG; \ + done From c5913c3fff71cd9c0f784c34e44ec280970450f0 Mon Sep 17 00:00:00 2001 From: peg Date: Mon, 5 Jan 2026 10:53:28 +0100 Subject: [PATCH 2/6] Tidy makefile --- Makefile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Makefile b/Makefile index e90a22a..2a1b849 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,4 @@ -# Heavily inspired by Lighthouse: https://github.com/sigp/lighthouse/blob/stable/Makefile -# and Reth: https://github.com/paradigmxyz/reth/blob/main/Makefile +# Heavily inspired by rbuilder: https://github.com/flashbots/rbuilder/blob/develop/Makefile .DEFAULT_GOAL := help GIT_VER ?= $(shell git describe --tags --always --dirty="-dev") @@ -111,9 +110,3 @@ fmt: ## Format the code cargo fmt cargo fix --allow-staged cargo clippy --features "$(FEATURES)" --fix --allow-staged - -.PHONY: validate-config -validate-config: ## Validate the correctness of the configuration files - @for CONFIG in $(shell ls config-*.toml); do \ - cargo run --bin validate-config -- --config $$CONFIG; \ - done From 7be9328661d2582fbf4dd5506f75d58b305a0035 Mon Sep 17 00:00:00 2001 From: peg Date: Mon, 5 Jan 2026 10:55:49 +0100 Subject: [PATCH 3/6] Add release workflow --- .github/workflows/release.yaml | 206 +++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..36b7179 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,206 @@ +name: Release + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + draft-release: + default: false + description: "Draft Release" + required: false + type: boolean + build-docker: + default: false + description: "Build Docker" + required: false + type: boolean + build-binary: + default: true + description: "Build Binary" + required: false + type: boolean + features: + default: '' + description: "Binary Compilation Features" + options: + - '' + - 'redact-sensitive' + required: false + type: choice + +jobs: + extract-version: + name: Extract version + runs-on: warp-ubuntu-2404-x64-2x + outputs: + VERSION: ${{ steps.extract_version.outputs.VERSION }} + steps: + - name: Extract version + id: extract_version + run: | + if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + VERSION="${GITHUB_REF#refs/tags/}" + else + VERSION="$(echo ${GITHUB_SHA} | cut -c1-7)" + fi + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT + echo "${VERSION}" + + echo "### Version: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY + echo "| | |" >> $GITHUB_STEP_SUMMARY + echo "| ------------------- | ---------------------- |" >> $GITHUB_STEP_SUMMARY + echo "| \`GITHUB_REF_TYPE\` | \`${GITHUB_REF_TYPE}\` |" >> $GITHUB_STEP_SUMMARY + echo "| \`GITHUB_REF_NAME\` | \`${GITHUB_REF_NAME}\` |" >> $GITHUB_STEP_SUMMARY + echo "| \`GITHUB_REF\` | \`${GITHUB_REF}\` |" >> $GITHUB_STEP_SUMMARY + echo "| \`GITHUB_SHA\` | \`${GITHUB_SHA}\` |" >> $GITHUB_STEP_SUMMARY + echo "| \`VERSION\` | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY + echo "| \`FEATURES\` | \`${{ github.event.inputs.features || 'none' }}\` |" >> $GITHUB_STEP_SUMMARY + + build-binary: + name: Build binary + needs: extract-version + if: ${{ github.event.inputs.build-binary == 'true' || github.event_name == 'push'}} # when manually triggered or version tagged + runs-on: ${{ matrix.configs.runner }} + permissions: + contents: write + packages: write + strategy: + matrix: + configs: + - target: x86_64-unknown-linux-gnu + runner: warp-ubuntu-latest-x64-32x + profile: reproducible + features: + - ${{ github.event.inputs.features || '' }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Install rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + + - name: Build reproducible binary with Docker + run: | + RUST_TOOLCHAIN=$(rustc --version | cut -d' ' -f2) + docker build \ + --build-arg "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" \ + --build-arg "FEATURES=${{ matrix.features }}" \ + --build-arg "VERSION=${{ needs.extract-version.outputs.VERSION }}" \ + -f Dockerfile.build-deb -t atp:release \ + --output type=local,dest=./target . + + - name: Upload attested-tls-proxy artifact + uses: actions/upload-artifact@v4 + with: + name: attested-tls-proxy-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }} + path: target/${{ matrix.configs.profile }}/attested-tls-proxy + + - name: Upload *.deb package + uses: actions/upload-artifact@v4 + with: + name: deb-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }} + path: target/debian/*.deb + + + draft-release: + name: Draft release + if: ${{ github.event.inputs.draft-release == 'true' || github.event_name == 'push'}} # when manually triggered or version tagged + needs: [extract-version, build-binary] + runs-on: warp-ubuntu-2404-x64-16x + env: + VERSION: ${{ needs.extract-version.outputs.VERSION }} + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + merge-multiple: true + path: artifacts + + - name: Record artifacts checksums + working-directory: artifacts + run: | + find ./ || true + for file in *; do sha256sum "$file" >> sha256sums.txt; done; + cat sha256sums.txt + + - name: Create release draft + uses: softprops/action-gh-release@v2.0.5 + id: create-release-draft + with: + draft: true + files: artifacts/* + generate_release_notes: true + name: ${{ env.VERSION }} + tag_name: ${{ env.VERSION }} + + - name: Write Github Step Summary + run: | + echo "---" + echo "### Release Draft: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY + echo "${{ steps.create-release-draft.outputs.url }}" >> $GITHUB_STEP_SUMMARY + + # build-docker: + # if: ${{ github.event.inputs.build-docker == 'true' }} + # name: Build and publish Docker image + # needs: extract-version + # runs-on: warp-ubuntu-2404-x64-16x + # env: + # VERSION: ${{ needs.extract-version.outputs.VERSION }} + # permissions: + # contents: read + # packages: write + # + # steps: + # - name: checkout sources + # uses: actions/checkout@v4 + # + # - name: docker qemu + # uses: docker/setup-qemu-action@v3 + # + # - name: docker buildx + # uses: docker/setup-buildx-action@v3 + # + # - name: docker metadata + # uses: docker/metadata-action@v5 + # id: meta + # with: + # images: ghcr.io/${{ github.repository }} + # labels: org.opencontainers.image.source=${{ github.repositoryUrl }} + # tags: | + # type=sha + # type=semver,pattern={{version}},value=${{ env.VERSION }} + # type=semver,pattern={{major}}.{{minor}},value=${{ env.VERSION }} + # type=semver,pattern={{major}},value=${{ env.VERSION }} + # + # # Push latest tag for full version only, not for prerelease versions (i.e. not for v1.2.3-rc1) + # type=raw,value=latest,enable=${{ !contains(env.VERSION, '-') }} + # + # - name: docker login + # uses: docker/login-action@v3 + # with: + # registry: ghcr.io + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + # + # - name: docker build and push + # uses: docker/build-push-action@v5 + # with: + # cache-from: type=gha + # cache-to: type=gha,mode=max + # file: docker/Dockerfile.rbuilder + # context: . + # labels: ${{ steps.meta.outputs.labels }} + # platforms: linux/amd64 + # push: true + # tags: ${{ steps.meta.outputs.tags }} From 76bafe2b37dcfa6e57a99ed2a5be8cd895fa4b21 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 6 Jan 2026 10:08:42 +0100 Subject: [PATCH 4/6] Rm workflow stage for docker --- .github/workflows/release.yaml | 55 ---------------------------------- 1 file changed, 55 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 36b7179..43b68c9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -149,58 +149,3 @@ jobs: echo "---" echo "### Release Draft: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY echo "${{ steps.create-release-draft.outputs.url }}" >> $GITHUB_STEP_SUMMARY - - # build-docker: - # if: ${{ github.event.inputs.build-docker == 'true' }} - # name: Build and publish Docker image - # needs: extract-version - # runs-on: warp-ubuntu-2404-x64-16x - # env: - # VERSION: ${{ needs.extract-version.outputs.VERSION }} - # permissions: - # contents: read - # packages: write - # - # steps: - # - name: checkout sources - # uses: actions/checkout@v4 - # - # - name: docker qemu - # uses: docker/setup-qemu-action@v3 - # - # - name: docker buildx - # uses: docker/setup-buildx-action@v3 - # - # - name: docker metadata - # uses: docker/metadata-action@v5 - # id: meta - # with: - # images: ghcr.io/${{ github.repository }} - # labels: org.opencontainers.image.source=${{ github.repositoryUrl }} - # tags: | - # type=sha - # type=semver,pattern={{version}},value=${{ env.VERSION }} - # type=semver,pattern={{major}}.{{minor}},value=${{ env.VERSION }} - # type=semver,pattern={{major}},value=${{ env.VERSION }} - # - # # Push latest tag for full version only, not for prerelease versions (i.e. not for v1.2.3-rc1) - # type=raw,value=latest,enable=${{ !contains(env.VERSION, '-') }} - # - # - name: docker login - # uses: docker/login-action@v3 - # with: - # registry: ghcr.io - # username: ${{ github.actor }} - # password: ${{ secrets.GITHUB_TOKEN }} - # - # - name: docker build and push - # uses: docker/build-push-action@v5 - # with: - # cache-from: type=gha - # cache-to: type=gha,mode=max - # file: docker/Dockerfile.rbuilder - # context: . - # labels: ${{ steps.meta.outputs.labels }} - # platforms: linux/amd64 - # push: true - # tags: ${{ steps.meta.outputs.tags }} From 5a5fe008313bbef830a8627e9d17daa2ffe53827 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 6 Jan 2026 14:21:46 +0100 Subject: [PATCH 5/6] Apply suggestions from review and add script to check reproducibility --- Cargo.toml | 1 - Dockerfile.build-deb | 2 +- scripts/check-reproducibility.sh | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100755 scripts/check-reproducibility.sh diff --git a/Cargo.toml b/Cargo.toml index 926d895..c20cafb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,5 +83,4 @@ systemd-units = { enable = false, start = false, unit-name = "attested-tls-proxy inherits = "release" lto = "thin" panic = "abort" -codegen-units = 1 incremental = false diff --git a/Dockerfile.build-deb b/Dockerfile.build-deb index 70e83ac..dc2ff1d 100644 --- a/Dockerfile.build-deb +++ b/Dockerfile.build-deb @@ -12,7 +12,7 @@ RUN apt-get -o Acquire::Check-Valid-Until=false update && \ WORKDIR /build COPY . . -RUN SOURCE_DATE=1730000000 make build && make build-deb +RUN make build && make build-deb FROM scratch AS artifacts COPY --from=builder /build/target/x86_64-unknown-linux-gnu/ / diff --git a/scripts/check-reproducibility.sh b/scripts/check-reproducibility.sh new file mode 100755 index 0000000..1b9e6ae --- /dev/null +++ b/scripts/check-reproducibility.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Checks reproducibility by running a package build twice and printing hashes of .deb package + +set -euo pipefail + +rm -rf /tmp/repro1 /tmp/repro2 +mkdir -p /tmp/repro1 /tmp/repro2 + +docker build -f Dockerfile.build-deb --no-cache --output type=local,dest=/tmp/repro1 . +docker build -f Dockerfile.build-deb --no-cache --output type=local,dest=/tmp/repro2 . + +sha256sum /tmp/repro1/debian/*.deb +sha256sum /tmp/repro2/debian/*.deb From 2c6c793f750b29ffd5f08b98acc52a1f9cdcf186 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 6 Jan 2026 16:15:08 +0100 Subject: [PATCH 6/6] Use reproducible version of binary in deb package --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c20cafb..7509be7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ priority = "optional" maintainer-scripts = "pkg/debian" assets = [ [ - "target/release/**/attested-tls-proxy", + "target/reproducible/attested-tls-proxy", "usr/bin/", "755", ],