feat(crowdsec): restore web traffic protection

Protect public Traefik routes with CrowdSec HTTP decisions and restore access logging for web traffic analysis.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
forustandCopilot committed 2026-09-12 21:05:12 +02:00
1 parent 726b3ee544
commit ed1ddaad5d
23 files changed
+186

No files matched your search

+6
View File
@@ -9,11 +9,17 @@ spec:
routes: routes:
- match: Host(`adguard.forust.xyz`) || Host(`dns.forust.xyz`) - match: Host(`adguard.forust.xyz`) || Host(`dns.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: adguard-service - name: adguard-service
port: 3000 port: 3000
- match: (Host(`adguard.forust.xyz`) || Host(`dns.forust.xyz`)) && PathPrefix(`/dns-query`) - match: (Host(`adguard.forust.xyz`) || Host(`dns.forust.xyz`)) && PathPrefix(`/dns-query`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: adguard-service - name: adguard-service
port: 3000 port: 3000
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`auth.forust.xyz`) - match: Host(`auth.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: authentik-server-service - name: authentik-server-service
port: 9000 port: 9000
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`cmk.forust.xyz`) - match: Host(`cmk.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: checkmk-service - name: checkmk-service
port: 5000 port: 5000
+14
View File
@@ -0,0 +1,14 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: crowdsec-bouncer
namespace: crowdsec
spec:
plugin:
crowdsec-bouncer:
enabled: true
LogLevel: INFO
CrowdsecMode: live
CrowdsecLapiScheme: http
CrowdsecLapiHost: crowdsec-service.crowdsec.svc.cluster.local:8080
CrowdsecLapiKeyFile: "/etc/traefik/secrets/traefik-api-key"
+55
View File
@@ -0,0 +1,55 @@
container_runtime: containerd
agent:
env:
- name: COLLECTIONS
value: "crowdsecurity/traefik crowdsecurity/base-http-scenarios"
- name: DISABLE_COLLECTIONS
value: "crowdsecurity/linux crowdsecurity/sshd"
acquisition:
- namespace: traefik
podName: "*traefik*"
program: traefik
poll_without_inotify: true
resources:
requests:
cpu: 50m
memory: 100Mi
limits:
cpu: 200m
memory: 500Mi
lapi:
env:
- name: COLLECTIONS
value: "crowdsecurity/traefik crowdsecurity/base-http-scenarios"
- name: DISABLE_COLLECTIONS
value: "crowdsecurity/linux crowdsecurity/sshd"
service:
type: ClusterIP
persistentVolume:
data:
enabled: true
storageClassName: local-path-retain
size: 1Gi
config:
enabled: true
storageClassName: local-path-retain
size: 100Mi
storeLAPICscliCredentialsInSecret: true
resources:
requests:
cpu: 50m
memory: 150Mi
limits:
cpu: 200m
memory: 500Mi
metrics:
enabled: true
serviceMonitor:
additionalLabels:
release: prometheus-stack
enabled: true
namespace: prometheus
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: crowdsec
labels:
app.kubernetes.io/part-of: crowdsec
+27
View File
@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: crowdsec-lapi
namespace: crowdsec
spec:
podSelector:
matchLabels:
k8s-app: crowdsec
type: lapi
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
- podSelector:
matchLabels:
k8s-app: crowdsec
type: agent
ports:
- protocol: TCP
port: 8080
+2
View File
@@ -18,6 +18,8 @@ spec:
- match: Host(`dockmon.forust.xyz`) - match: Host(`dockmon.forust.xyz`)
kind: Rule kind: Rule
middlewares: middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
- name: security-headers@file - name: security-headers@file
services: services:
- name: dockmon-service - name: dockmon-service
+2
View File
@@ -10,6 +10,8 @@ spec:
- match: Host(`downtify.forust.xyz`) - match: Host(`downtify.forust.xyz`)
kind: Rule kind: Rule
middlewares: middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
- name: security-chain@file - name: security-chain@file
services: services:
- name: downtify-service - name: downtify-service
+6
View File
@@ -9,11 +9,17 @@ spec:
routes: routes:
- match: Host(`gitea.forust.xyz`) - match: Host(`gitea.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: gitea-service - name: gitea-service
port: 3000 port: 3000
- match: Host(`gcr.forust.xyz`) && PathPrefix(`/v2`) - match: Host(`gcr.forust.xyz`) && PathPrefix(`/v2`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: gitea-service - name: gitea-service
port: 3000 port: 3000
+11
View File
@@ -18,16 +18,25 @@ spec:
routes: routes:
- match: Host(`hs.forust.xyz`) - match: Host(`hs.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: headscale-server-external - name: headscale-server-external
port: 8080 port: 8080
- match: Host(`hs.forust.xyz`) && PathPrefix(`/admin`) - match: Host(`hs.forust.xyz`) && PathPrefix(`/admin`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: headscale-ui-external - name: headscale-ui-external
port: 80 port: 80
- match: Host(`hs.forust.xyz`) && PathPrefix(`/metrics`) - match: Host(`hs.forust.xyz`) && PathPrefix(`/metrics`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: headscale-server-external - name: headscale-server-external
port: 9090 port: 9090
@@ -47,6 +56,8 @@ spec:
kind: Rule kind: Rule
middlewares: middlewares:
- name: headplane-prefix - name: headplane-prefix
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: headplane-external - name: headplane-external
port: 3000 port: 3000
+6
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`forust.xyz`) || Host(`www.forust.xyz`) - match: Host(`forust.xyz`) || Host(`www.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
priority: 10 priority: 10
services: services:
- name: forust-homepage-service - name: forust-homepage-service
@@ -43,6 +46,9 @@ spec:
routes: routes:
- match: Host(`xdfnx.cfd`) - match: Host(`xdfnx.cfd`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: xdfnx-homepage-service - name: xdfnx-homepage-service
port: 80 port: 80
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`status.forust.xyz`) - match: Host(`status.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: kener-service - name: kener-service
port: 3000 port: 3000
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`n8n.forust.xyz`) - match: Host(`n8n.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: n8n-service - name: n8n-service
port: 5678 port: 5678
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`nm.forust.xyz`) - match: Host(`nm.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: netronome-service - name: netronome-service
port: 7575 port: 7575
+4
View File
@@ -12,6 +12,8 @@ spec:
kind: Rule kind: Rule
middlewares: middlewares:
- name: nextcloud-chain@file - name: nextcloud-chain@file
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: nextcloud-apache - name: nextcloud-apache
port: 11000 port: 11000
@@ -30,6 +32,8 @@ spec:
- match: Host(`nextcloud.workstation.internal`) || Host(`nextcloud.gigaforust.internal`) - match: Host(`nextcloud.workstation.internal`) || Host(`nextcloud.gigaforust.internal`)
kind: Rule kind: Rule
middlewares: middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
- name: nextcloud-chain@file - name: nextcloud-chain@file
services: services:
- name: nextcloud-apache - name: nextcloud-apache
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`portainer.forust.xyz`) - match: Host(`portainer.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: portainer-service - name: portainer-service
port: 9000 port: 9000
+2
View File
@@ -10,6 +10,8 @@ spec:
- match: Host(`grafana.forust.xyz`) - match: Host(`grafana.forust.xyz`)
kind: Rule kind: Rule
middlewares: middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
- name: "security-chain@file" - name: "security-chain@file"
services: services:
- name: prometheus-stack-grafana - name: prometheus-stack-grafana
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`s.forust.xyz`) || Host(`search.forust.xyz`) - match: Host(`s.forust.xyz`) || Host(`search.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: searxng-service - name: searxng-service
port: 8080 port: 8080
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`termix.forust.xyz`) - match: Host(`termix.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: termix-service - name: termix-service
port: 8080 port: 8080
+3
View File
@@ -10,6 +10,9 @@ spec:
routes: routes:
- match: Host(`traefik.forust.xyz`) - match: Host(`traefik.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: api@internal - name: api@internal
kind: TraefikService kind: TraefikService
+15
View File
@@ -141,6 +141,9 @@ volumes:
- name: traefik-dynamic - name: traefik-dynamic
mountPath: /etc/traefik/dynamic mountPath: /etc/traefik/dynamic
type: configMap type: configMap
- name: crowdsec-bouncer-secrets
mountPath: /etc/traefik/secrets
type: secret
additionalArguments: additionalArguments:
- "--providers.file.directory=/etc/traefik/dynamic" - "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true" - "--providers.file.watch=true"
@@ -148,3 +151,15 @@ additionalArguments:
- "--providers.kubernetesCRD.safeNaming=false" - "--providers.kubernetesCRD.safeNaming=false"
- "--entryPoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1" - "--entryPoints.websecure.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1"
- "--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1" - "--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,192.168.1.1,192.168.1.0/24,192.168.88.0/24,192.168.88.1"
experimental:
plugins:
crowdsec-bouncer:
moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
version: v1.3.3
log:
level: INFO
accessLog:
enabled: true
format: common
+3
View File
@@ -9,6 +9,9 @@ spec:
routes: routes:
- match: Host(`uptime.forust.xyz`) - match: Host(`uptime.forust.xyz`)
kind: Rule kind: Rule
middlewares:
- name: crowdsec-bouncer
namespace: crowdsec
services: services:
- name: uptime-kuma-service - name: uptime-kuma-service
port: 3001 port: 3001