Files
netbird/e2e/harness/Dockerfile.nblink
T
Maycon Santos 66a28fd666 [client] Add nblink, an unprivileged forwarder into the network (#7955)
Reaching an internal service meant installing the agent, which needs root
for a TUN device. nblink runs the embedded client in netstack mode and
forwards local HTTP listeners to upstreams inside the tunnel, so it works on
managed machines and in rootless containers. Upstream names resolve
in-process.

Forwards bind loopback unless --allow-public-bind is given. The listener
refuses rebound and cross-site browser requests and bounds stalled request
bodies. It ships as release archives and a distroless image that runs under
an arbitrary UID.

An embedded client given no StatePath now keeps its state in memory rather
than falling back to the installed agent's state file, which every embedded
client in a proxy process also shared. The state manager gets an explicit
in-memory store for it.
2026-10-12 13:54:15 +02:00

38 lines
1.6 KiB
Docker

# Multistage build for nblink, used in e2e tests. The release image
# (client/Dockerfile-nblink) packages a goreleaser artifact, so this compiles
# from source the way Dockerfile.client does for the agent, while keeping the
# release image's runtime shape: distroless, non-root, numeric UID.
#
# The runtime stage deliberately grants nothing. nblink's claim is that it
# needs no TUN device and no capabilities, so an image or a container request
# 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
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -o /out/nblink ./client/link/cmd/nblink \
&& mkdir -p /out/state/nblink && chmod 770 /out/state/nblink
FROM gcr.io/distroless/static-debian13:nonroot
# Same state directory as the release image, so a volume mounted over it
# starts out owned by 65532:0 and the identity-persistence case runs against
# the ownership the release image ships.
COPY --from=builder --chown=65532:0 /out/state/ /var/lib/
# Numeric, as in the release image: the runtime may substitute its own UID and
# there is no passwd entry to look up.
USER 65532:0
# No NB_STATE_DIR by default. State stays in memory and each run registers a
# fresh peer; the persistence case sets it explicitly with a volume.
ENV NB_LOG_LEVEL=info
COPY --from=builder /out/nblink /usr/local/bin/nblink
ENTRYPOINT ["/usr/local/bin/nblink"]