From 16e52aaadf3cfb76c0d67f2bfdf94766a511053b Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Wed, 29 Oct 2025 21:26:44 +0900 Subject: [PATCH 1/5] docker: switch base image from distroless/base to distroless/static:nonroot go-httpbin is built fully statically and does not depend on libc, so it can use the distroless/static image. This change reduces the resulting image size by about half. Since go-httpbin's default listening port is 8080, an unprivileged port, it can run as non-root. While this may break setups that use privileged ports, running as non-root provides a clear security advantage. Such users can continue using their ports by adding the CAP_NET_BIND_SERVICE capability. Signed-off-by: Kohei YOSHIDA --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4680433..f1c3910 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ COPY . . RUN --mount=type=cache,id=gobuild,target=/root/.cache/go-build \ make build buildtests -FROM gcr.io/distroless/base +FROM gcr.io/distroless/static:nonroot COPY --from=build /go/src/github.com/mccutchen/go-httpbin/dist/go-httpbin* /bin/ From 8bc2d3116619eee75016d884101755b34713f1e3 Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Thu, 30 Oct 2025 23:11:13 +0900 Subject: [PATCH 2/5] update README.md to reflect container image change to run as non-root Signed-off-by: Kohei YOSHIDA --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index e3ded9a..22fd497 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,36 @@ $ docker run -P ghcr.io/mccutchen/go-httpbin $ docker run -e HTTPS_CERT_FILE='/tmp/server.crt' -e HTTPS_KEY_FILE='/tmp/server.key' -p 8080:8080 -v /tmp:/tmp ghcr.io/mccutchen/go-httpbin ``` +#### Run as non-root + +Prebuilt images now run as a non-root user by default. This improves container +security, but some configurations may require additional care. + +For example, if you run go-httpbin on a privileged port (i.e. below 1024) using +the Docker host network, you may need to run the container as root in order to +enable the `CAP_NET_BIND_SERVICE` capability. Note that this is normally not +required when using other network modes. + +```bash +$ docker run \ + --network host \ + --user root \ + --cap-drop ALL \ + --cap-add CAP_NET_BIND_SERVICE \ + ghcr.io/mccutchen/go-httpbin \ + /bin/go-httpbin -port=80 +``` + +If you enable HTTPS directly in go-httpbin, make sure that the certificate and +private key files are readable by the user running the process. + +```bash +$ chmod 644 /tmp/server.crt +$ chmod 640 /tmp/server.key +# GID 65532: primary group of the nonroot user in distroless/static:nonroot. +$ chown root:65532 /tmp/server.crt /tmp/server.key +``` + ### Kubernetes ``` From f8c53ac64b94a377f212aa5793baa627d7c040f8 Mon Sep 17 00:00:00 2001 From: Kohei YOSHIDA Date: Thu, 30 Oct 2025 23:12:48 +0900 Subject: [PATCH 3/5] set securityContext.runAsNonRoot explicitly in Kubernetes Deployment Signed-off-by: Kohei YOSHIDA --- kustomize/resources.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kustomize/resources.yaml b/kustomize/resources.yaml index fc88712..66ab9cd 100644 --- a/kustomize/resources.yaml +++ b/kustomize/resources.yaml @@ -21,6 +21,8 @@ spec: path: /status/200 port: http resources: {} + securityContext: + runAsNonRoot: true --- apiVersion: v1 kind: Service From 05aa999182eb304c8cd6b556833f807463066edb Mon Sep 17 00:00:00 2001 From: Will McCutchen Date: Fri, 31 Oct 2025 14:00:26 -0400 Subject: [PATCH 4/5] tweak README --- README.md | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 22fd497..56ee4cb 100644 --- a/README.md +++ b/README.md @@ -19,42 +19,13 @@ automatically published to these public registries for every tagged release: - [mccutchen/go-httpbin][docker-hub] ```bash -# Run http server $ docker run -P ghcr.io/mccutchen/go-httpbin - -# Run https server -$ docker run -e HTTPS_CERT_FILE='/tmp/server.crt' -e HTTPS_KEY_FILE='/tmp/server.key' -p 8080:8080 -v /tmp:/tmp ghcr.io/mccutchen/go-httpbin -``` - -#### Run as non-root - -Prebuilt images now run as a non-root user by default. This improves container -security, but some configurations may require additional care. - -For example, if you run go-httpbin on a privileged port (i.e. below 1024) using -the Docker host network, you may need to run the container as root in order to -enable the `CAP_NET_BIND_SERVICE` capability. Note that this is normally not -required when using other network modes. - -```bash -$ docker run \ - --network host \ - --user root \ - --cap-drop ALL \ - --cap-add CAP_NET_BIND_SERVICE \ - ghcr.io/mccutchen/go-httpbin \ - /bin/go-httpbin -port=80 ``` -If you enable HTTPS directly in go-httpbin, make sure that the certificate and -private key files are readable by the user running the process. - -```bash -$ chmod 644 /tmp/server.crt -$ chmod 640 /tmp/server.key -# GID 65532: primary group of the nonroot user in distroless/static:nonroot. -$ chown root:65532 /tmp/server.crt /tmp/server.key -``` +> [!NOTE] +> Prebuilt image versions >= 2.19.0 run as a non-root user by default. See +> [Configuring non-root docker images](#configuring-non-root-docker-images) +> below for details. ### Kubernetes @@ -139,15 +110,44 @@ variables (or a combination of the two): | `-srv-read-timeout` | `SRV_READ_TIMEOUT` | Value to use for the http.Server's ReadTimeout option | 5s | | `-use-real-hostname` | `USE_REAL_HOSTNAME` | Expose real hostname as reported by os.Hostname() in the /hostname endpoint | false | -#### ⚠️ **HERE BE DRAGONS** ⚠️ - -These configuration options are dangerous and/or deprecated and should be -avoided unless backwards compatibility is absolutely required. +> [!WARNING] +> These configuration options are dangerous and/or deprecated and should be +> avoided unless backwards compatibility is absolutely required. | Argument| Env var | Documentation | Default | | - | - | - | - | | `-unsafe-allow-dangerous-responses` | `UNSAFE_ALLOW_DANGEROUS_RESPONSES` | Allow endpoints to return unescaped HTML when clients control response Content-Type (enables XSS attacks) | false | +#### Configuring non-root docker images + +Prebuilt image versions >= 2.19.0 run as a non-root user by default to improve +container security at the cost of additional complexity for some non-standard +deployments: + +- To run the go-httpbin image a) on a privileged port (i.e. below 1024) _and_ + b) using the Docker host network, you may need to run the container as root + in order to enable the `CAP_NET_BIND_SERVICE` capability: + + ```bash + $ docker run \ + --network host \ + --user root \ + --cap-drop ALL \ + --cap-add CAP_NET_BIND_SERVICE \ + ghcr.io/mccutchen/go-httpbin \ + /bin/go-httpbin -port=80 + ``` + +- If you enable HTTPS directly in the image, make sure that the certificate + and private key files are readable by the user running the process: + + ```bash + $ chmod 644 /tmp/server.crt + $ chmod 640 /tmp/server.key + # GID 65532: primary group of the nonroot user in distroless/static:nonroot. + $ chown root:65532 /tmp/server.crt /tmp/server.key + ``` + **Notes:** - Command line arguments take precedence over environment variables. - See [Production considerations] for recommendations around safe configuration From 50e4fdf16f5df2be5e4170eff2c45e39b96d874d Mon Sep 17 00:00:00 2001 From: Will McCutchen Date: Fri, 31 Oct 2025 14:16:31 -0400 Subject: [PATCH 5/5] another tweak --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 56ee4cb..71db1f8 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,11 @@ variables (or a combination of the two): | - | - | - | - | | `-unsafe-allow-dangerous-responses` | `UNSAFE_ALLOW_DANGEROUS_RESPONSES` | Allow endpoints to return unescaped HTML when clients control response Content-Type (enables XSS attacks) | false | +**Notes:** +- Command line arguments take precedence over environment variables. +- See [Production considerations] for recommendations around safe configuration + of public instances of go-httpbin + #### Configuring non-root docker images Prebuilt image versions >= 2.19.0 run as a non-root user by default to improve @@ -148,12 +153,6 @@ deployments: $ chown root:65532 /tmp/server.crt /tmp/server.key ``` -**Notes:** -- Command line arguments take precedence over environment variables. -- See [Production considerations] for recommendations around safe configuration - of public instances of go-httpbin - - ## Installation To add go-httpbin as a dependency to an existing golang project (e.g. for use