Premessa: useremo macchine virtuali (ad esempio VirtualBox, GNOME Boxes o KVM).
🔹 Scenario Didattico DDoS in Laboratorio
1. Architettura
VM1 – Server vittima
Debian 12 + Apache/Nginx (porta 80).
IP interno:192.168.56.10VM2 – Attaccante 1
Debian 12 + strumenti (hping3, ab, slowloris).
IP interno:192.168.56.11VM3 – Attaccante 2 (opzionale, per simulare “distributed”).
Debian 12 + stessi strumenti.
IP interno:192.168.56.12
📌 Tutte le VM collegate a rete interna (solo tra loro), così non rischi di uscire su Internet.
2. Preparazione del server (VM1)
sudo apt update && sudo apt install apache2 -ysudo systemctl enable --now apache2
Controlla che risponda:
curl http://192.168.56.10
3. Installazione strumenti sugli attaccanti (VM2 e VM3)
sudo apt updatesudo apt install hping3 apache2-utils git python3 -y
Per slowloris:
git clone https://github.com/gkbrk/slowloris.gitcd slowloris
4. Simulazioni di attacco
🔹 Test di carico legittimo (Apache Benchmark)
ab -n 1000 -c 100 http://192.168.56.10/
-n 1000= numero di richieste totali-c 100= connessioni concorrenti
Serve per vedere fino a che punto regge il server.
🔹 SYN Flood con hping3
sudo hping3 -S --flood -V -p 80 192.168.56.10
-S= SYN packet--flood= invio continuo-p 80= porta del server web
Dal lato server, osserva:
sudo netstat -ant | grep SYN
🔹 HTTP Slowloris Attack
python3 slowloris.py 192.168.56.10 -p 80 -s 500 -v
Mantiene centinaia di connessioni aperte con richieste HTTP incomplete → saturazione thread Apache.
5. Difesa lato server
Limitare connessioni per IP (esempio con Apache
mod_evasive):
sudo apt install libapache2-mod-evasive -ysudo systemctl restart apache2
- Firewall rate-limit (es. con iptables):
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPTsudo iptables -A INPUT -p tcp --dport 80 -j DROP
- Monitoraggio:
sudo dstat -nttail -f /var/log/apache2/access.log
🔹 Obiettivo Didattico
Capire come un server reagisce a diverse forme di stress.
Vedere la differenza tra traffico legittimo (benchmark) e attacco (flood, slowloris).
Imparare a mitigare con firewall, moduli e rate limiting.
MINI LABORATORIO - CHIAVI IN MANO
Serve per preparare il server (vittima), preparare gli “attaccanti” (solo nel LAB!), lanciare test controllati e a basso impatto, e provare contromisure.
Usalo solo in rete isolata / VM sui tuoi sistemi, con parametri prudenziali (niente flood o PPS elevati).
1) server_setup.sh — Server vittima (Debian 12)
#!/usr/bin/env bashset -euo pipefail
# === Config ===SERVER_WEB_ROOT="/var/www/html"TEST_PAGE_TITLE="Lab DDoS Didattico"LOG="/root/server_setup.log"
echo "[*] Aggiorno sistema e installo Apache..." | tee -a "$LOG"apt update -y && apt install -y apache2
echo "[*] Creo pagina di test..." | tee -a "$LOG"cat > "${SERVER_WEB_ROOT}/index.html" <<'HTML'<!DOCTYPE html><html lang="it"><head><meta charset="utf-8"><title>Lab DDoS Didattico</title></head><body><h1>Lab DDoS Didattico</h1><p>Questa è una pagina di prova per test di carico/difesa su rete isolata.</p></body></html>HTML
chown www-data:www-data "${SERVER_WEB_ROOT}/index.html"
echo "[*] Abilito moduli utili alla mitigazione..." | tee -a "$LOG"apt install -y libapache2-mod-evasivea2enmod reqtimeout ratelimit evasive
# Config mod_reqtimeout: chiude richieste lentecat >/etc/apache2/mods-available/reqtimeout.conf <<'CONF'<IfModule reqtimeout_module> RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500</IfModule>CONF
# Config mod_ratelimit: limita banda per risposta (dimostrazione)cat >/etc/apache2/conf-available/ratelimit-demo.conf <<'CONF'<IfModule mod_ratelimit.c> <Location "/"> SetOutputFilter RATE_LIMIT SetEnv rate-limit 400 </Location></IfModule>CONFa2enconf ratelimit-demo
# Config mod_evasive: blocco base su eccessimkdir -p /var/log/mod_evasivechown www-data:www-data /var/log/mod_evasivecat >/etc/apache2/mods-available/evasive.conf <<'CONF'<IfModule mod_evasive20.c> DOSHashTableSize 3097 DOSPageCount 20 DOSSiteCount 200 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSEmailNotify root@localhost DOSLogDir "/var/log/mod_evasive"</IfModule>CONF
echo "[*] Hardening TCP basilare (nftables rate limit su :80)..." | tee -a "$LOG"apt install -y nftablessystemctl enable --now nftables
# Regole molto conservative e facilmente rimovibilicat >/etc/nftables.conf <<'NFT'flush rulesettable inet filter { chain input { type filter hook input priority 0;
ct state established,related accept iif lo accept
# Consenti SSH locale (opzionale) tcp dport 22 accept
# Rate limit base HTTP (burst 100, 50/s) tcp dport 80 ct state new limit rate 50/second burst 100 packets accept tcp dport 80 drop
# Resto di base ip protocol icmp accept ip6 nexthdr icmpv6 accept
# Drop tutto il resto drop }}NFT
systemctl restart nftables
echo "[*] Riavvio Apache..." | tee -a "$LOG"systemctl enable --now apache2systemctl restart apache2
echoecho "[OK] Server pronto. Prova: curl http://<IP_SERVER>/"
2) attacker_setup.sh — Macchine “attaccanti” (solo LAB)
#!/usr/bin/env bashset -euo pipefail
echo "[*] Installo strumenti di test (leciti)..." apt update -yapt install -y apache2-utils slowhttptest hping3 iproute2 curl
echoecho "[OK] Attaccante pronto. Comandi disponibili:"echo " ab (ApacheBench), slowhttptest, hping3"
3) run_scenarios.sh — Esecuzione test controllati
Imposta l’IP del server e lancia uno scenario alla volta. I parametri sono moderati (no flood), così puoi osservare, fermare e ripetere.
#!/usr/bin/env bashset -euo pipefail
# === Config ===TARGET_IP="${TARGET_IP:-192.168.56.10}" # esporta TARGET_IP se vuoiTARGET_URL="http://${TARGET_IP}/"
echo "[i] Target: ${TARGET_URL}"echoecho "Seleziona scenario:"echo " 1) Benchmark legittimo (ab) - carico moderato"echo " 2) Connessioni lente (slowhttptest) - tipo slowloris controllato"echo " 3) SYN burst (hping3) - pacchetti limitati, NON flood"echo " 4) Monitor suggerito (server side)"read -rp "Scelta [1-4]: " CH
case "$CH" in 1) echo "[*] Benchmark legittimo con ab (1000 richieste, 50 concorrenti)..." ab -n 1000 -c 50 "${TARGET_URL}" ;; 2) echo "[*] Slow HTTP test controllato (connessioni lente, 200, 60s)..." # -c numero connessioni, -H header, -i intervallo, -r rate, -t durata slowhttptest -c 200 -H -i 10 -r 10 -t GET -u "${TARGET_URL}" -x 24 -p 3 -l 60 echo "[i] Report generato in ./slowhttptest_* (HTML e CSV)." ;; 3) echo "[*] SYN burst limitato (1000 pacchetti). NO flood." # Invia 1000 SYN alla :80, poi si ferma. Usa solo in rete isolata. sudo hping3 -S -p 80 -c 1000 "${TARGET_IP}" echo "[i] Completato. Osserva sul server: 'ss -tan state syn-recv' o 'journalctl -u apache2 -f'" ;; 4) cat <<'TIP'
[MONITOR SERVER] # CPU/RAM/processi top vmstat 1 dstat -nt --top-cpu --top-io
# Socket e stati TCP ss -tan | awk 'NR==1 || /:80/ {print}' watch -n1 'ss -tan state syn-recv | wc -l'
# Log Apache tail -f /var/log/apache2/access.log tail -f /var/log/apache2/error.log
# nftables counters sudo nft list ruleset
TIP ;; *) echo "Scelta non valida." exit 1 ;;esac
4) defense_toggle.sh — Accendi/Spegni mitigazioni (demo)
#!/usr/bin/env bashset -euo pipefail
ACTION="${1:-status}" # on|off|status
case "$ACTION" in on) echo "[*] Abilito reqtimeout/ratelimit/evasive + nftables..." a2enmod reqtimeout ratelimit evasive a2enconf ratelimit-demo || true systemctl restart apache2
systemctl enable --now nftables systemctl restart nftables echo "[OK] Difese ON." ;; off) echo "[*] Disabilito configurazioni demo (non farlo su sistemi reali)..." a2dismod evasive ratelimit reqtimeout || true a2disconf ratelimit-demo || true systemctl restart apache2
# nftables permissivo minimo (accetta tutto) — SOLO PER LAB cat >/etc/nftables.conf <<'NFT'flush rulesettable inet filter { chain input { type filter hook input priority 0; accept }}NFT systemctl restart nftables echo "[OK] Difese OFF (solo LAB)." ;; status) echo "[*] Apache modules:" apache2ctl -M | egrep 'evasive|ratelimit|reqtimeout' || true echo "[*] nftables ruleset:" nft list ruleset ;; *) echo "Uso: $0 {on|off|status}" exit 1 ;;esac
Come usarli (passi rapidi)
Rete isolata tra le VM (es. “Rete interna” in VirtualBox).
Server (VM1)
chmod +x server_setup.sh defense_toggle.shsudo ./server_setup.sh# facoltativo: sudo ./defense_toggle.sh on
- Attaccante/i (VM2, VM3)
chmod +x attacker_setup.sh run_scenarios.shsudo ./attacker_setup.shexport TARGET_IP=192.168.56.10./run_scenarios.sh
Osserva il server (log, connessioni, regole) mentre esegui i vari scenari.
Sperimenta accendendo/spegnendo le difese con
defense_toggle.she ripetendo i test.
Note importanti (etica & sicurezza)
Esegui questi test solo su macchine di tua proprietĂ e in rete isolata.
Parametri volutamente “soft” per osservare senza bloccare le VM.
Evito opzioni “flood”/altissimo PPS: non servono per capire dinamiche base e rischiano di saturare l’host.
Docker Compose - Mini Laboratorio
Per facilitare le operazioni ecco una versione Docker Compose così avvii tutto in pochi comandi (1 server Apache “vittima” + 2 generatori di traffico/attaccanti). Tutto resta in rete isolata del Compose.
Struttura dei file
ddos-lab/├─ docker-compose.yml├─ server/│ ├─ Dockerfile│ ├─ index.html│ └─ apache.conf└─ attacker/ ├─ Dockerfile └─ entrypoint.sh
1) docker-compose.yml
version: "3.9"
services: server: build: ./server container_name: ddos_server ports: # Espone SOLO sulla rete host locale per prova (puoi rimuovere se non serve) - "8080:80" networks: - ddosnet
attacker1: build: ./attacker container_name: ddos_attacker1 depends_on: - server networks: - ddosnet entrypoint: ["/bin/bash", "/entrypoint.sh"]
attacker2: build: ./attacker container_name: ddos_attacker2 depends_on: - server networks: - ddosnet entrypoint: ["/bin/bash", "/entrypoint.sh"]
networks: ddosnet: driver: bridge
2) Cartella server/
server/Dockerfile
FROM debian:12-slim
RUN apt-get update && apt-get install -y \ apache2 apache2-utils \&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Pagina e configurazioniCOPY index.html /var/www/html/index.htmlCOPY apache.conf /etc/apache2/conf-available/ddos-lab.conf
# Moduli utili (mitigazione base)RUN a2enmod reqtimeout ratelimit && \ a2enconf ddos-lab && \ # mod_evasive non sempre disponibile nei repo slim; se presente: (apt-get update && apt-get install -y libapache2-mod-evasive && a2enmod evasive || true) && \ echo "Done"
EXPOSE 80CMD ["bash", "-lc", "apachectl -D FOREGROUND"]
server/index.html
<!DOCTYPE html><html lang="it"><head><meta charset="utf-8"><title>Lab DDoS Didattico</title></head><body> <h1>Lab DDoS Didattico</h1> <p>Server di test per carico/mitigazioni in rete isolata Docker.</p></body></html>
server/apache.conf
# Limita richieste lente (anti slowloris)<IfModule reqtimeout_module> RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500</IfModule>
# Esempio di rate limit in uscita (dimostrativo)<IfModule mod_ratelimit.c> <Location "/"> SetOutputFilter RATE_LIMIT SetEnv rate-limit 400 </Location></IfModule>
# Config mod_evasive (se disponibile)<IfModule mod_evasive20.c> DOSHashTableSize 3097 DOSPageCount 20 DOSSiteCount 200 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSLogDir "/var/log/apache2"</IfModule>
3) Cartella attacker/
attacker/Dockerfile
FROM debian:12-slim
RUN apt-get update && apt-get install -y \ apache2-utils slowhttptest hping3 curl iproute2 procps \&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY entrypoint.sh /entrypoint.shRUN chmod +x /entrypoint.sh
# Default: tieniti in shell interattivaCMD ["/bin/bash"]
attacker/entrypoint.sh
#!/usr/bin/env bashset -e
cat <<'BANNER'===================================================== Attacker container pronto. Comandi utili: # Benchmark "legittimo" (carico moderato) ab -n 1000 -c 50 http://server/
# Slow HTTP test (tipo slowloris controllato, 60s) slowhttptest -c 200 -H -i 10 -r 10 -t GET -u http://server/ -x 24 -p 3 -l 60
# SYN burst limitato (1000 pacchetti) — usa con prudenza hping3 -S -p 80 -c 1000 server
# Monitor lato client vmstat 1 ss -tan=====================================================BANNER
# Lascia una shell per l'utenteexec /bin/bash
Avvio rapido
# Nella cartella ddos-labdocker compose builddocker compose up -d
Controlla che il server risponda:
Apri una shell su un attaccante:
docker exec -it ddos_attacker1 bash
Esegui i test (uno alla volta):
Benchmark legittimo
ab -n 1000 -c 50 http://server/
Slow HTTP (60s, controllato)
slowhttptest -c 200 -H -i 10 -r 10 -t GET -u http://server/ -x 24 -p 3 -l 60
SYN burst limitato (no flood)
hping3 -S -p 80 -c 1000 server
===============================================================
Osservazione lato server
Log e processi:
docker logs -f ddos_serverdocker exec -it ddos_server bash
# Dentro il container:tail -f /var/log/apache2/access.logtail -f /var/log/apache2/error.logps aux | grep apache
Stati delle connessioni:
docker exec -it ddos_server bash -lc "ss -tan | awk 'NR==1 || /:80/ {print}'"
Note & suggerimenti
I parametri sono moderati per evitare blocchi del laptop/host. Aumentali solo gradualmente.
Il servizio è accessibile anche da host su
http://localhost:8080(puoi rimuovere il mapping porta se vuoi tenerlo solo isolato).mod_evasivepotrebbe non essere presente in tutte le immagini base: lo script lo abilita solo se disponibile.In Docker non ha molto senso usare firewall del container per mitigazioni complesse: concentrati su mod_reqtimeout, mod_ratelimit,
KeepAlive,MaxRequestWorkers(se vuoi estendere).
Estensioni possibili
Aggiungere Nginx come reverse proxy con limit_req e conn limit.
Aggiungere Grafana/Prometheus per metriche (richiede altri container).
Introdurre fail2ban (piĂą significativo fuori da Docker o con log share).