Mitigazione attacchi DDOS L7
Nel precedente post di questa serie abbiamo parlato di mitigazione attacchi layer 7 utilizzando Crowdsec e Cloudflare. Quella soluzione era indirizzata principalmente a chi utilizza già Cloudflare oppure chi sta valutando se utilizzarlo.
Oggi vedremo come mitigare gli attacchi DDOS layer 7 utilizzando strumenti FLOSS (Free/Libre and Open Source Software). Ho già parlato di sicurezza collaborativa e gli attacchi DDOS nel precedente post per cui non starò a ripeterlo.
Installazione
Prerequisiti
Per poter eseguire questa mitigazione avremo bisogno di Crowdsec e OpenResty (NginX core + LuaJIT).
Per l’installazione di Crowdsec basta leggere le guide già fatte le guide già fatte, mentre per avere un reverse proxy valido e affidabile utilizzeremo una versione personalizzata di Nginx-proxy-manager fatta da baudneo .
Nginx proxy manager (npm)
Come già saprete, il modo migliore per avere npm è con docker compose.
Ho creato una piccola guida con una modifica al percorso indicato dal proprietario del progetto.
Creiamo una cartella (es: /opt/docker/nginx-pm) con all’interno il file docker-compose.yml e il file conf all’interno del path /data/crowdsec
docker-compose.yml
data/crowdsec/crowdsec.conf
docker-compose.yml
version: "3"
services:
app:
image: 'baudneo/nginx-proxy-manager:bullseye'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
# Uncomment the next line if you uncomment anything in the section
environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
TZ: "Europe/Rome"
ADMIN_PANEL_LOG: "1"
CROWDSEC_BOUNCER: "1"
OPENRESTY_DEBUG: "0"
CROWDSEC_LAPI: "http://172.17.0.1:8080"
CROWDSEC_KEY: "[CROWDSEC-API-KEY-FOR-BOUNCER]"
CROWDSEC_RECAP_SECRET: "[GOOGLE-SECRET]"
CROWDSEC_RECAP_SITE: "{[GOOGLE-SITE]}"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
I dati importanti sono, ovviamente, la timezone, la coppia di chiavi prese da Google e i dati di connessione a Crowdsec.
data/crowdsec/crowdsec-openresty-bouncer.conf
ENABLED=true
API_URL=${CROWDSEC_LAPI}
API_KEY=${CROWDSEC_KEY}
CACHE_EXPIRATION=1
# bounce for all type of remediation that the bouncer can receive from the local API
BOUNCING_ON_TYPE=all
FALLBACK_REMEDIATION=ban
REQUEST_TIMEOUT=3000
UPDATE_FREQUENCY=10
# live or stream
MODE=stream
# exclude the bouncing on those location
EXCLUDE_LOCATION=
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE
BAN_TEMPLATE_PATH=/crowdsec/templates/ban.html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
# ReCaptcha Secret Key
SECRET_KEY=${CROWDSEC_RECAP_SECRET}
# Recaptcha Site key
SITE_KEY=${CROWDSEC_RECAP_SITE}
CAPTCHA_TEMPLATE_PATH=/crowdsec/templates/captcha.html
CAPTCHA_EXPIRATION=3600
Il file crowdsec-openresty-bouncer.conf è stato modificato per leggere le variabili di ambiente che imposteremo all’interno del file docker-compose.
Crowdsec
Dopo aver installato Crowdsec avremo due passi da compiere: inserire un template per presentare il captcha e ottenere l’api-key. In /etc/crowdsec/profiles.yaml
name: captcha_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip" && Alert.GetScenario() startsWith "crowdsecurity/http-"
decisions:
- type: captcha
duration: 4h
on_success: break
---
e poi lanciamo
# cscli collections install crowdsecurity/base-http-scenarios
# systemctl reload crowdsec
Per l’api invece
# cscli bouncers add npm-proxy
Primo avvio dello stack
Nelle mie simulazioni e installazioni ho sempre visto che, durante il primo avvio, si raggiunge un punto di battuta per cui bisogna stoppare il servizio a mano e farlo ripartire. Ci posizioniamo della cartella con il file docker-compose.yml
# docker-compose up
e successivamente
# docker-compose up -d
se tutto va per il meglio nei log troveremo:
nginx-pm-app-1 | nginx: [alert] [lua] init_by_lua:11: [Crowdsec] Initialisation done
Mitigazione
Per testare il captca basterà aggiungere nella blacklist un ip noto.
# cscli decisions add 1.2.3.4 -t captcha
Dopo aver testato possiamo rimuoverlo
# cscli decisions delete -i 1.2.3.4
Extra
Se non abbiamo necessità particolari, il bouncer legato al firewall è molto più semplice da implementare e protegge l’host da tutti i tipi di richieste; siano esse layer7 e meno.
Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.
Risorse: