Après avoir décidé de me passer de Cloudflare, j’ai cherché le moyen de bloquer les attaques DDOS avec NGinx via fail2ban : voici donc un mémo détaillant la mise en place d’une protection (ddos mitigation) basique.
Bloquer les attaques DDOS avec NGinx
Commencez par ouvrir la configuration générale de NGinx
sudo nano /etc/nginx/nginx.conf
Nous allons utiliser deux variables :
- limit_req : permet de limiter le nombre de requetes maximum par IP et par seconde
- limit_conn : permet de limiter le nombre de connexions maximum par IP
Au début du bloc http ajoutez donc les lignes suivantes
#Requete maximun par ip limit_req_zone $binary_remote_addr zone=flood:10m rate=100r/s; limit_req zone=flood burst=100 nodelay; #Connexions maximum par ip limit_conn_zone $binary_remote_addr zone=ddos:10m; limit_conn ddos 100;
L’exemple ci-dessus vous permet de limiter une IP à 100 connexions simultanées ou 100 requêtes par seconde (ce qui est déjà énorme). Si une personne devait dépasser l’une de ces limites votre serveur lui servirait alors une jolie erreur 503.
Testez donc la configuration de votre serveur
sudo nginx -t
Si tout fonctionne redémarrez le
sudo service nginx restart
Bloquer les attaques DDOS avec NGinx via fail2ban
Lorsque NGinx bloque une IP à cause de son trop grands nombres de requêtes et/ou connexions simultanés il l’indique dans ses logs. Si ces informations sont loguées elles peuvent alors être utilisées par fail2ban. Pour bloquer les IPs des attaquants nous allons créer deux règles fail2ban : une pour limit_conn et une pour limit_req
Créons un fichier pour notre première règle
sudo nano /etc/fail2ban/filter.d/nginx-conn-limit.conf
Dans celui-ci, collez les lignes de configuration suivantes
# Fail2Ban configuration file # # supports: ngx_http_limit_conn_module [Definition] failregex = limiting connections by zone.*client: <HOST> # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Créons maintenant notre seconde règle
sudo nano /etc/fail2ban/filter.d/nginx-req-limit.conf
Dans lequel nous ajoutons la configuration ci-dessous
# Fail2Ban configuration file # # supports: ngx_http_limit_req_module [Definition] failregex = limiting requests, excess:.* by zone.*client: <HOST> # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Nos règles sont paramétrées, il faut maintenant demander à fail2ban de les utiliser. Modifions la configuration de fail2ban
sudo nano /etc/fail2ban/jail.local
Ajoutons deux blocs : 1 par règle
[nginx-req-limit] enabled = true filter = nginx-req-limit action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp] logpath = /var/log/nginx/*error.log findtime = 600 bantime = 7200 maxretry = 10 [nginx-conn-limit] enabled = true filter = nginx-conn-limit action = iptables-multiport[name=ConnLimit, port="http,https", protocol=tcp] logpath = /var/log/nginx/*error.log findtime = 300 bantime = 7200 maxretry = 100
Rechargez la configuration de fail2ban
sudo service fail2ban reload
Vérifiez que les règles soient bien chargées
sudo fail2ban-client status
Ce qui dans mon cas me donne
Status |- Number of jail: 4 `- Jail list: nginx-conn-limit, nginx-req-limit, ssh, nginx-http-auth
Pour avoir plus d’information sur le nombres d’échecs et bannissements
sudo fail2ban-client status nginx-conn-limit && sudo fail2ban-client status nginx-req-limit
Ce qui nous donne
Status for the jail: nginx-conn-limit |- filter | |- File list: /var/log/nginx/error.log | |- Currently failed: 0 | `- Total failed: 0 `- action |- Currently banned: 0 | `- IP list: `- Total banned: 0 Status for the jail: nginx-req-limit |- filter | |- File list: /var/log/nginx/error.log | |- Currently failed: 0 | `- Total failed: 0 `- action |- Currently banned: 0 | `- IP list: `- Total banned: 0
Si vous effectuez des tests et que votre IP est bannie utilisez la commande suivante
sudo fail2ban-client set nom-de-regle unbanip XXX.XXX.XXX.XXX
Sources