Add crowdsec auto ban

This commit is contained in:
2026-04-01 19:51:16 +11:00
parent f540312aa9
commit 7ae2616308
+117
View File
@@ -0,0 +1,117 @@
---
# CrowdSec → NGINX Ingress IP Block Sync
#
# Runs every minute, reads all active CrowdSec ban decisions,
# and updates the NGINX Ingress Controller ConfigMap's block-cidrs field.
# This propagates CrowdSec's automated threat detection into NGINX's global IP blocklist.
apiVersion: v1
kind: ServiceAccount
metadata:
name: crowdsec-nginx-sync
namespace: crowdsec
---
# Allow the sync job to read CrowdSec LAPI pod exec (to run cscli)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: crowdsec-nginx-sync
rules:
# Exec into CrowdSec LAPI pod to run cscli
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
# Read/patch the NGINX Ingress ConfigMap
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crowdsec-nginx-sync
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: crowdsec-nginx-sync
subjects:
- kind: ServiceAccount
name: crowdsec-nginx-sync
namespace: crowdsec
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: crowdsec-nginx-sync
namespace: crowdsec
spec:
schedule: "* * * * *" # every minute
concurrencyPolicy: Forbid # skip if previous run is still going
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
activeDeadlineSeconds: 55 # must finish before next run
template:
spec:
serviceAccountName: crowdsec-nginx-sync
restartPolicy: Never
containers:
- name: sync
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
set -e
# Find the CrowdSec LAPI pod
LAPI_POD=$(kubectl get pods -n crowdsec \
-l "type=lapi" \
-o jsonpath='{.items[0].metadata.name}')
if [ -z "$LAPI_POD" ]; then
echo "ERROR: CrowdSec LAPI pod not found"
exit 1
fi
echo "Using LAPI pod: $LAPI_POD"
# Fetch all active ban decisions in raw CSV format:
# id,source,ip,reason,action,country,as,events_count,expiration,simulated,alert_id
# The ip column has format "Ip:1.2.3.4" or "Range:1.2.3.0/24"
RAW=$(kubectl exec -n crowdsec "$LAPI_POD" -- \
cscli decisions list -t ban -o raw 2>/dev/null || true)
# Skip CSV header, extract column 3, strip the "Ip:" / "Range:" prefix
CIDRS=$(echo "$RAW" | \
tail -n +2 | \
cut -d',' -f3 | \
sed 's/^[^:]*://g' | \
grep -v '^$' | \
tr '\n' ',' | \
sed 's/,$//')
echo "Active ban count: $(echo "$RAW" | tail -n +2 | grep -c '.' || echo 0)"
echo "Blocked CIDRs: ${CIDRS:-<none>}"
# Patch the NGINX Ingress ConfigMap (JSON merge patch — only updates block-cidrs)
kubectl patch configmap ingress-nginx-controller \
-n ingress-nginx \
--type merge \
-p "{\"data\":{\"block-cidrs\":\"${CIDRS}\"}}"
echo "ConfigMap patched successfully"
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 100m
memory: 64Mi