Docker images for CrowdSec Firewall Bouncer with nftables and iptables support, optimized for Kubernetes deployments.
- nftables:
davidbcn86/crowdsec-firewall-bouncer-docker:v1.0.0-debian-12-bouncer-0.0.34-nftables - iptables:
davidbcn86/crowdsec-firewall-bouncer-docker:v1.0.0-debian-12-bouncer-0.0.34-iptables
This image provides the CrowdSec Firewall Bouncer as a Kubernetes sidecar container to secure TCP and HTTP services. The bouncer runs alongside your application container and automatically blocks malicious IPs detected by CrowdSec, protecting your services from attacks.
Principal Use Case: Deploy as a sidecar container in Kubernetes pods to protect your TCP and HTTP services by automatically applying firewall rules based on CrowdSec threat intelligence.
When to Use This Sidecar: While the recommended approach is to bounce at the ingress level, some ingress controllers (like Traefik) lack support for TCP bouncers. For TCP services or when ingress-level bouncing isn't available, deploy this sidecar directly in your workload pods to apply firewall rules at the pod level.
- Pre-installed CrowdSec firewall bouncer with nftables support
- Template-based configuration using
envsubst - Kubernetes-ready sidecar container
- Minimal Debian-based image
Before deploying the bouncer, you need to create an API key in CrowdSec. There are two methods:
# Connect to your CrowdSec container or server
cscli bouncers add firewall-bouncer --key <your-api-key>Or let CrowdSec generate a key:
cscli bouncers add firewall-bouncer
# Output will show the generated API keySet an environment variable on the CrowdSec container/service:
# Docker Compose example
services:
crowdsec:
environment:
- BOUNCER_KEY_FIREWALL_BOUNCER=your-api-key-here# Kubernetes example
env:
- name: BOUNCER_KEY_FIREWALL_BOUNCER
value: "your-api-key-here"The format is BOUNCER_KEY_<NAME> where <NAME> is your bouncer identifier. CrowdSec will automatically create the bouncer with this key on startup.
Add the CrowdSec Firewall Bouncer as a sidecar container:
apiVersion: v1
kind: ConfigMap
metadata:
name: crowdsec-bouncer-config-nftables
data:
crowdsec-firewall-bouncer.yaml.template: |
api_url: ${CROWDSEC_API_URL}
api_key: ${CROWDSEC_API_KEY}
mode: nftables
update_frequency: 10s
daemonize: false
log_level: info
log_media: stdout
log_dir: /var/log
pid_dir: /var/run
nftables:
enabled: true
ipv4_table: crowdsec
ipv6_table: crowdsec6
ipv4_chain: crowdsec-chain
ipv6_chain: crowdsec-chain
---
apiVersion: v1
kind: Secret
metadata:
name: crowdsec-api-key
type: Opaque
stringData:
api_key: "your-api-key-here"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: your-app:v1.0.0
# CrowdSec Firewall Bouncer sidecar (nftables variant)
- name: crowdsec-firewall-bouncer
image: davidbcn86/crowdsec-firewall-bouncer-docker:v1.0.0-debian-12-bouncer-0.0.34-nftables
security_context:
privileged: true
allow_privilege_escalation: true
capabilities:
add: ["NET_ADMIN", "NET_RAW", "SYS_ADMIN"]
env:
- name: CROWDSEC_API_URL
value: "http://crowdsec-service:8080"
- name: CROWDSEC_API_KEY
valueFrom:
secretKeyRef:
name: crowdsec-api-key
key: api_key
volumeMounts:
- name: crowdsec-bouncer-config
mountPath: /tmp/crowdsec-config-source
- name: crowdsec-bouncer-var-log
mountPath: /var/log
- name: crowdsec-bouncer-var-run
mountPath: /var/run
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "256Mi"
volumes:
- name: crowdsec-bouncer-config
configMap:
name: crowdsec-bouncer-config-nftables
- name: crowdsec-bouncer-var-log
emptyDir: {}
- name: crowdsec-bouncer-var-run
emptyDir: {}resource "kubernetes_config_map" "crowdsec_bouncer_config_nftables" {
metadata {
name = "crowdsec-bouncer-config-nftables"
}
data = {
"crowdsec-firewall-bouncer.yaml.template" = <<-EOT
api_url: ${var.crowdsec_api_url}
api_key: ${var.crowdsec_api_key}
mode: nftables
update_frequency: 10s
daemonize: false
log_level: info
log_media: stdout
log_dir: /var/log
pid_dir: /var/run
nftables:
enabled: true
ipv4_table: crowdsec
ipv6_table: crowdsec6
ipv4_chain: crowdsec-chain
ipv6_chain: crowdsec-chain
EOT
}
}
resource "kubernetes_deployment" "app" {
metadata {
name = "my-app"
}
spec {
replicas = 1
selector {
match_labels = {
app = "my-app"
}
}
template {
metadata {
labels = {
app = "my-app"
}
}
spec {
# Main application container
container {
name = "app"
image = "atmoz/sftp:latest"
# ... your app configuration ...
}
# CrowdSec Firewall Bouncer sidecar
container {
name = "crowdsec-firewall-bouncer"
image = "davidbcn86/crowdsec-firewall-bouncer-docker:v1.0.0-debian-12-bouncer-0.0.34-nftables"
security_context {
privileged = true
allow_privilege_escalation = true
capabilities {
add = ["NET_ADMIN", "NET_RAW", "SYS_ADMIN"]
}
}
env {
name = "CROWDSEC_API_URL"
value = var.crowdsec_api_url
}
env {
name = "CROWDSEC_API_KEY"
value_from {
secret_key_ref {
name = kubernetes_secret.crowdsec_api_key.metadata[0].name
key = "api_key"
}
}
}
volume_mount {
name = "crowdsec-bouncer-config"
mount_path = "/tmp/crowdsec-config-source"
}
volume_mount {
name = "crowdsec-bouncer-var-log"
mount_path = "/var/log"
}
volume_mount {
name = "crowdsec-bouncer-var-run"
mount_path = "/var/run"
}
resources {
requests = {
cpu = "50m"
memory = "64Mi"
}
limits = {
cpu = "200m"
memory = "256Mi"
}
}
}
volume {
name = "crowdsec-bouncer-config"
config_map {
name = kubernetes_config_map.crowdsec_bouncer_config_nftables.metadata[0].name
}
}
volume {
name = "crowdsec-bouncer-var-log"
empty_dir {}
}
volume {
name = "crowdsec-bouncer-var-run"
empty_dir {}
}
}
}
}
}The bouncer uses a configuration template processed with envsubst at runtime.
- Template:
/tmp/crowdsec-config-source/crowdsec-firewall-bouncer.yaml.template - Output:
/etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
All environment variables starting with CROWDSEC_ are automatically substituted:
CROWDSEC_API_URL: CrowdSec API URL (default:http://127.0.0.1:8080)CROWDSEC_API_KEY: API key (required)
api_url: ${CROWDSEC_API_URL}
api_key: ${CROWDSEC_API_KEY}The firewall bouncer logs its operations (connecting to CrowdSec API, applying firewall rules, processing decisions) to stdout by default (configurable via log_media and log_dir).
Operational Logs: The bouncer logs when it:
- Connects to the CrowdSec API
- Receives and processes decisions from CrowdSec
- Adds or removes IPs from firewall rules
- General operational status
Blocked Connection Logs: To log individual blocked connections, enable the deny_log option in your configuration:
deny_log: true
deny_log_prefix: "crowdsec: "When enabled, blocked packets are logged to the kernel log (viewable via dmesg or /var/log/kern.log). In Kubernetes, these logs appear in the container's kernel logs or can be collected via a log aggregation system.
# Build and start services
docker compose up -d
# Run integration tests
./Test-Integration.ps1
# Clean up
docker compose down -vVersions are managed in .env:
DEBIAN_VERSION=12
CROWDSEC_BOUNCER_VERSION=0.0.34Build:
docker compose build- Kubernetes cluster with privileged container support
- CrowdSec API instance
- Network access between bouncer and API