Files
netbird/docs/testing-privileged.md
T
Maycon Santos c051ca8f87 [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
2026-10-24 01:07:20 +02:00

2.8 KiB

Privileged tests

Some tests in this repo need root or mutate host network state: they create TUN/WireGuard interfaces, open netlink/raw sockets, or shell out to ip/iptables/nft/ifconfig/route. Running them on a developer machine would require sudo and could leave stray interfaces or routes behind.

These tests are gated behind the privileged build tag so the default test run is host-safe.

Running tests

# Host-safe: excludes privileged tests. Runs as a normal user, no sudo.
make test-unit
# equivalently:
go test -tags devcert ./...

# Privileged suite: runs the privileged-tagged tests inside a
# --privileged --cap-add=NET_ADMIN container (requires Docker).
make test-privileged

# Narrow the container run to a single test / package:
PRIV_RUN=TestNftablesManager PRIV_PKGS=./client/firewall/nftables/... make test-privileged

PRIV_RUN adds a -run test-name filter and PRIV_PKGS overrides the package list; both are optional and default to the full privileged suite.

make test-privileged invokes the ory/dockertest harness in client/testutil/privileged/. The harness:

  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.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.
  3. Streams the container's output to the test log and fails if the suite fails.

Adding a privileged test

A test is privileged if it does any of:

  • creates a real interface via iface.NewWGIFace(...).Create(),
  • opens a netlink or raw socket that hard-fails without CAP_NET_ADMIN,
  • shells out to ip, iptables, nft, ifconfig, or route to change state.

Add the tag to the top of the file, combined with any existing platform constraint:

//go:build privileged && linux

package foo

If a file mixes privileged and pure-logic tests, split it: keep the pure tests (and any shared data — type/var declarations, table-driven testCases, helper interfaces) in an untagged file, and move the privileged tests into a *_privileged_test.go file with the tag. Shared declarations must stay untagged, otherwise the unprivileged files in the package will not compile.

Always verify both build modes compile on every target platform:

go vet -tags devcert ./...
go vet -tags 'devcert privileged' ./...

CI

  • The Client / Unit job runs go test -tags devcert with no sudo — only host-safe tests.
  • The Client (Docker) / Unit job runs go test -tags 'devcert privileged' inside a --privileged --cap-add=NET_ADMIN container, which is where the privileged tests actually execute.