Files
Homelabv4/infrastructure/crowdsec/manifests/firewall-bouncer.yaml
T
2026-03-09 20:21:35 -05:00

165 lines
4.2 KiB
YAML

# CrowdSec Firewall Bouncer - nftables enforcement on each node
# Blocks malicious IPs before they reach Cilium eBPF processing
# Requires: hostNetwork + privileged (nftables management)
# Image: community Docker build of cs-firewall-bouncer (no official image exists)
---
apiVersion: v1
kind: ConfigMap
metadata:
name: crowdsec-firewall-bouncer-config
namespace: crowdsec
data:
crowdsec-firewall-bouncer.yaml: |
mode: nftables
update_frequency: 10s
log_mode: stdout
log_level: info
api_url: http://crowdsec-service.crowdsec.svc:8080/
api_key: ${API_KEY}
insecure_skip_verify: false
disable_ipv6: false
deny_action: DROP
deny_log: true
deny_log_prefix: "crowdsec: "
supported_decisions_types:
- ban
blacklists_ipv4: crowdsec-blacklists
blacklists_ipv6: crowdsec6-blacklists
nftables:
ipv4:
enabled: true
set-only: false
table: crowdsec
chain: crowdsec-chain
priority: -10
ipv6:
enabled: true
set-only: false
table: crowdsec6
chain: crowdsec6-chain
priority: -10
nftables_hooks:
- input
- forward
prometheus:
enabled: true
listen_addr: 0.0.0.0
listen_port: 60601
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: crowdsec-firewall-bouncer
namespace: crowdsec
labels:
app: crowdsec-firewall-bouncer
spec:
selector:
matchLabels:
app: crowdsec-firewall-bouncer
template:
metadata:
labels:
app: crowdsec-firewall-bouncer
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
tolerations:
- operator: Exists
initContainers:
# Render env vars in config template
- name: render-config
image: docker.io/library/busybox:1.36
securityContext:
runAsUser: 10000
runAsGroup: 10000
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
command: ["/bin/sh", "-c"]
args:
- |
sed "s|\${API_KEY}|${API_KEY}|g" /config-template/crowdsec-firewall-bouncer.yaml > /config/crowdsec-firewall-bouncer.yaml
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: crowdsec-bouncer-key
key: api-key
volumeMounts:
- name: config-template
mountPath: /config-template
- name: config-rendered
mountPath: /config
containers:
- name: bouncer
image: ghcr.io/shgew/cs-firewall-bouncer-docker:v0.0.34-patch1
command:
- /usr/local/bin/crowdsec-firewall-bouncer
- -c
- /config/crowdsec-firewall-bouncer.yaml
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 64Mi
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
- NET_RAW
volumeMounts:
- name: config-rendered
mountPath: /config
readOnly: true
- name: nftables-lock
mountPath: /run
volumes:
- name: config-template
configMap:
name: crowdsec-firewall-bouncer-config
- name: config-rendered
emptyDir: {}
- name: nftables-lock
hostPath:
path: /run
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: crowdsec-firewall-bouncer-metrics
namespace: crowdsec
labels:
app: crowdsec-firewall-bouncer
spec:
selector:
app: crowdsec-firewall-bouncer
ports:
- name: metrics
port: 60601
targetPort: 60601
protocol: TCP
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: crowdsec-firewall-bouncer
namespace: crowdsec
labels:
app: crowdsec-firewall-bouncer
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app: crowdsec-firewall-bouncer
endpoints:
- port: metrics
interval: 30s