// infrastructure — défense en profondeur

BRIQUES DE SÉCURITÉ

DÉFENSE EN PROFONDEUR  ·  FAIL2BAN  ·  CROWDSEC  ·  UFW  ·  GEOIP2  ·  SSH

6 couches de défense fail2ban · CrowdSec UFW firewall GeoIP2 · SSH hardened Rotation des clés
6
COUCHES DE DÉFENSE
3
SERVEURS PROTÉGÉS
0
EXPOSITION SSH WAN
LAN
UNIQUEMENT ACCÈS SSH
// défense en profondeur — modèle en couches

$ cat defense-in-depth.json

Chaque couche intercepte une catégorie de menaces différente. Une attaque doit traverser toutes les couches pour atteindre l'application. Modèle inspiré du principe de moindre privilège et de la segmentation réseau.

COUCHE 1 — RÉSEAU UFW Firewall — ports autorisés uniquement
COUCHE 2 — TRANSPORT SSL/TLS — TLSv1.2 + TLSv1.3 · HSTS · dhparam
COUCHE 3 — GÉOGRAPHIQUE GeoIP2 — restriction pays · whitelist IP fixe
COUCHE 4 — COMPORTEMENTALE CrowdSec — analyse patterns · ban automatique
COUCHE 5 — APPLICATIVE nginx Headers · Rate Limiting · WAF AppSec
COUCHE 6 — ACCÈS ADMIN SSH — ed25519 · port non standard · fail2ban
// démarche chronologique — ordre de mise en place

$ cat chronologie-securite.txt

L'ordre d'implémentation est important. On sécurise d'abord les accès admin (SSH), puis le périmètre réseau, puis on empile les couches applicatives.

01
SSH Hardening
port non standard
clé ed25519 seule
PasswordAuth no
MaxAuthTries 4
02
UFW Firewall
deny all par défaut
ouverture ports explicites
80/443/SSH/8080 LAN
03
fail2ban
jails SSH + HTTP
LAN whitelisté
bantime/findtime
maxretry configurés
04
SSL/TLS
certbot --nginx
renouvellement auto
options-ssl-nginx.conf
05
Security Headers
snippet nginx
HSTS preload
CSP stricte
X-Frame DENY
06
Rate Limiting
zones nginx
whitelist LAN
burst nodelay
07
GeoIP2
module nginx
base MaxMind
restriction géo
whitelist admin
08
CrowdSec
collections nginx
collections linux
bouncer firewall
AppSec WAF 7422
// UFW — règles type

$ cat ufw-rules.txt

Politique par défaut : tout bloquer en entrée, tout autoriser en sortie. Ouverture explicite des services nécessaires uniquement. Le réseau local est traité différemment (SSH LAN uniquement).

// UFW — POLITIQUE DENY ALL + OUVERTURES EXPLICITES
# Politique par défaut ufw default deny incoming ufw default allow outgoing # Services publics ufw allow 80/tcp comment 'HTTP' ufw allow 443/tcp comment 'HTTPS' # SSH — LAN uniquement (jamais exposé sur internet) ufw allow in to [NGINX_IP] port [SSH_PORT] proto tcp \ from [LAN_SUBNET] comment 'SSH LAN only' # Monitoring interne — LAN uniquement ufw allow in to [NGINX_IP] port 8080 proto tcp \ from [LAN_SUBNET] comment 'Monitoring LAN' # Règles sortantes explicites (backends) ufw allow out to [BACKEND_IP_A] port 80 ufw allow out to [BACKEND_IP_B] port 80 # Activer ufw enable && ufw status numbered
// fail2ban — configuration type

$ cat fail2ban-config.txt

fail2ban surveille les logs et bannit les IPs après N échecs dans une fenêtre de temps. Le réseau local est systématiquement whitelisté pour éviter l'auto-blocage lors des rotations de clés ou des tests.

