Sécuriser Nginx pour le protéger des attaques DoS et bruteforce

Bloqueur de pub détectée - Vous bloquez l'affichage des publicités.
Pour soutenir le site, merci de bien vouloir laisser les publicités s'afficher
Plus d'informations : Comment désactiver les bloqueurs de publicité sur un site internet

Nginx est un serveur WEB de plus en plus prisé.
Parmi ces nombreuses fonctionnalités, il existe des parades et protections contre les attaques DoS et bruteforce.

Voici quelques réglages et configuration à appliquer pour améliorer la sécurité de votre serveur WEB.
Elles permettent de limiter certains attaques DoS et bruteforce.

Introduction aux protections Nginx

Pour rappel, il existe de nombreuses techniques et attaques DoS différentes.
Parmi ces attaques, on trouve les attaques L7 ou HTTP Flood.
Celle-ci consiste à envoyer des requêtes HTTP sur différentes pages si possible qui utilise le plus de ressources.
Cela peut conduire à saturer le serveur WEB voire le serveur dans son entier

Nginx propose plusieurs protections contre ce type d'attaque qui peuvent être activé dans la configuration du serveur WEB.
Ces protections visent à limiter le nombre de requêtes ou de connexions concurrentes pour une même adresse IP.
Il s'agit de configurer un seuil (limite de taux) et si une machine la dépasse, la requête peut être rejetée.

Il faut être conscient qu'il s'agit de bloquer trop de requêtes provenant d'une même IP.
Ainsi selon la méthode d'attaques DoS, cette protection peut ne pas suffire.
En effet, si l'attaque a un pool d'IP important il lui suffit d'éviter de trop faire de connexion depuis une même IP et faire tourner un maximum les IP disponibles.
Ainsi une adresse IP reste en dessous du seuil de déclenchement mais l'attaque peut tout de même être conséquente.

Enfin l'article vous guide pour mettre en place des blocages d'IP, referer ou sur le user agent.

Sécuriser Nginx pour le protéger des attaques DoS et bruteforce

Les limites de taux (rate limit)

limit_req_zone

Dans un premier temps, il faut créer une zone dans le contexte http à l'aide la directive limit_req_zone.
Voici la syntaxe de la directive limit_req_zone.

Syntax: 	limit_req_zone key zone=name:size rate=rate [sync];
Default: 	—
Context: 	http

Imaginons que vous souhaitez limiter le nombre de requêtes sur une adresse IP d'un client.
Voici la syntaxe que l'on peut utiliser

limit_req_zone $binary_remote_addr zone=flood:10m rate=5r/s;
  • $binary_remote_addr correspond aux adresses IP des clients qui se connectent à votre serveur WEB Nginx. Vous pouvez utiliser les variables $http_x_forwarded_for mais cela n'est pas recommandé.
  • zone est le nom de la zone que vous donnez à votre directive limit_req_zone, ici, flood
  • 10m correspond à la quantité de mémoire qui peuvent être utilisées pour stocker les adresses IP. 16,000 adresse IP utilisent environ 1 Mo, donc ici on peut en stocker 160 000.
  • enfin rate correspond au nombre de requêtes autorisées. Dans cet exemple 1 requête par seconde. On peut utiliser m pour les minutes.

limit_req

Ensuite, il faut utiliser la directive limit_req dans les blocs location ou server utilisant la zone précédemment créée.
La syntaxe est la suivante :

Syntax: 	limit_req zone=name [burst=number] [nodelay | delay=number];
Default: 	—
Context: 	http, server, location

Par exemple si on veut protéger une page login des attaques :

limit_req_zone $binary_remote_addr zone=flood:10m rate=5r/s;

location /login/ {
    limit_req zone=flood burst=12 delay=8;
    proxy_pass http://my_upstream;
}

Dans cet exemple, on charge la zone flood à 5 requêtes par seconde avec un burst à 12 et un delay de 8.
Cela signifie que l'on n'autorise que 4 requêtes.
Ainsi au delà des 8 requêtes, on impose un délai afin de ne pas dépasser la limite des 5 requêtes par seconde.
Si on ne souhaite pas imposer de délai, il faut utiliser le paramètre nodelay.

Les 8 premières demandes (la valeur de délai) sont envoyées sans délai par Nginx. Les 4 demandes suivantes (rafale - délai) sont retardées afin que le débit défini de 5 tr / s ne soit pas dépassé. Les 3 demandes suivantes sont rejetées car la taille totale de la rafale a été dépassée. Les demandes suivantes sont retardées.

