mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 20:31:30 +00:00
e6bb10afb6
CI run #484's Go Build & Test job failed govulncheck (M-024 hard gate). Six standard-library CVEs land in go1.25.9 + one golang.org/x/net CVE in v0.49.0; all are fixed in go1.25.10 + x/net v0.53.0 respectively. The advisories that fired were: GO-2026-4986 Quadratic string concat in net/mail.consumeComment — called via internal/api/handler/validation.go's ValidateCommonName -> mail.ParseAddress GO-2026-4977 Quadratic string concat in net/mail.consumePhrase — same call site GO-2026-4982 Bypass of meta-content URL escaping in html/template — called via internal/service/digest.go's RenderDigestHTML -> Template.Execute GO-2026-4980 Escaper bypass in html/template — same call site GO-2026-4971 Panic in net.Dial / LookupPort on Windows NUL bytes — many call sites (email notifier, SSH connector, ACME validators, validation.ValidateSafeURL, ...) GO-2026-4918 Infinite loop in net/http2 transport on bad SETTINGS_MAX_FRAME_SIZE — called via internal/connector/target/f5.go's F5Client.Authenticate -> http.Client.Do Bumps applied: * `go.mod`: `go 1.25.9` -> `go 1.25.10`; `golang.org/x/net v0.49.0` -> `v0.53.0` (kept indirect — the upgrade is force-pulled by the module-version directive; transitive deps will pick the higher). * `.github/workflows/{ci,codeql,release}.yml`: setup-go pin and the release.yml `GO_VERSION` env var bumped to 1.25.10. The security-deep-scan.yml workflow uses the major-minor `1.25` pin which auto-resolves to the latest 1.25.x and is unaffected. * `Dockerfile` + `Dockerfile.agent`: `golang:1.25-alpine@sha256:5caa...` re-pinned to `golang:1.25.10-alpine@sha256:8d22e29d960bc50cd0...` (digest looked up against `registry-1.docker.io/v2/library/golang/ manifests/1.25.10-alpine`; verified by the digest-validity ci-guard). The explicit `1.25.10-alpine` tag form replaces the moving `1.25-alpine` pin so the image-spec is reproducible end-to-end even without the digest reference. * `deploy/test/f5-mock-icontrol/Dockerfile`: `golang:1.25.9-bookworm @sha256:1a14...` re-pinned to `golang:1.25.10-bookworm@sha256: e3a54b77385b4f8a31c1...` (looked up the same way). * `deploy/test/f5-mock-icontrol/go.mod`: `go 1.25.9` -> `go 1.25.10`. * `internal/api/handler/version.go` + `api/openapi.yaml`: the `runtime.Version()`-shape comment + OpenAPI `example: go1.25.9` bumped to keep doc/example freshness. * `docs/contributor/ci-pipeline.md` + `docs/reference/connectors/ iis.md`: doc-only `Go 1.25.9` -> `Go 1.25.10` references. Verification done in-tree: * All `scripts/ci-guards/*.sh` pass locally including `digest-validity.sh` (the new digests resolve cleanly against Docker Hub). * `S-1-hardcoded-source-counts.sh` clean (the false-positive on "Bundle 1 migrations" was fixed in the prior commit). Operator step required post-push (sandbox has no Go toolchain): cd certctl && go mod tidy This regenerates go.sum's `golang.org/x/net v0.49.0` h1: lines into v0.53.0 ones. CI's `go mod tidy && git diff --exit-code go.mod go.sum` step will catch the drift if missed; in that case run the command, commit, and push the go.sum-only delta.
82 lines
3.0 KiB
Docker
82 lines
3.0 KiB
Docker
# Multi-stage build for certctl agent
|
|
#
|
|
# Bundle A / Audit H-001 (CWE-829): every FROM line is pinned to an
|
|
# immutable digest. See Dockerfile (server) for the bump-procedure
|
|
# operator runbook; the pins here MUST be bumped in the same pass.
|
|
|
|
# Stage 1: Build
|
|
FROM golang:1.25.10-alpine@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS builder
|
|
|
|
# Proxy propagation (M-4, Issue #9) — defaulted to empty so un-proxied builds
|
|
# behave identically to the pre-fix tree. When `HTTP_PROXY`/`HTTPS_PROXY`/
|
|
# `NO_PROXY` are forwarded via `docker build --build-arg` (or compose
|
|
# `build.args`), they are re-exported as ENV with both upper- and lower-case
|
|
# names because apk and curl read the lowercase variants while Go reads the
|
|
# uppercase ones.
|
|
ARG HTTP_PROXY=
|
|
ARG HTTPS_PROXY=
|
|
ARG NO_PROXY=
|
|
ENV HTTP_PROXY=${HTTP_PROXY} \
|
|
HTTPS_PROXY=${HTTPS_PROXY} \
|
|
NO_PROXY=${NO_PROXY} \
|
|
http_proxy=${HTTP_PROXY} \
|
|
https_proxy=${HTTPS_PROXY} \
|
|
no_proxy=${NO_PROXY}
|
|
|
|
RUN apk add --no-cache git ca-certificates
|
|
|
|
WORKDIR /app
|
|
|
|
COPY go.mod go.sum ./
|
|
RUN go mod download
|
|
|
|
COPY . .
|
|
|
|
ARG TARGETARCH=amd64
|
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build \
|
|
-ldflags="-w -s" \
|
|
-o bin/agent \
|
|
./cmd/agent
|
|
|
|
# Stage 2: Runtime
|
|
FROM alpine:3.19@sha256:6baf43584bcb78f2e5847d1de515f23499913ac9f12bdf834811a3145eb11ca1
|
|
|
|
# U-2: `procps` ships pgrep, which the HEALTHCHECK below uses to verify the
|
|
# agent process is alive. Pre-U-2 the deploy/docker-compose.yml agent
|
|
# HEALTHCHECK called `pgrep -f certctl-agent` against this image but
|
|
# pgrep wasn't installed — the compose probe was a latent always-fail.
|
|
# Adding procps here fixes both the new image-level HEALTHCHECK and the
|
|
# pre-existing compose override. Adds ~250KB to the image; acceptable for
|
|
# observability parity with the server image.
|
|
RUN apk add --no-cache ca-certificates curl procps
|
|
|
|
RUN addgroup -g 1000 certctl && \
|
|
adduser -D -u 1000 -G certctl certctl
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=builder /app/bin/agent .
|
|
|
|
# Create key storage directory for agent-side keygen
|
|
RUN mkdir -p /var/lib/certctl/keys && \
|
|
chown -R certctl:certctl /app /var/lib/certctl
|
|
|
|
USER certctl
|
|
|
|
# Image-level HEALTHCHECK for bare `docker run` / Docker Swarm / Nomad / ECS.
|
|
#
|
|
# U-2 (P1, cat-u-healthcheck_protocol_mismatch — adjacent fix): the agent
|
|
# has no HTTP listener (it polls the server via outbound HTTPS), so a
|
|
# process-presence check is the correct primitive. Pre-U-2 the agent image
|
|
# shipped with no HEALTHCHECK at all, so bare-`docker run` operators got
|
|
# zero health signal and orchestrators that key off Docker's HEALTHCHECK
|
|
# (Swarm, Nomad, ECS) saw the container reported as `none`. The compose
|
|
# override at deploy/docker-compose.yml:173 used the same `pgrep -f
|
|
# certctl-agent` shape; we mirror it here so the published image has
|
|
# parity with the compose stack and the override on docker-compose.yml
|
|
# becomes redundant-but-correct rather than load-bearing.
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD pgrep -f certctl-agent > /dev/null || exit 1
|
|
|
|
ENTRYPOINT ["/app/agent"]
|