[ci skip] add graceful degradation to CrowdSec bouncer middleware

P0: Set updateMaxFailure=-1 (fail-open)
  Previously defaulted to 0 which blocked ALL traffic on first LAPI
  failure. Now serves from cached decisions when LAPI is unreachable.

P1: Enable Redis cache for CrowdSec decisions
  Decisions are now shared across all 3 Traefik replicas and survive
  pod restarts. redisCacheUnreachableBlock=false prevents Redis from
  becoming another SPOF.

P1: Add clientTrustedIPs for internal cluster traffic
  Node CIDR (10.0.20.0/24) and pod CIDR (10.10.0.0/16) bypass
  CrowdSec entirely, preventing internal cascade failures.
This commit is contained in:
Viktor Barzin 2026-03-01 02:36:53 +00:00
parent 946b5b1745
commit 6139052104
3 changed files with 10 additions and 3 deletions

View file

@ -162,6 +162,7 @@ module "traefik" {
source = "./modules/traefik"
tier = local.tiers.core
crowdsec_api_key = var.ingress_crowdsec_api_key
redis_host = var.redis_host
tls_secret_name = var.tls_secret_name
}

View file

@ -1,5 +1,6 @@
variable "tier" { type = string }
variable "crowdsec_api_key" { type = string }
variable "redis_host" { type = string }
variable "tls_secret_name" {}
resource "kubernetes_namespace" "traefik" {

View file

@ -150,9 +150,14 @@ resource "kubernetes_manifest" "middleware_crowdsec" {
spec = {
plugin = {
crowdsec-bouncer = {
crowdsecLapiKey = var.crowdsec_api_key
crowdsecLapiHost = "crowdsec-service.crowdsec.svc.cluster.local:8080"
crowdsecMode = "stream"
crowdsecLapiKey = var.crowdsec_api_key
crowdsecLapiHost = "crowdsec-service.crowdsec.svc.cluster.local:8080"
crowdsecMode = "stream"
updateMaxFailure = -1 # fail-open: serve from cache when LAPI is unreachable
redisCacheEnabled = true
redisCacheHost = var.redis_host
redisCacheUnreachableBlock = false # don't block traffic if Redis is also unreachable
clientTrustedIPs = ["10.0.20.0/24", "10.10.0.0/16"] # node + pod CIDRs bypass CrowdSec
}
}
}