From ebc035e308e1fbd069965cce3dbf8cd44509bdfe Mon Sep 17 00:00:00 2001 From: collin-lee Date: Mon, 27 Oct 2025 09:56:32 -0700 Subject: [PATCH 1/2] Replace Alpine with Google's distroless static image for enhanced security and simplified maintenance. Includes CA certificates automatically and provides debug variant for troubleshooting. --- Dockerfile | 3 +-- README.md | 30 +++++++++++++++++++++++++++--- docker-compose.yml | 30 ++++-------------------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index 31bd31ae3..36aee3845 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,5 @@ COPY script script RUN CGO_ENABLED=0 GOOS=linux go build -o /go/bin/ratelimit -ldflags="-w -s" -v github.com/envoyproxy/ratelimit/src/service_cmd -FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412 AS final -RUN apk --no-cache add ca-certificates && apk --no-cache update +FROM gcr.io/distroless/static-debian12 COPY --from=build /go/bin/ratelimit /bin/ratelimit diff --git a/README.md b/README.md index b2171b02e..b629a35ff 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ - [Overview](#overview) - [Docker Image](#docker-image) + - [Distroless Base Image](#distroless-base-image) + - [Benefits of Distroless:](#benefits-of-distroless) + - [Debugging with Distroless:](#debugging-with-distroless) - [Supported Envoy APIs](#supported-envoy-apis) - [API Deprecation History](#api-deprecation-history) - [Building and Testing](#building-and-testing) @@ -80,6 +83,28 @@ decision is then returned to the caller. For every main commit, an image is pushed to [Dockerhub](https://hub.docker.com/r/envoyproxy/ratelimit/tags?page=1&ordering=last_updated). There is currently no versioning (post v1.4.0) and tags are based on commit sha. +## Distroless Base Image + +The Docker image uses Google's [distroless](https://github.com/GoogleContainerTools/distroless) base image (`gcr.io/distroless/static-debian12`) for enhanced security and minimal attack surface. Distroless images contain only the application and its runtime dependencies, omitting unnecessary OS components like package managers, shells, and other utilities. + +### Benefits of Distroless: + +- **Enhanced Security**: Minimal attack surface with no unnecessary components +- **Smaller Image Size**: Significantly smaller than traditional base images +- **Reduced Vulnerabilities**: Fewer components means fewer potential security issues +- **Better Compliance**: Meets security requirements for minimal base images + +### Debugging with Distroless: + +For debugging purposes, you can use the debug variant of the distroless image: + +```dockerfile +FROM gcr.io/distroless/static-debian12:debug +COPY --from=build /go/bin/ratelimit /bin/ratelimit +``` + +This provides shell access and debugging tools while maintaining the security benefits of distroless. + # Supported Envoy APIs [v3 rls.proto](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/ratelimit/v3/rls.proto) is currently supported. @@ -132,14 +157,13 @@ Support for [v2 rls proto](https://github.com/envoyproxy/data-plane-api/blob/mas ## Docker-compose setup -The docker-compose setup has three containers: redis, ratelimit-build, and ratelimit. In order to run the docker-compose setup from the root of the repo, run +The docker-compose setup uses a distroless-based container for the ratelimit service. In order to run the docker-compose setup from the root of the repo, run ```bash docker-compose up ``` -The ratelimit-build container will build the ratelimit binary. Then via a shared volume the binary will be shared with the ratelimit container. This dual container setup is used in order to use a -a minimal container to run the application, rather than the heftier container used to build it. +The ratelimit service is built using the main Dockerfile which uses Google's distroless base image for enhanced security and minimal attack surface. The distroless image contains only the application and its runtime dependencies, omitting unnecessary OS components like package managers and shells. If you want to run with [two redis instances](#two-redis-instances), you will need to modify the docker-compose.yml file to run a second redis container, and change the environment variables diff --git a/docker-compose.yml b/docker-compose.yml index 340906072..1a35cca8a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,39 +18,20 @@ services: networks: - ratelimit-network - # minimal container that builds the ratelimit service binary and exits. - ratelimit-build: - image: golang:1.23.9-alpine - working_dir: /go/src/github.com/envoyproxy/ratelimit - command: go build -o /usr/local/bin/ratelimit ./src/service_cmd/main.go - volumes: - - .:/go/src/github.com/envoyproxy/ratelimit - - binary:/usr/local/bin/ - - ratelimit-client-build: - image: golang:1.23.9-alpine - working_dir: /go/src/github.com/envoyproxy/ratelimit - command: go build -o /usr/local/bin/ratelimit_client ./src/client_cmd/main.go - volumes: - - .:/go/src/github.com/envoyproxy/ratelimit - - binary:/usr/local/bin/ - ratelimit: - image: alpine:3.6 - command: > - sh -c "until test -f /usr/local/bin/ratelimit; do sleep 5; done; /usr/local/bin/ratelimit" + build: + context: . + dockerfile: Dockerfile + command: /bin/ratelimit ports: - 8080:8080 - 8081:8081 - 6070:6070 depends_on: - redis - - ratelimit-build - - ratelimit-client-build networks: - ratelimit-network volumes: - - binary:/usr/local/bin/ - ./examples:/data environment: - USE_STATSD=false @@ -63,6 +44,3 @@ services: networks: ratelimit-network: - -volumes: - binary: From 5009d932c9b8e200d4bdd2e3a176bb3f4b0d20ee Mon Sep 17 00:00:00 2001 From: collin-lee Date: Mon, 27 Oct 2025 14:48:50 -0700 Subject: [PATCH 2/2] security: pin distroless image to SHA and use nonroot variant - Pin gcr.io/distroless/static-debian12:nonroot to specific SHA digest - Ensures deterministic builds and prevents supply chain attacks - Use nonroot variant for enhanced security (runs as UID 65532) - Follows same pattern as Envoy proxy for consistency - Update documentation to reflect security improvements --- Dockerfile | 2 +- README.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 36aee3845..d9cb59a07 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,5 +10,5 @@ COPY script script RUN CGO_ENABLED=0 GOOS=linux go build -o /go/bin/ratelimit -ldflags="-w -s" -v github.com/envoyproxy/ratelimit/src/service_cmd -FROM gcr.io/distroless/static-debian12 +FROM gcr.io/distroless/static-debian12:nonroot@sha256:e8a4044e0b4ae4257efa45fc026c0bc30ad320d43bd4c1a7d5271bd241e386d0 COPY --from=build /go/bin/ratelimit /bin/ratelimit diff --git a/README.md b/README.md index b629a35ff..9076731aa 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,9 @@ For every main commit, an image is pushed to [Dockerhub](https://hub.docker.com/ ## Distroless Base Image -The Docker image uses Google's [distroless](https://github.com/GoogleContainerTools/distroless) base image (`gcr.io/distroless/static-debian12`) for enhanced security and minimal attack surface. Distroless images contain only the application and its runtime dependencies, omitting unnecessary OS components like package managers, shells, and other utilities. +The Docker image uses Google's [distroless](https://github.com/GoogleContainerTools/distroless) base image (`gcr.io/distroless/static-debian12:nonroot`) for enhanced security and minimal attack surface. Distroless images contain only the application and its runtime dependencies, omitting unnecessary OS components like package managers, shells, and other utilities. + +The image is pinned to a specific SHA digest for deterministic builds and uses the `nonroot` variant to run as a non-privileged user, following security best practices. ### Benefits of Distroless: @@ -93,6 +95,8 @@ The Docker image uses Google's [distroless](https://github.com/GoogleContainerTo - **Smaller Image Size**: Significantly smaller than traditional base images - **Reduced Vulnerabilities**: Fewer components means fewer potential security issues - **Better Compliance**: Meets security requirements for minimal base images +- **Non-root Execution**: Runs as a non-privileged user (UID 65532) for enhanced security +- **Deterministic Builds**: Pinned to specific SHA digest ensures reproducible builds ### Debugging with Distroless: