extract dbaas, authentik, crowdsec from platform into independent stacks [ci skip]
Phase 1 of platform stack split for parallel CI applies. All 3 modules were fully independent (no cross-module refs). State migrated via terraform state mv. All 3 stacks applied with zero changes (dbaas had pre-existing ResourceQuota drift). Woodpecker pipeline updated to run extracted stacks in parallel.
This commit is contained in:
parent
c8b42f78df
commit
3c804aedf8
28 changed files with 2306 additions and 57 deletions
|
|
@ -0,0 +1,44 @@
|
|||
controller:
|
||||
extraVolumes:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
emptyDir: {}
|
||||
extraInitContainers:
|
||||
- name: init-clone-crowdsec-bouncer
|
||||
image: crowdsecurity/lua-bouncer-plugin
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: API_URL
|
||||
value: "http://crowdsec-service.crowdsec.svc.cluster.local:8080" # crowdsec lapi service-name
|
||||
- name: API_KEY
|
||||
value: "<API KEY>" # generated with `cscli bouncers add -n <bouncer_name>
|
||||
- name: BOUNCER_CONFIG
|
||||
value: "/crowdsec/crowdsec-bouncer.conf"
|
||||
- name: CAPTCHA_PROVIDER
|
||||
value: "recaptcha" # valid providers are recaptcha, hcaptcha, turnstile
|
||||
- name: SECRET_KEY
|
||||
value: "<your-captcha-secret-key>" # If you want captcha support otherwise remove this ENV VAR
|
||||
- name: SITE_KEY
|
||||
value: "<your-captcha-site-key>" # If you want captcha support otherwise remove this ENV VAR
|
||||
- name: BAN_TEMPLATE_PATH
|
||||
value: /etc/nginx/lua/plugins/crowdsec/templates/ban.html
|
||||
- name: CAPTCHA_TEMPLATE_PATH
|
||||
value: /etc/nginx/lua/plugins/crowdsec/templates/captcha.html
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"sh /docker_start.sh; mkdir -p /lua_plugins/crowdsec/; cp -R /crowdsec/* /lua_plugins/crowdsec/",
|
||||
]
|
||||
volumeMounts:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
mountPath: /lua_plugins
|
||||
extraVolumeMounts:
|
||||
- name: crowdsec-bouncer-plugin
|
||||
mountPath: /etc/nginx/lua/plugins/crowdsec
|
||||
subPath: crowdsec
|
||||
config:
|
||||
plugins: "crowdsec"
|
||||
lua-shared-dicts: "crowdsec_cache: 50m"
|
||||
server-snippet: |
|
||||
lua_ssl_trusted_certificate "/etc/ssl/certs/ca-certificates.crt"; # If you want captcha support otherwise remove this line
|
||||
resolver local=on ipv6=off;
|
||||
376
stacks/crowdsec/modules/crowdsec/main.tf
Normal file
376
stacks/crowdsec/modules/crowdsec/main.tf
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
variable "tls_secret_name" {}
|
||||
variable "homepage_username" {}
|
||||
variable "homepage_password" {}
|
||||
variable "db_password" {}
|
||||
variable "enroll_key" {}
|
||||
variable "crowdsec_dash_api_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "crowdsec_dash_machine_id" { type = string } # used for web dash
|
||||
variable "crowdsec_dash_machine_password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
variable "tier" { type = string }
|
||||
variable "slack_webhook_url" { type = string }
|
||||
variable "mysql_host" { type = string }
|
||||
|
||||
module "tls_secret" {
|
||||
source = "../../../../modules/kubernetes/setup_tls_secret"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "crowdsec" {
|
||||
metadata {
|
||||
name = "crowdsec"
|
||||
labels = {
|
||||
tier = var.tier
|
||||
"resource-governance/custom-quota" = "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map" "crowdsec_custom_scenarios" {
|
||||
metadata {
|
||||
name = "crowdsec-custom-scenarios"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
labels = {
|
||||
"app.kubernetes.io/name" = "crowdsec"
|
||||
}
|
||||
}
|
||||
|
||||
data = {
|
||||
"http-403-abuse.yaml" = <<-YAML
|
||||
type: leaky
|
||||
name: crowdsecurity/http-403-abuse
|
||||
description: "Detect IPs triggering too many HTTP 403s in NGINX ingress logs"
|
||||
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.status == '403'"
|
||||
groupby: "evt.Meta.source_ip"
|
||||
leakspeed: "2s"
|
||||
capacity: 10
|
||||
blackhole: 5m
|
||||
labels:
|
||||
service: http
|
||||
behavior: abusive_403
|
||||
remediation: true
|
||||
YAML
|
||||
"http-429-abuse.yaml" : <<-YAML
|
||||
type: leaky
|
||||
name: crowdsecurity/http-429-abuse
|
||||
description: "Detect IPs repeatedly triggering rate-limit (HTTP 429)"
|
||||
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.status == '429'"
|
||||
groupby: "evt.Meta.source_ip"
|
||||
leakspeed: "10s"
|
||||
capacity: 5
|
||||
blackhole: 1m
|
||||
labels:
|
||||
service: http
|
||||
behavior: rate_limit_abuse
|
||||
remediation: true
|
||||
YAML
|
||||
}
|
||||
}
|
||||
|
||||
# Whitelist for trusted IPs that should never be blocked
|
||||
resource "kubernetes_config_map" "crowdsec_whitelist" {
|
||||
metadata {
|
||||
name = "crowdsec-whitelist"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
labels = {
|
||||
"app.kubernetes.io/name" = "crowdsec"
|
||||
}
|
||||
}
|
||||
|
||||
data = {
|
||||
"whitelist.yaml" = <<-YAML
|
||||
name: crowdsecurity/whitelist-trusted-ips
|
||||
description: "Whitelist for trusted IPs that should never be blocked"
|
||||
whitelist:
|
||||
reason: "Trusted IP - never block"
|
||||
ip:
|
||||
- "176.12.22.76"
|
||||
YAML
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "helm_release" "crowdsec" {
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
create_namespace = true
|
||||
name = "crowdsec"
|
||||
atomic = true
|
||||
version = "0.21.0"
|
||||
|
||||
repository = "https://crowdsecurity.github.io/helm-charts"
|
||||
chart = "crowdsec"
|
||||
|
||||
values = [templatefile("${path.module}/values.yaml", { homepage_username = var.homepage_username, homepage_password = var.homepage_password, DB_PASSWORD = var.db_password, ENROLL_KEY = var.enroll_key, SLACK_WEBHOOK_URL = var.slack_webhook_url, mysql_host = var.mysql_host })]
|
||||
timeout = 900
|
||||
wait = true
|
||||
wait_for_jobs = true
|
||||
}
|
||||
|
||||
|
||||
# Deployment for my custom dashboard that helps me unblock myself when I blocklist myself
|
||||
resource "kubernetes_deployment" "crowdsec-web" {
|
||||
metadata {
|
||||
name = "crowdsec-web"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
labels = {
|
||||
app = "crowdsec_web"
|
||||
"kubernetes.io/cluster-service" = "true"
|
||||
tier = var.tier
|
||||
}
|
||||
}
|
||||
spec {
|
||||
replicas = 1
|
||||
strategy {
|
||||
type = "RollingUpdate"
|
||||
}
|
||||
selector {
|
||||
match_labels = {
|
||||
app = "crowdsec_web"
|
||||
}
|
||||
}
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "crowdsec_web"
|
||||
"kubernetes.io/cluster-service" = "true"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
priority_class_name = "tier-1-cluster"
|
||||
container {
|
||||
name = "crowdsec-web"
|
||||
image = "viktorbarzin/crowdsec_web"
|
||||
env {
|
||||
name = "CS_API_URL"
|
||||
value = "http://crowdsec-service.crowdsec.svc.cluster.local:8080/v1"
|
||||
}
|
||||
env {
|
||||
name = "CS_API_KEY"
|
||||
value = var.crowdsec_dash_api_key
|
||||
}
|
||||
env {
|
||||
name = "CS_MACHINE_ID"
|
||||
value = var.crowdsec_dash_machine_id
|
||||
}
|
||||
env {
|
||||
name = "CS_MACHINE_PASSWORD"
|
||||
value = var.crowdsec_dash_machine_password
|
||||
}
|
||||
port {
|
||||
name = "http"
|
||||
container_port = 8000
|
||||
protocol = "TCP"
|
||||
}
|
||||
resources {
|
||||
requests = {
|
||||
cpu = "15m"
|
||||
memory = "128Mi"
|
||||
}
|
||||
limits = {
|
||||
memory = "128Mi"
|
||||
}
|
||||
}
|
||||
}
|
||||
dns_config {
|
||||
option {
|
||||
name = "ndots"
|
||||
value = "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_service" "crowdsec-web" {
|
||||
metadata {
|
||||
name = "crowdsec-web"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
labels = {
|
||||
"app" = "crowdsec_web"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
selector = {
|
||||
app = "crowdsec_web"
|
||||
}
|
||||
port {
|
||||
port = "80"
|
||||
target_port = "8000"
|
||||
}
|
||||
}
|
||||
}
|
||||
module "ingress" {
|
||||
source = "../../../../modules/kubernetes/ingress_factory"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
name = "crowdsec-web"
|
||||
protected = true
|
||||
tls_secret_name = var.tls_secret_name
|
||||
exclude_crowdsec = true
|
||||
rybbit_site_id = "d09137795ccc"
|
||||
}
|
||||
|
||||
# CronJob to import public blocklists into CrowdSec
|
||||
# https://github.com/wolffcatskyy/crowdsec-blocklist-import
|
||||
# Uses kubectl exec to run in an existing CrowdSec agent pod that's already registered
|
||||
resource "kubernetes_cron_job_v1" "crowdsec_blocklist_import" {
|
||||
metadata {
|
||||
name = "crowdsec-blocklist-import"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
labels = {
|
||||
app = "crowdsec-blocklist-import"
|
||||
tier = var.tier
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
# Run daily at 4 AM
|
||||
schedule = "0 4 * * *"
|
||||
timezone = "Europe/London"
|
||||
concurrency_policy = "Forbid"
|
||||
successful_jobs_history_limit = 3
|
||||
failed_jobs_history_limit = 3
|
||||
|
||||
job_template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "crowdsec-blocklist-import"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
backoff_limit = 3
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
app = "crowdsec-blocklist-import"
|
||||
}
|
||||
}
|
||||
|
||||
spec {
|
||||
service_account_name = kubernetes_service_account.blocklist_import.metadata[0].name
|
||||
restart_policy = "OnFailure"
|
||||
|
||||
container {
|
||||
name = "blocklist-import"
|
||||
image = "bitnami/kubectl:latest"
|
||||
|
||||
command = ["/bin/bash", "-c"]
|
||||
args = [
|
||||
<<-EOF
|
||||
set -e
|
||||
|
||||
echo "Finding CrowdSec agent pod..."
|
||||
AGENT_POD=$(kubectl get pods -n crowdsec -l k8s-app=crowdsec,type=agent -o jsonpath='{.items[0].metadata.name}')
|
||||
|
||||
if [ -z "$AGENT_POD" ]; then
|
||||
echo "ERROR: Could not find CrowdSec agent pod"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using agent pod: $AGENT_POD"
|
||||
|
||||
# Download the import script
|
||||
echo "Downloading blocklist import script..."
|
||||
curl -fsSL -o /tmp/import.sh \
|
||||
https://raw.githubusercontent.com/wolffcatskyy/crowdsec-blocklist-import/main/import.sh
|
||||
chmod +x /tmp/import.sh
|
||||
|
||||
# Copy script to agent pod and execute
|
||||
echo "Copying script to agent pod and executing..."
|
||||
kubectl cp /tmp/import.sh crowdsec/$AGENT_POD:/tmp/import.sh
|
||||
|
||||
kubectl exec -n crowdsec "$AGENT_POD" -- /bin/bash -c '
|
||||
set -e
|
||||
|
||||
# Run with native mode since we are inside the CrowdSec container
|
||||
export MODE=native
|
||||
export DECISION_DURATION=24h
|
||||
export FETCH_TIMEOUT=60
|
||||
export LOG_LEVEL=INFO
|
||||
|
||||
/tmp/import.sh
|
||||
|
||||
# Cleanup
|
||||
rm -f /tmp/import.sh
|
||||
'
|
||||
|
||||
echo "Blocklist import completed successfully!"
|
||||
EOF
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Service account for the blocklist import job (needs kubectl exec permissions)
|
||||
resource "kubernetes_service_account" "blocklist_import" {
|
||||
metadata {
|
||||
name = "crowdsec-blocklist-import"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_role" "blocklist_import" {
|
||||
metadata {
|
||||
name = "crowdsec-blocklist-import"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
}
|
||||
|
||||
rule {
|
||||
api_groups = [""]
|
||||
resources = ["pods"]
|
||||
verbs = ["get", "list"]
|
||||
}
|
||||
rule {
|
||||
api_groups = [""]
|
||||
resources = ["pods/exec"]
|
||||
verbs = ["create"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_role_binding" "blocklist_import" {
|
||||
metadata {
|
||||
name = "crowdsec-blocklist-import"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
}
|
||||
|
||||
role_ref {
|
||||
api_group = "rbac.authorization.k8s.io"
|
||||
kind = "Role"
|
||||
name = kubernetes_role.blocklist_import.metadata[0].name
|
||||
}
|
||||
|
||||
subject {
|
||||
kind = "ServiceAccount"
|
||||
name = kubernetes_service_account.blocklist_import.metadata[0].name
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
}
|
||||
}
|
||||
|
||||
# Custom ResourceQuota for CrowdSec — needs more than default 1-cluster quota
|
||||
# because it runs DaemonSet agents (1 per worker node) + 3 LAPI replicas + web UI
|
||||
resource "kubernetes_resource_quota" "crowdsec" {
|
||||
metadata {
|
||||
name = "crowdsec-quota"
|
||||
namespace = kubernetes_namespace.crowdsec.metadata[0].name
|
||||
}
|
||||
spec {
|
||||
hard = {
|
||||
"requests.cpu" = "4"
|
||||
"requests.memory" = "8Gi"
|
||||
"limits.memory" = "16Gi"
|
||||
pods = "30"
|
||||
}
|
||||
}
|
||||
}
|
||||
226
stacks/crowdsec/modules/crowdsec/values.yaml
Normal file
226
stacks/crowdsec/modules/crowdsec/values.yaml
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
# values from - https://github.com/crowdsecurity/helm-charts/blob/main/charts/crowdsec/values.yaml
|
||||
container_runtime: containerd
|
||||
|
||||
agent:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
priorityClassName: "tier-1-cluster"
|
||||
# To specify each pod you want to process it logs (pods present in the node)
|
||||
acquisition:
|
||||
# The namespace where the pod is located
|
||||
- namespace: traefik
|
||||
# The pod name
|
||||
podName: traefik-*
|
||||
# as in crowdsec configuration, we need to specify the program name so the parser will match and parse logs
|
||||
program: traefik
|
||||
# Those are ENV variables
|
||||
env:
|
||||
# As it's a test, we don't want to share signals with CrowdSec so disable the Online API.
|
||||
# - name: DISABLE_ONLINE_API
|
||||
# value: "true"
|
||||
# As we are running Traefik, we want to install the Traefik collection
|
||||
- name: COLLECTIONS
|
||||
value: "crowdsecurity/traefik crowdsecurity/base-http-scenarios crowdsecurity/http-cve"
|
||||
- name: SCENARIOS
|
||||
value: ""
|
||||
# value: "crowdsecurity/http-crawl-aggressive"
|
||||
# Mount custom scenarios into /etc/crowdsec/scenarios
|
||||
extraVolumeMounts:
|
||||
- name: custom-scenarios
|
||||
mountPath: /etc/crowdsec/scenarios/http-403-abuse.yaml
|
||||
subPath: "http-403-abuse.yaml"
|
||||
readonly: true
|
||||
- name: custom-scenarios
|
||||
mountPath: /etc/crowdsec/scenarios/http-429-abuse.yaml
|
||||
subPath: "http-429-abuse.yaml"
|
||||
readonly: true
|
||||
- name: whitelist
|
||||
mountPath: /etc/crowdsec/parsers/s02-enrich/whitelist.yaml
|
||||
subPath: "whitelist.yaml"
|
||||
readonly: true
|
||||
extraVolumes:
|
||||
- name: custom-scenarios
|
||||
configMap:
|
||||
name: crowdsec-custom-scenarios
|
||||
- name: whitelist
|
||||
configMap:
|
||||
name: crowdsec-whitelist
|
||||
lapi:
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
failureThreshold: 30
|
||||
periodSeconds: 10
|
||||
priorityClassName: "tier-1-cluster"
|
||||
replicas: 3
|
||||
topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: kubernetes.io/hostname
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: crowdsec
|
||||
type: lapi
|
||||
pdb:
|
||||
enabled: true
|
||||
maxUnavailable: 1
|
||||
extraSecrets:
|
||||
dbPassword: "${DB_PASSWORD}"
|
||||
storeCAPICredentialsInSecret: true
|
||||
persistentVolume:
|
||||
config:
|
||||
enabled: false
|
||||
data:
|
||||
enabled: false
|
||||
env:
|
||||
- name: ENROLL_KEY
|
||||
value: "${ENROLL_KEY}"
|
||||
- name: ENROLL_INSTANCE_NAME
|
||||
value: "k8s-cluster"
|
||||
- name: ENROLL_TAGS
|
||||
value: "k8s linux"
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: crowdsec-lapi-secrets
|
||||
key: dbPassword
|
||||
# As it's a test, we don't want to share signals with CrowdSec, so disable the Online API.
|
||||
# - name: DISABLE_ONLINE_API
|
||||
# value: "true"
|
||||
dashboard:
|
||||
enabled: true
|
||||
env:
|
||||
- name: MB_DB_TYPE
|
||||
value: "mysql"
|
||||
- name: MB_DB_DBNAME
|
||||
value: crowdsec-metabase
|
||||
- name: MB_DB_USER
|
||||
value: "crowdsec"
|
||||
- name: MB_DB_PASS
|
||||
value: "${DB_PASSWORD}"
|
||||
- name: MB_DB_HOST
|
||||
value: "${mysql_host}"
|
||||
|
||||
- name: MB_EMAIL_SMTP_USERNAME
|
||||
value: "info@viktorbarzin.me"
|
||||
- name: MB_EMAIL_FROM_ADDRESS
|
||||
value: "info@viktorbarzin.me"
|
||||
- name: MB_EMAIL_SMTP_HOST
|
||||
value: "mailserver.mailserver.svc.cluster.local"
|
||||
- name: MB_EMAIL_SMTP_PASSWORD
|
||||
value: "" # Ignore for now as it's unclear what notifications we can get
|
||||
- name: MB_EMAIL_SMTP_PORT
|
||||
value: "587"
|
||||
- name: MB_EMAIL_SMTP_SECURITY
|
||||
value: "starttls"
|
||||
ingress:
|
||||
enabled: true
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
#nginx.ingress.kubernetes.io/auth-url: "https://oauth2.viktorbarzin.me/oauth2/auth"
|
||||
nginx.ingress.kubernetes.io/auth-url: "http://ak-outpost-authentik-embedded-outpost.authentik.svc.cluster.local:9000/outpost.goauthentik.io/auth/nginx"
|
||||
# nginx.ingress.kubernetes.io/auth-signin: "https://oauth2.viktorbarzin.me/oauth2/start?rd=/redirect/$http_host$escaped_request_uri"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://authentik.viktorbarzin.me/outpost.goauthentik.io/start?rd=$scheme%3A%2F%2F$host$escaped_request_uri"
|
||||
nginx.ingress.kubernetes.io/auth-response-headers: "Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
|
||||
nginx.ingress.kubernetes.io/auth-snippet: "proxy_set_header X-Forwarded-Host $http_host;"
|
||||
gethomepage.dev/enabled: "true"
|
||||
gethomepage.dev/description: "Web Application Firewall"
|
||||
gethomepage.dev/icon: "crowdsec.png"
|
||||
gethomepage.dev/name: "CrowdSec"
|
||||
gethomepage.dev/group: "Identity & Security"
|
||||
gethomepage.dev/widget.type: "crowdsec"
|
||||
gethomepage.dev/widget.url: "http://crowdsec-service.crowdsec.svc.cluster.local:8080"
|
||||
gethomepage.dev/widget.username: "${homepage_username}"
|
||||
gethomepage.dev/widget.password: "${homepage_password}"
|
||||
gethomepage.dev/pod-selector: ""
|
||||
ingressClassName: "nginx"
|
||||
host: "crowdsec.viktorbarzin.me"
|
||||
tls:
|
||||
- hosts:
|
||||
- crowdsec.viktorbarzin.me
|
||||
secretName: "tls-secret"
|
||||
metrics:
|
||||
enabled: true
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
|
||||
config:
|
||||
# Custom profiles: captcha for rate limiting, ban for attacks
|
||||
profiles.yaml: |
|
||||
# Captcha for rate limiting and 403 abuse (user can unblock themselves)
|
||||
name: captcha_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Ip" && Alert.GetScenario() in ["crowdsecurity/http-429-abuse", "crowdsecurity/http-403-abuse", "crowdsecurity/http-crawl-non_statics", "crowdsecurity/http-sensitive-files"]
|
||||
decisions:
|
||||
- type: captcha
|
||||
duration: 4h
|
||||
notifications:
|
||||
- slack_alerts
|
||||
on_success: break
|
||||
---
|
||||
# Default: Ban for serious attacks (CVE exploits, scanners, brute force)
|
||||
name: default_ip_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Ip"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
notifications:
|
||||
- slack_alerts
|
||||
on_success: break
|
||||
---
|
||||
name: default_range_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Range"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
notifications:
|
||||
- slack_alerts
|
||||
on_success: break
|
||||
|
||||
config.yaml.local: |
|
||||
db_config:
|
||||
type: mysql
|
||||
user: crowdsec
|
||||
password: ${DB_PASSWORD}
|
||||
db_name: crowdsec
|
||||
host: ${mysql_host}
|
||||
port: 3306
|
||||
api:
|
||||
server:
|
||||
auto_registration: # Activate if not using TLS for authentication
|
||||
enabled: true
|
||||
token: "$${REGISTRATION_TOKEN}" # /!\ do not change
|
||||
allowed_ranges: # /!\ adapt to the pod IP ranges used by your cluster
|
||||
- "127.0.0.1/32"
|
||||
- "192.168.0.0/16"
|
||||
- "10.0.0.0/8"
|
||||
- "172.16.0.0/12"
|
||||
|
||||
notifications:
|
||||
slack.yaml: |
|
||||
type: slack
|
||||
name: slack_alerts
|
||||
log_level: info
|
||||
format: |
|
||||
:rotating_light: *CrowdSec Alert*
|
||||
{{range .}}
|
||||
*Scenario:* {{.Alert.Scenario}}
|
||||
*Source IP:* {{.Alert.Source.IP}} ({{.Alert.Source.Cn}})
|
||||
*Decisions:*
|
||||
{{range .Alert.Decisions}} - {{.Type}} for {{.Duration}} (scope: {{.Scope}}, value: {{.Value}})
|
||||
{{end}}
|
||||
{{end}}
|
||||
webhook: ${SLACK_WEBHOOK_URL}
|
||||
Loading…
Add table
Add a link
Reference in a new issue