A lightweight CrowdSec bouncer for Envoy Proxy using the ext_authz (external authorization) filter.
This project provides a seamless way to integrate CrowdSec with Envoy to block malicious IP addresses before they reach your internal services. The bouncer uses CrowdSec’s Local API (LAPI) to receive ban decisions and respond to Envoy’s external authorization calls.
This bouncer:
403 Forbidden to Envoy for banned IPs, or 200 OK if the IP is clean.sequenceDiagram
participant Client
participant Envoy as Envoy Proxy
participant Bouncer as Envoy Bouncer
Client->>Envoy: HTTP Request
Envoy->>Bouncer: ext_authz Check
Note over Bouncer: Extract client IP
alt IP is banned
Bouncer->>Envoy: 403 Forbidden
Envoy->>Client: Blocked
else IP is clean
Bouncer->>Envoy: 200 OK
Envoy->>Client: Allow Request
end
go install github.com/kdwils/envoy-proxy-bouncer@latest
The bouncer can be configured using:
Create a config.yaml file:
server:
port: 8080 # optional (defaults to 8080)
logLevel: "info" # optional (defaults to info)
bouncer:
apiKey: "your-crowdsec-bouncer-api-key" # required
apiURL: "http://crowdsec:8080" # required
metrics: true # optional (defaults to false) - report metrics to the LAPI instance
trustedProxies: # optional (defaults to 127.0.0.1, ::1)
- 192.168.0.1 # IPv4
- 2001:db8::1 # IPv6
- 10.0.0.0/8 # CIDR range
- 100.64.0.0/10 # CIDR range
tickerInterval: "10s" # optional (defaults to 10s) - how often to check for ban decisions from the LAPI stream
Run with config file:
envoy-proxy-bouncer serve --config config.yaml
All configuration options can be set via environment variables using the prefix ENVOY_BOUNCER_ and replacing dots with underscores:
# Server configuration
export ENVOY_BOUNCER_SERVER_PORT=8080
export ENVOY_BOUNCER_SERVER_LOGLEVEL=debug
# Bouncer configuration
export ENVOY_BOUNCER_BOUNCER_APIKEY=your-api-key
export ENVOY_BOUNCER_BOUNCER_APIURL=http://crowdsec:8080
export ENVOY_BOUNCER_BOUNCER_TRUSTEDPROXIES=192.168.0.1,10.0.0.0/8
export ENVOY_BOUNCER_BOUNCER_TICKERINTERVAL=5s
The configuration is loaded in the following order (last wins):
The following configuration options are required:
bouncer.apiKey: CrowdSec bouncer API keybouncer.apiURL: CrowdSec API URLserver:
port: 8080
logLevel: "info"
bouncer:
metrics: false
trustedProxies:
- "127.0.0.1"
- "::1"
tickerInterval: "10s"
sudo cscli bouncers add envoy-bouncer
export ENVOY_BOUNCER_BOUNCER_APIKEY=<your-api-key>
export ENVOY_BOUNCER_BOUNCER_APIURL=<your-lapi-host>
envoy-proxy-bouncer serve
# Test if an ip is banned (multiple IPs can be specified)
envoy-proxy-bouncer bounce -i 192.168.1.1,10.0.0.1
# Manual gRPC request test
grpcurl -plaintext -d @ localhost:8080 envoy.service.auth.v3.Authorization/Check < request.json
An examle request would look like:
{
"attributes": {
"source": {
"address": {
"socketAddress": {
"address": "192.168.1.100",
"portValue": 50555
}
}
},
"request": {
"http": {
"headers": {
"x-forwarded-for": "192.168.1.100, 10.0.0.1"
}
}
}
}
}
Build and run with Docker:
# Build
docker build -t envoy-proxy-bouncer .
# Run
docker run -p 8080:8080 \
-v $(pwd)/config.yaml:/app/config.yaml \
envoy-proxy-bouncer
The bouncer checks for ip addresses in the following order:
For X-Forwarded-For headers with multiple IPs the bouncer uses the first (rightmost) non-trusted ip. For this reason, it is recommended to configure the bouncer with trusted proxies.
# Run tests
go test ./...
# Build from source
go build -o envoy-proxy-bouncer
starting a shell with the project dependencies:
nix develop .
The bouncer reports metrics to CrowdSec’s dashboard including:
These are opt-in and can be enabled by setting metrics: true in the bouncer config.
From cscli
cscli metrics
I have personally only tested this in a kubernetes cluster with Envoy Gateway installed. If there are other environments that aren’t working, feel free to open an issue and i’ll try to help.
The bouncer can be deployed in a Kubernetes cluster alongside Envoy Gateway: An flat yaml example lives here.
Add the Helm repository:
helm repo add envoy-proxy-bouncer https://kdwils.github.io/envoy-proxy-bouncer
helm repo update
Install the chart:
helm install bouncer envoy-proxy-bouncer/envoy-proxy-bouncer \
--set crowdsec.apiKey=<your-api-key> \
--set crowdsec.apiURL=<your-crowsdsec-host>:<port>
Acknowledgements: