8000 chore(vendor): pin and verify pre-built gvproxy switch binary by norrietaylor · Pull Request #503 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/ci-gvproxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI gvproxy

# Fetches the pinned pre-built gvproxy switch binary (gvisor-tap-vsock) and
# verifies its SHA-256 against vendor/gvproxy/gvproxy.lock. No build, no Go
# toolchain — the upstream release binary is downloaded and checksum-verified
# (architecture assumption gvproxy-source-build, amended to a pinned pre-built
# binary with checked-in digests).
on:
pull_request:
branches: ["main"]
paths:
- "vendor/gvproxy/**"
- "scripts/fetch-gvproxy.sh"
- ".github/workflows/ci-gvproxy.yml"
push:
branches: ["main"]
paths:
- "vendor/gvproxy/**"
- "scripts/fetch-gvproxy.sh"
- ".github/workflows/ci-gvproxy.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
verify-gvproxy:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- name: Fetch and verify pinned gvproxy binary
run: bash scripts/fetch-gvproxy.sh "${RUNNER_TEMP}/gvproxy"
- name: Record pinned version + digest
run: |
{
echo "### gvproxy (pinned pre-built)"
echo ""
echo "- version: \`$(sed -n 's/^version=//p' vendor/gvproxy/gvproxy.lock)\`"
echo "- linux-amd64 sha256: \`$(sha256sum "${RUNNER_TEMP}/gvproxy" | awk '{print $1}')\`"
} >> "${GITHUB_STEP_SUMMARY}"
- name: Upload gvproxy binary
uses: actions/upload-artifact@v4
with:
name: gvproxy-linux-amd64
path: ${{ runner.temp }}/gvproxy
if-no-files-found: error
2 changes: 1 addition & 1 deletion docs/specs/03-spec-networking/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ proposed here is the typed replacement for that placeholder.
| `minvmd-owns-vm-gvproxy` | On DM1/3/4, minvmd owns the gvproxy process that serves the libkrun VM; minimald owns the gvproxy that serves DM2 PTasks | settled | spec R1.4; prior arch-minvmd-host-daemon delegates network lifecycle to the VM supervisor; minimald is the process that creates and destroys DM2 PTasks |
| `dynamic-portmap-api-http` | Dynamic port-mapping requests from within a PTask (R2.4) use HTTP to gvproxy's management endpoint at the gateway IP | settled | spec § "Technical Considerations" references gvproxy's port-forward API; gvproxy's management HTTP endpoint is its standard API surface for port mapping; accessible from any OwnIp PTask without additional infrastructure |
| `dm2-uc5-collapse` | VM-wide egress (UC5) is a configuration error on DM2 (native Linux, no VM boundary); UC5 collapses to UC3 on DM2 | settled | spec R2.5 explicitly states this; DM2 has no VM boundary — `vm_egress` applies only when minvmd owns the VM |
| `gvproxy-source-build` | gvproxy is built from vendored Go source rather than downloaded as a pre-built binary | settled | spec § "Technical Considerations": "Building from source is preferred for reproducibility and eliminates supply-chain risk" (informed by spec-networking) |
| `gvproxy-source-build` | gvproxy ships as a pinned **pre-built** release binary (gvisor-tap-vsock v0.8.9), fetched and verified against checked-in SHA-256 digests in `vendor/gvproxy/gvproxy.lock` via `scripts/fetch-gvproxy.sh` — not built from source | settled (maintainer decision; supersedes the spec's source-build preference) | spec § "Technical Considerations" lists a SHA-256-verified pre-built binary as the accepted alternative; chosen to avoid a Go toolchain + module-proxy egress in the build sandbox; supply-chain risk mitigated by pinned upstream digests (#495) |
| `https-proxy-hyper-rustls` | The Unit 4 HTTPS reverse proxy uses hyper/axum for HTTP and rustls for TLS, matching the workspace's existing ecosystem | settled | spec § "Technical Considerations"; `rustls` is listed as a no-OpenSSL-dependency choice; `hyper`/`axum` are named as consistent with workspace deps |
| `dns-hostname-mechanism` | The system resolver supports PTask hostname registration without root privilege per-invocation via either `*.localhost` wildcard (rootless on macOS; requires systemd-resolved or NetworkManager on Linux) or a one-time `/etc/resolver`-equivalent setup | needs-spike | spec Open Questions item 1: "Decision needed before Unit 3 implementation begins"; whether `*.localhost` wildcard resolution is reliably available on common Linux distributions (Ubuntu, Fedora, Arch, Debian) is not settleable from the repo working tree; R3.4 requires rootless per-invocation operation |
| `wireguard-implementation` | Unit 4 WireGuard implementation is **boringtun** (pure Rust); wireguard-go subprocess is the v2 escalation path if peer coordination is needed or boringtun stalls | settled | spike #486 concluded boringtun for v1: clean Cargo feature-flag support for R4.7, zero additional build-chain dependencies, sufficient production maturity (Cloudflare WARP, Mullvad VPN) for the AllowedIPs-based subnet-router model; cgo path substantially more complex than hypothesised; maintainer confirmed on #478 (informed by #486) |
Expand Down
37 changes: 37 additions & 0 deletions scripts/fetch-gvproxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Download the pinned gvproxy (gvisor-tap-vsock) release binary for the host
# platform and verify its SHA-256 against vendor/gvproxy/gvproxy.lock.
# No build, no Go toolchain. minimald spawns this binary as the per-host switch.
set -euo pipefail

here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
lock="${here}/../vendor/gvproxy/gvproxy.lock"
out="${1:-./gvproxy}"

ver="$(sed -n 's/^version=//p' "$lock")"
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) asset=gvproxy-linux-amd64 ;;
Linux-aarch64) asset=gvproxy-linux-arm64 ;;
Darwin-*) asset=gvproxy-darwin ;;
*) echo "fetch-gvproxy: unsupported platform $(uname -s)-$(uname -m)" >&2; exit 1 ;;
esac
want="$(sed -n "s/^${asset}=//p" "$lock")"
[ -n "$want" ] || { echo "fetch-gvproxy: no pinned digest for ${asset}" >&2; exit 1; }

url="https://github.com/containers/gvisor-tap-vsock/releases/download/${ver}/${asset}"
echo "fetch-gvproxy: downloading ${url}"
curl -fsSL "$url" -o "$out"

if command -v sha256sum >/dev/null 2>&1; then
got="$(sha256sum "$out" | awk '{print $1}')"
else
got="$(shasum -a 256 "$out" | awk '{print $1}')"
fi
if [ "$got" != "$want" ]; then
echo "fetch-gvproxy: SHA-256 mismatch for ${asset}" >&2
echo " got: ${got}" >&2
echo " want: ${want}" >&2
rm -f "$out"; exit 1
fi
chmod +x "$out"
echo "fetch-gvproxy: ${asset} ${ver} verified (${got})"
7 changes: 7 additions & 0 deletions vendor/gvproxy/gvproxy.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# gvproxy (gvisor-tap-vsock) pinned pre-built release, verified by SHA-256.
# Source: https://github.com/containers/gvisor-tap-vsock/releases/tag/v0.8.9
# Digests are the upstream-published sha256sums for each release asset.
version=v0.8.9
gvproxy-linux-amd64=3011c5629c9138d2050fb23c510e09ae53e30ec52e6a9ab85632bc1550e8ef63
gvproxy-linux-arm64=6ecca02839254c9a0cc184bba7aac63755a22d7ed10d455b852528a99d7f7d4b
gvproxy-darwin=c6f7b4bc7f21bf810b5cf54e04d979b014c5d96472a03a9e97fe62a00940067c
Loading
0