Un client expunea aplicatii web prin OPNsense si primea non-stop scanari si tentative de brute-force. Am integrat Caddy ca reverse proxy si CrowdSec ca sa citeasca logurile din DOUA surse — Caddy si firewallul pf — sa le coreleze si sa blocheze automat sursele ostile. Iata configuratia reala.
Cerinta: aparare corelata firewall + aplicatie
Atacurile veneau pe doua planuri: la nivel de retea (scanari de porturi, flood de conexiuni respinse) si la nivel de aplicatie web (cautare de cai, brute-force pe login, sonde de CVE). Un firewall singur vede doar reteaua; un WAF singur vede doar HTTP. Voiam o singura minte care sa vada AMBELE si sa decida.
Pe scurt: acelasi atacator e vazut si de firewall, si de aplicatia web; il blocam o data, pentru tot — automat.
Arhitectura
Internetul intra prin OPNsense (firewall pf), care trimite traficul web catre Caddy (reverse proxy cu HTTPS automat) si de acolo la aplicatii. CrowdSec citeste in paralel logurile Caddy si logurile pf, aplica scenarii, ia decizii, iar un bouncer le pune in aplicare.
Caddy: reverse proxy cu HTTPS automat + loguri
Caddy face HTTPS automat (Let's Encrypt) si logheaza in JSON — format usor de parsat de CrowdSec.
# Caddyfile
{
order crowdsec first
crowdsec {
api_url http://127.0.0.1:8080
api_key {env.CROWDSEC_BOUNCER_KEY}
}
}
app.example.com {
crowdsec # bouncer la nivel de aplicatie (403 pt IP-uri rele)
reverse_proxy 10.0.0.20:8080
log {
output file /var/log/caddy/access.log
format json
}
}
CrowdSec: citeste DOUA surse (Caddy + pf)
Aici e cheia: in acquis.yaml ii dai CrowdSec ambele surse de loguri. Asa vede si HTTP-ul (din Caddy) si reteaua (din firewallul OPNsense).
# /etc/crowdsec/acquis.yaml
---
filenames:
- /var/log/caddy/access.log
labels:
type: caddy
---
filenames:
- /var/log/filter/latest.log # logurile firewallului OPNsense (filterlog)
labels:
type: opnsense
---
source: journalctl
journalctl_filter:
- "_SYSTEMD_UNIT=sshd.service"
labels:
type: syslog
Scenarii: HTTP + firewall
Instalezi colectiile care stiu sa recunoasca atacurile din fiecare sursa — cautari de cai, brute-force, sonde CVE (din Caddy) si scanari/flood (din firewall).
cscli collections install crowdsecurity/caddy crowdsecurity/base-http-scenarios crowdsecurity/http-cve
cscli parsers install crowdsecurity/opnsense-logs # parseaza filterlog
cscli collections list
cscli hub update && cscli hub upgrade
Bouncer: blocare la firewall + 403 la Caddy
Doua nivele de aplicare: bouncerul de firewall pune IP-ul rau intr-un set pf/nftables (il opreste inainte sa ajunga la Caddy), iar bouncerul Caddy raspunde 403 la nivel de aplicatie. Impreuna acopera tot.
# 1. bouncer de firewall (pe OPNsense / Linux) -> block in pf/nftables
apt -y install crowdsec-firewall-bouncer-nftables
cscli bouncers add opnsense-fw
# 2. bouncer Caddy (403 la nivel HTTP) -> cheia din Caddyfile
cscli bouncers add caddy-bouncer
cscli bouncers list
Decizii si operare
CoreleazA totul intr-un singur set de decizii, plus reputatia comunitara (IP-uri raportate de toata reteaua CrowdSec).
cscli metrics # ce citeste din fiecare sursa
cscli decisions list # IP-urile blocate acum (din Caddy SAU pf)
cscli alerts list --since 24h
cscli console enroll <KEY> # dashboard + blocklists CTI
Rezultat
Un atacator care scaneaza porturi si apoi incearca brute-force pe login e prins de ambele surse si blocat o singura data, la firewall, inainte sa mai atinga aplicatia. Fals-pozitivele sunt reduse prin tuning, totul e vizibil in consola CrowdSec, iar reputatia comunitara opreste multe atacuri inainte sa inceapa. Il proiectam, il tunam si il dam in monitorizarea 24/7.