// /ETC/FAIL2BAN/JAIL.LOCAL
# /etc/fail2ban/jail.local [DEFAULT] ignoreip = 127.0.0.1/8 ::1 [LAN_SUBNET] bantime = 1h findtime = 10m maxretry = 3 banaction = nftables [sshd] enabled = true port = [SSH_PORT] backend = systemd maxretry = 3 bantime = 2h findtime = 10m # Vérifier qu'un jail est actif : # fail2ban-client status sshd # Vérifier la whitelist LAN : # fail2ban-client get sshd ignoreip
// CrowdSec — analyse comportementale + WAF

$ cat crowdsec-stack.txt

CrowdSec analyse les logs en temps réel et bannit les IPs dont le comportement correspond à des patterns d'attaque connus. Le bouncer firewall bloque au niveau réseau. L'AppSec WAF (port 7422) intercepte les attaques applicatives avant qu'elles atteignent le backend.

Firewall Bouncer
Lit les décisions CrowdSec → bannit via nftables au niveau réseau. Actif sur les 3 serveurs.
AppSec WAF
auth_request nginx → analyse chaque requête sur port 7422 → bloque SQLi/XSS/traversal. Actif sur les vhosts publics.
// /ETC/NGINX/SNIPPETS/CROWDSEC-APPSEC.CONF
# /etc/nginx/snippets/crowdsec-appsec.conf # À inclure dans les locations exposées publiquement auth_request /crowdsec-appsec; location = /crowdsec-appsec { internal; proxy_pass http://127.0.0.1:7422; proxy_pass_request_body on; proxy_set_header Content-Length $content_length; proxy_set_header X-Crowdsec-Appsec-Ip $remote_addr; proxy_set_header X-Crowdsec-Appsec-Uri $request_uri; proxy_set_header X-Crowdsec-Appsec-Host $host; proxy_set_header X-Crowdsec-Appsec-Verb $request_method; proxy_set_header X-Crowdsec-Appsec-Api-Key "[BOUNCER_API_KEY]"; proxy_read_timeout 5s; }
// SSH — durcissement & rotation des clés

$ cat ssh-hardening.txt

Une clé ed25519 dédiée par serveur. Pas de réutilisation de clé entre destinations. Rotation périodique. Le LAN est systématiquement whitelisté dans fail2ban avant toute rotation pour éviter le lockout.

01
Génération clé
ssh-keygen -t ed25519
-C "[usage]"
une clé par lien
02
Déploiement
ssh-copy-id
ou authorized_keys
test avant durcissement
03
Hardening sshd
Port [non-standard]
PermitRootLogin
prohibit-password
PasswordAuth no
04
Rotation
nouvelle clé → déploiement
→ test → retrait ancienne
LAN whitelisté f2b
05
Audit
grep authorized_keys
entrées obsolètes
rotation-ssh.log
// /ETC/SSH/SSHD_CONFIG.D/99-HARDENED.CONF
# /etc/ssh/sshd_config.d/99-hardened.conf Port [SSH_PORT] PermitRootLogin prohibit-password PasswordAuthentication no PubkeyAuthentication yes MaxAuthTries 4 MaxSessions 5 X11Forwarding no AllowAgentForwarding no # Tester avant reload : # sshd -t && systemctl reload ssh # Connexion type depuis le client : # ssh -i ~/.ssh/[key_name] -p [SSH_PORT] \ # -o IdentitiesOnly=yes user@[HOST]
// audit & vérification posture sécurité

$ cat audit-posture.txt

Commandes de vérification périodique. À exécuter après chaque changement de configuration ou lors d'un audit de sécurité.

Vérification Commande Attendu
fail2ban jails actifs fail2ban-client status sshd et nginx actifs
IPs bannies actives fail2ban-client status sshd liste bans en cours
LAN whitelisté f2b fail2ban-client get sshd ignoreip [LAN_SUBNET] présent
Règles UFW ufw status numbered politique deny · ports explicites
CrowdSec décisions cscli decisions list bans actifs par IP
CrowdSec collections cscli collections list nginx + linux installés
Headers SSL curl -I https://[domaine] HSTS + headers sécurité
Score TLS testssl.sh [domaine] TLSv1.2/1.3 uniquement · Grade A
Config nginx valide nginx -t syntax is ok
Processus actifs systemctl status nginx fail2ban crowdsec active (running)