From c051ca8f8767617091ce8fdb23edccd83487cba0 Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Sat, 24 Oct 2026 01:07:20 +0200 Subject: [PATCH] [client,proxy,management,signal,relay] Distrust compromised eMudhra CA keys (#8326) * [client,proxy,management,signal,relay] Distrust compromised eMudhra CA keys Eight eMudhra intermediate CA private keys were compromised and browsers blocked them on 2026-10-17. Our binaries were built with go1.26.7, which accepts chains through those intermediates whenever the trust store still holds emSign ECC Root CA - G3. go1.26.10 rejects them in crypto/x509 on every platform, regardless of the trust store. The UBI base still ships the root and Red Hat has no fixed package yet, so the UBI images blocklist it with p11-kit. The ingest image, the UI server image and the pinned Chainguard digests also carried the root and move to bases that no longer do. * [client,proxy,management,signal,relay] Use the fixed UBI base instead of a blocklist Red Hat shipped ca-certificates 2026.2.92_v9.0.319-90.3 on 2026-10-22, which drops emSign ECC Root CA - G3 and AAA Certificate Services. The current ubi9-minimal image carries it, so pin that digest and remove the p11-kit blocklist step. * [misc] Pin upload-server images by digest only and restore go.mod comment --- .devcontainer/Dockerfile | 2 +- .github/workflows/golang-test-linux.yml | 2 +- client/Dockerfile-rootless.ubi | 2 +- client/internal/metrics/infra/ingest/Dockerfile | 4 ++-- client/testutil/privileged/runner_test.go | 2 +- client/ui/build/docker/Dockerfile.cross | 2 +- client/ui/build/docker/Dockerfile.server | 4 ++-- combined/Dockerfile.multistage | 2 +- combined/Dockerfile.ubi | 2 +- docs/testing-privileged.md | 2 +- e2e/harness/Dockerfile.client | 2 +- e2e/harness/Dockerfile.nblink | 2 +- go.mod | 2 +- management/Dockerfile.multistage | 2 +- management/Dockerfile.ubi | 2 +- proxy/Dockerfile | 2 +- proxy/Dockerfile.multistage | 2 +- proxy/Dockerfile.ubi | 2 +- relay/Dockerfile.ubi | 2 +- signal/Dockerfile.ubi | 2 +- upload-server/Dockerfile | 11 ++++++----- 21 files changed, 28 insertions(+), 27 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9b6a0edfd..dc7475a06 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26.7-bookworm +FROM golang:1.26.10-bookworm RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends\ diff --git a/.github/workflows/golang-test-linux.yml b/.github/workflows/golang-test-linux.yml index b3e4dd4f7..eea69eaa7 100644 --- a/.github/workflows/golang-test-linux.yml +++ b/.github/workflows/golang-test-linux.yml @@ -303,7 +303,7 @@ jobs: -e GOCACHE=${CONTAINER_GOCACHE} \ -e GOMODCACHE=${CONTAINER_GOMODCACHE} \ -e CONTAINER=${CONTAINER} \ - golang:1.26.7-alpine \ + golang:1.26.10-alpine \ sh -c ' \ apk update; apk add --no-cache \ ca-certificates iptables ip6tables dbus dbus-dev libpcap-dev build-base; \ diff --git a/client/Dockerfile-rootless.ubi b/client/Dockerfile-rootless.ubi index 4701728c1..396e0d562 100644 --- a/client/Dockerfile-rootless.ubi +++ b/client/Dockerfile-rootless.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG NETBIRD_BINARY=$TARGETPLATFORM/netbird diff --git a/client/internal/metrics/infra/ingest/Dockerfile b/client/internal/metrics/infra/ingest/Dockerfile index 3620c524b..1b4862a7d 100644 --- a/client/internal/metrics/infra/ingest/Dockerfile +++ b/client/internal/metrics/infra/ingest/Dockerfile @@ -1,9 +1,9 @@ -FROM golang:1.25-alpine AS build +FROM golang:1.26.10-alpine AS build WORKDIR /app COPY go.mod main.go ./ RUN CGO_ENABLED=0 go build -o ingest . -FROM alpine:3.20 +FROM alpine:3.24 RUN adduser -D -H ingest COPY --from=build /app/ingest /usr/local/bin/ingest USER ingest diff --git a/client/testutil/privileged/runner_test.go b/client/testutil/privileged/runner_test.go index 157005d3e..c7bde1316 100644 --- a/client/testutil/privileged/runner_test.go +++ b/client/testutil/privileged/runner_test.go @@ -25,7 +25,7 @@ import ( // (.github/workflows/golang-test-linux.yml, test_client_on_docker). const ( containerImage = "golang" - containerTag = "1.26.7-alpine" + containerTag = "1.26.10-alpine" ) const ( diff --git a/client/ui/build/docker/Dockerfile.cross b/client/ui/build/docker/Dockerfile.cross index 55c0d69e1..650087fb3 100644 --- a/client/ui/build/docker/Dockerfile.cross +++ b/client/ui/build/docker/Dockerfile.cross @@ -13,7 +13,7 @@ # docker run --rm -v $(pwd):/app wails-cross windows amd64 # docker run --rm -v $(pwd):/app wails-cross windows arm64 -FROM golang:1.26.7-bookworm +FROM golang:1.26.10-bookworm ARG TARGETARCH diff --git a/client/ui/build/docker/Dockerfile.server b/client/ui/build/docker/Dockerfile.server index 57183f1d2..7a7f36575 100644 --- a/client/ui/build/docker/Dockerfile.server +++ b/client/ui/build/docker/Dockerfile.server @@ -2,7 +2,7 @@ # Multi-stage build for minimal image size # Build stage -FROM golang:1.26.7-alpine AS builder +FROM golang:1.26.10-alpine AS builder WORKDIR /app @@ -22,7 +22,7 @@ RUN go mod tidy RUN go build -tags server -ldflags="-s -w" -o server . # Runtime stage - minimal image -FROM gcr.io/distroless/static-debian12 +FROM gcr.io/distroless/static-debian13 # Copy the binary COPY --from=builder /app/server /server diff --git a/combined/Dockerfile.multistage b/combined/Dockerfile.multistage index 011379c2f..0551516fd 100644 --- a/combined/Dockerfile.multistage +++ b/combined/Dockerfile.multistage @@ -1,4 +1,4 @@ -FROM golang:1.26.7-bookworm AS builder +FROM golang:1.26.10-bookworm AS builder WORKDIR /app # Install build dependencies diff --git a/combined/Dockerfile.ubi b/combined/Dockerfile.ubi index 66ef55a34..dbbb920c9 100644 --- a/combined/Dockerfile.ubi +++ b/combined/Dockerfile.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG VERSION=dev diff --git a/docs/testing-privileged.md b/docs/testing-privileged.md index 939770de9..7d9552c4a 100644 --- a/docs/testing-privileged.md +++ b/docs/testing-privileged.md @@ -32,7 +32,7 @@ list; both are optional and default to the full privileged suite. 1. Skips immediately when it detects it is already inside the container (`DOCKER_CI=true`), so the privileged tests run in place instead of recursing. -2. Otherwise spins up a `golang:1.26.7-alpine` container (matching CI), +2. Otherwise spins up a `golang:1.26.10-alpine` container (matching CI), bind-mounts the repo and the host Go build/module caches, installs the required packages, and runs `go test -tags 'devcert privileged'` over the client packages. diff --git a/e2e/harness/Dockerfile.client b/e2e/harness/Dockerfile.client index 4c76b95c6..4bcb2b079 100644 --- a/e2e/harness/Dockerfile.client +++ b/e2e/harness/Dockerfile.client @@ -3,7 +3,7 @@ # artifact), so this mirrors its alpine runtime + entrypoint while compiling the # CGO-free client inline. BuildKit cache mounts keep rebuilds incremental. -FROM golang:1.26.7-bookworm AS builder +FROM golang:1.26.10-bookworm AS builder WORKDIR /src COPY go.mod go.sum ./ RUN --mount=type=cache,target=/go/pkg/mod go mod download diff --git a/e2e/harness/Dockerfile.nblink b/e2e/harness/Dockerfile.nblink index dac3aceec..0628aa083 100644 --- a/e2e/harness/Dockerfile.nblink +++ b/e2e/harness/Dockerfile.nblink @@ -8,7 +8,7 @@ # that quietly hands it NET_ADMIN would make the suite prove the opposite of # what it is for. -FROM golang:1.26.7-bookworm AS builder +FROM golang:1.26.10-bookworm AS builder WORKDIR /src COPY go.mod go.sum ./ RUN --mount=type=cache,target=/go/pkg/mod go mod download diff --git a/go.mod b/go.mod index f93141d5c..0d1492731 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.26.0 // Pin the toolchain to a patch release >= go1.26.2 // See https://go.dev/issue/77875. -toolchain go1.26.7 +toolchain go1.26.10 require ( cunicu.li/go-rosenpass v0.5.42 diff --git a/management/Dockerfile.multistage b/management/Dockerfile.multistage index 5d037f1b1..1e9d11227 100644 --- a/management/Dockerfile.multistage +++ b/management/Dockerfile.multistage @@ -1,4 +1,4 @@ -FROM golang:1.26.7-bookworm AS builder +FROM golang:1.26.10-bookworm AS builder WORKDIR /app # Install build dependencies diff --git a/management/Dockerfile.ubi b/management/Dockerfile.ubi index 628d1a086..163302aa9 100644 --- a/management/Dockerfile.ubi +++ b/management/Dockerfile.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG VERSION=dev diff --git a/proxy/Dockerfile b/proxy/Dockerfile index 5944d944e..e4f9a0239 100644 --- a/proxy/Dockerfile +++ b/proxy/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26.7-alpine AS builder +FROM golang:1.26.10-alpine AS builder WORKDIR /app RUN echo "netbird:x:1000:1000:netbird:/var/lib/netbird:/sbin/nologin" > /tmp/passwd && \ diff --git a/proxy/Dockerfile.multistage b/proxy/Dockerfile.multistage index d1db32296..ff46280d2 100644 --- a/proxy/Dockerfile.multistage +++ b/proxy/Dockerfile.multistage @@ -1,4 +1,4 @@ -FROM golang:1.26.7-alpine AS builder +FROM golang:1.26.10-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ diff --git a/proxy/Dockerfile.ubi b/proxy/Dockerfile.ubi index a74280a49..013eb423d 100644 --- a/proxy/Dockerfile.ubi +++ b/proxy/Dockerfile.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG VERSION=dev diff --git a/relay/Dockerfile.ubi b/relay/Dockerfile.ubi index 86b0cbc01..b4987a424 100644 --- a/relay/Dockerfile.ubi +++ b/relay/Dockerfile.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG VERSION=dev diff --git a/signal/Dockerfile.ubi b/signal/Dockerfile.ubi index f0a6552da..5b4036469 100644 --- a/signal/Dockerfile.ubi +++ b/signal/Dockerfile.ubi @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:7fbeae18dc9476399f565e68255f602a3374ea8614ba3d14843565131a13ff93 +FROM registry.access.redhat.com/ubi9/ubi-minimal@sha256:2d4c4551af6831dcd26bbf86108c4385de5183ec8fe6b5868f6f9640fe47f4ed ARG TARGETPLATFORM ARG VERSION=dev diff --git a/upload-server/Dockerfile b/upload-server/Dockerfile index 8098a0186..16fd79871 100644 --- a/upload-server/Dockerfile +++ b/upload-server/Dockerfile @@ -16,13 +16,14 @@ # VARIANT=release|debug debug swaps the base for Chainguard busybox (a shell) # VERSION stamped into the binary the same way goreleaser does # -# Chainguard publishes only :latest for free, so the bases are pinned by digest -# and moved by Dependabot. +# Images are pinned by digest alone. The builder is golang:1.26.10-bookworm and +# the bases are Chainguard's :latest, the only free tag; bump them by hand with +# docker buildx imagetools inspect . ARG VARIANT=release # Pure Go: cross-compile from the build host instead of emulating the target. -FROM --platform=$BUILDPLATFORM golang:1.26.7-bookworm@sha256:e8c859f5632dcfde7b32d2012b4351728f6437930887c2f6a91ea242459e5514 AS builder +FROM --platform=$BUILDPLATFORM golang@sha256:632dff7351799a5a9954a48dc06670ade72ee44e8c351cdc0e5a57af2fea21af AS builder WORKDIR /app COPY go.mod go.sum ./ @@ -39,8 +40,8 @@ RUN --mount=type=cache,target=/go/pkg/mod \ -o /out/netbird-upload ./upload-server \ && mkdir -p /out/var/lib/netbird -FROM cgr.dev/chainguard/static:latest@sha256:41e17ed83c594a64a9396b6ab96dd26d5ddc290dacf4c177464712ff21ad534f AS base-release -FROM cgr.dev/chainguard/busybox:latest@sha256:b2953ab1cae4a6265e18cf675851bd99975211b150d7a014774911d76eb309ba AS base-debug +FROM cgr.dev/chainguard/static@sha256:17367e4d3ae2b46c3290858e483fac09be085c92b372360fe3bf6a6150848fde AS base-release +FROM cgr.dev/chainguard/busybox@sha256:98e9e7306c899a8af252ef1ff50c54def91c2fe04677298eafdf0b902f2980ed AS base-debug # hadolint ignore=DL3006 FROM base-${VARIANT}