Le paramètre delay se règle en fonction du nombre d'éléments chargés par page.
En général, pour la majorité des sites, il est autour de 12.

Enfin, lorsque le client dépasse la limite, une erreur 503 est renvoyée (paramétrable) ainsi que la génération de logs suivants.

11855#0: *5728 limiting requests, excess: 10.790 by zone "flood", client: xx.xx.xx.xx, server: forum.malekal.com, request: "GET /viewtopic.php?f=2 HTTP/1.0", host: "forum.malekal.com"

limit_conn conn_limit_per_ip

limit_conn conn_limit_per_ip est une autre directive qui peut-être déclaré dans les bloc server, location.
Celle-ci permet de limiter le nombre de connexion par IP.

Par exemple pour limiter le nombre de connexion par IP à 30 :

limit_conn conn_limit_per_ip 30

Au delà du nombre de connexions concurrentes autorisées alors Nginx retourne une erreur 503.

Fail2ban : protection avec iptables

Fail2ban est un daemon présent sur la plupart des distributions qui peut être utilisé en plus des protections Nginx.
Ce daemon peut lire les logs Nginx pour détecter les erreur 503 et au bout d'un certains nombres d'erreur générer une règle iptables pour bloquer complètement l'adresse IP.

Enfin, les logs fail2ban se trouvent dans /var/log/fail2ban.log

Bloquer des referrer

On peut être amené à vouloir bloquer les connexions HTTP avec certains referer (référant).
Voici comment faire sur nginx.

  • Créez le fichier /etc/nginx/blacklist-referer.conf
  • Puis inspirez-vous de ce contenu où ici les sites baidu, reddit et qq seront bloqués :
map $http_referer $bad_referer {
    hostnames;

    default                           0;

    # Put regexes for undesired referers here
        "~www.baidu.com"   1;
        "~www.reddit.com"    1;
        "~www.qq.com"    1;
}
  • Ensuite dans la directive http de nginx, il faut inclure le fichier de configuration. Si vous ne voulez pas que ce s'applique à tous les sites, le mettre dans la directive server.
include blacklist-referer.conf;
  • Enfin dans la directive server, on ajoute ce test qui retourne 403 pour les referrer à 1 dans le map.
if ($bad_referer) {
            return 403;
}

Il ne reste plus qu'à relancer nginx et tester.

Pour tester le referer avec curl, on utilise le paramètre -e :

curl -e www.sitereferer.tld https://www.monsite.tld

Bloquer des user agent

On peut faire la même chose avec les user agent.

  • Par exemple, on créé le fichier /etc/nginx/blacklist-UA.conf
map $http_user_agent $block_ua {
        default           0;
        ~*profound        1;
        ~*scrapyproject   1;
        ~*netcrawler      1;
        ~*nmap            1;
        ~*sqlmap          1;
        ~*slowhttptest    1;
        ~*nikto           1;
        ~*jersey          1;
        ~*brandwatch      1;
        ~*magpie-crawler  1;
        ~*mechanize       1;
        ~*python-requests 1;
        ~*redback         1;
        ~*python          1;
        ~*wget            1;
        ~*Pcore-HTTP      1;
        ~*HTTrack         1;
}
  • Ensuite dans la directive http de nginx, on inclut le fichier de configuration
include blacklist-UA.conf;
  • Enfin on ajoute le test :
if ($block_ua) {
                return 403;
        }
  • Enfin relancez nginx puis testez

Avec curl, pour tester le useragent, on utilise le paramètre -A en spécifiant ce dernier :

curl -A UA https://www.monsite.tld

Bloquer des adresses ou plages d'IP

Enfin il est tout à fait possible de mettre des IP en liste blanche ou listes noires.
Là aussi grâce à l'option map on peut faire des listes pour un test.

  • Par exemple créez le fichier /etc/nginx/blacklist-ip.conf
  • Ajoutez les IP à bannir en utilisant deny suivi de l'IP et un point virgule à chaque fin de ligne
deny 41.242.103.118;
deny 1.1.1.1;
deny 41.98.135.92;
deny 41.188.53.31;
deny 160.177.104.123;

Enfin on inclut le fichier de configuration dans la directive http :

include blacklist-ip.conf;

Démonstration en vidéo


Vous avez trouvé cet article utile et interressant, n'hésitez pas à le partager...

Trouver la solution sur le forum d'aide

Vous êtes arrivé au terme de l'article Sécuriser Nginx pour le protéger des attaques DoS et bruteforce mais vous n'avez pas trouvé la solution à votre problème...
Suivez ces articles du forum pour trouver une réponse ou demandez à votre tour de l'aide sur le forum