Un peu de sécurité avec Nginx🐱‍🐉

Cet article va aborder un sujet important quand on héberge un service web, la sécurité de son serveur Web. Et plus particulièrement de Nginx. 👌

Actuellement Nginx est le serveur web le plus populaire du monde, comme vous pouvez le constater ici. Il est léger, rapide, robuste et supporte une très grande majorité des systèmes d'exploitation.

C'est dire, Netflix l'utilise, preuve que le bousin est plutôt costaud!

Bon, zéééééé parti ! 😎

Quand c'est inutile...

Lorsque vous installez Nginx, il emporte automatiquement un grand nombre de modules. Pour le moment, vous ne pouvez pas choisir de modules au moment de l'exécution. Peut-être, Inch Allah, un jour ça sera possible! 🤷‍♂️

Pour désactiver certaines modules, il faut passer par une étape de re-compilation de Nginx.

Il est très fortement recommandé ainsi, de désactiver tous les modules qui ne sont pas nécessaires. Tout cela dans le but de réduire le risque d'attaques potentielles.

Par exemple:

./configure --without-http_autoindex_module
make
make install

Cachez-vous ! 😜

C'est une chose que je vois trop souvent, l'affichage du numéro de version de Nginx encore actif. On est d'accord, vous ne donneriez pas l'info à un voleur pour ouvrir votre voiture, bien là, c'est pareil !

Par défaut, la directive server_tokens affiche le numéro de version de Nginx. C'est directement visible dans les pages d'erreur mais aussi dans les réponses HTTP, dans le header Server.

Pour désactiver ça:

http {
    ...
    server_tokens off;
    ...
}
/etc/nginx/nginx.conf

Pour vérifier:

printf "$(curl -sI localhost | grep -oP 'Server: \K.+')\n"

Tromper l'ennemi 😎

Quand je parle de tromper l'ennemi, du header HTTP Server. La technique du dessus consisté à ne plus afficher le numéro de version sur ce header mais ne cache pas le type de serveur web utilisé: Server: nginx.

Pour palier à ça, il est possible de tromper l'ennemi en remplaçant Server: nginx par Server: apache par exemple!

Pour ce faire:

sudo apt update; sudo apt install nginx-extras -y

Ensuite:

http {
      ...
      # Replace nginx with apache or whatever you want as server name.
      more_set_headers 'Server: apache';
      ...
}
/etc/nginx/nginx.con

Contrôler et limiter les ressources ‼

Pour prévenir d'éventuelles attaques par déni de service sur nginx, vous pouvez fixer des limites de taille de mémoire tampon pour tous les clients.

Vous pouvez le faire dans le fichier de configuration nginx en utilisant les directives suivantes :

  • client_body_buffer_size, utilisez cette directive pour spécifier la taille du tampon du corps de la requête du client. La valeur par défaut est de 8k ou 16k mais il est recommandé de la fixer à 1k.

Exemple:

client_body_buffer_size 1k
/etc/nginx/nginx.conf
  • client_header_buffer_size, utilisez cette directive pour spécifier la taille du tampon de l'en-tête de la requête du client. Une taille de tampon de 1k est adéquate pour la plupart des requêtes.
  • client_max_body_size, utilisez cette directive pour spécifier la taille maximale acceptée pour une requête client. Une directive de 1k devrait être suffisante, mais vous devez l'augmenter si vous recevez des téléchargements de fichiers via la méthode POST. 😉
  • large_client_header_buffers, utilisez cette directive pour spécifier le nombre et la taille maximum des tampons à utiliser pour lire les en-têtes des requêtes de clients de grande taille.

Exemple:

large_client_header_buffers 2 1k 
/etc/nginx/nginx.conf

Dans cet exemple, le nombre maximum de tampons est de 2, chaque tampon ayant une taille maximale de 1k. A noter que cette directive accepte les URI de données de 2kB. Que demande le peuple! 😁

Waf waf wafffff !🐶

A titre perso j'utilise Naxsi comme solution de WAF (Web Application Firewall). C'est un outil français (cocorico 😁). Je vous laisse vous rendre sur la documentation officielle pour plus d'infos.

Vous avez aussi ModSecurity qui est très bien mais je n'ai pas autant joué avec, je ferais un article très bientôt sur Naxsi.

Inclure les Security Headers

Pour renforcer votre serveur web nginx, vous pouvez ajouter plusieurs en-têtes HTTP différents. Voici quelques-unes des options que je vous recommande très fortement! 😉

http {
    ...
    # Prevent clickjacking attacks
    add_header X-Frame-Options "SAMEORIGIN" always;

    # Add an HSTS header to your nginx server
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; always";

    # Cross-site scripting protection
    add_header X-XSS-Protection "1; mode=block";
    default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';

    # Prevention of MIME confusion-based attacks
    add_header X-Content-Type-Options "nosniff" always;

    # Hide X-Powered-By header
    proxy_hide_header X-Powered-By;
    more_clear_headers 'X-Powered-By';

    # Referrer policy
    add_header Referrer-Policy "origin-when-cross-origin" always;
    ...
}
/etc/nginx/nginx.conf

Vous pouvez ensuite tester votre site ici. 😉

Bloquer certaines user-agent...

Parfois, il peut être intéressant de bloquer, dans certains cas, que les utilisateurs puissent utiliser la commande curl ou wget sur votre site (pour le télécharger par exemple).

server {
    ...
    # Block wget user agent
    if ($http_user_agent ~* (wget|curl) ) {
          return 403;
    }
    ...
}
/etc/nginx/site-enabled/example.org

Il est possible de tester en utilisant la commande:

curl -Is https://www.example.org | grep HTTP

Normalement, vous devrez obtenir une erreur type 403. 🐱‍🏍

Limiter les accès via l'adresse IP 👍

Sur des accès plus sensibles, il est intéressant de mettre en place un filtrage au niveau de l'adresse IP dans la configuration Nginx directement.

location / {
    ...
    # Block one workstation
    deny    192.168.1.1;

    # Allow anyone in 192.168.1.0/24
    allow   192.168.1.0/24;

    # Drop rest of the world
    deny    all;
    ...
}
/etc/nginx/site-enabled/example.org

Tu l'utilises pas, tu désactives...

Il est fortement conseillé de désactiver les méthodes HTTP que vous n'utilisez pas, par exemple:

server {
    ...
    location / {
        limit_except GET HEAD POST {
            deny all;
        }
    }
    ...
}
/etc/nginx/site-enabled/example.org

Le security.txt

Le fichier security.txt est une norme proposée pour les informations de sécurité des sites Web. Il est destinée à permettre aux chercheurs en sécurité informatique de signaler facilement les failles de sécurité (exemple Orange).

Pour commencer on va créer le fichier:

cat <<EOF > /var/www/html/.security.txt
Contact: secu@example.org
Rate-limit: 300
Preferred-Languages: EN
EOF

Ensuite, on va modifier la configuration d'un virtualhost:

server {
        ...
        location /security.txt {
                return 301 http://$host/.well-known/security.txt;
        }

        location = /.well-known/security.txt {
                alias /var/www/html/.security.txt;
        }
        ...
}
/etc/nginx/site-enabled/example.org

Configurer le SSL et les suites de Cipher 👌

La configuration par défaut de nginx vous permet d'utiliser les anciennes versions non sécurisées du protocole TLS (selon la documentation officielle : ssl_protocols TLSv1 TLSv1.1 TLSv1.2).

Cela peut conduire à des attaques telles que l'attaque BEAST. Par conséquent, nous vous recommandons de ne pas utiliser les anciens protocoles TLS et de modifier votre configuration afin de ne prendre en charge que les versions TLS plus récentes et sécurisées.

Pour ce faire, ajoutez la directive suivante dans la section serveur du fichier de configuration nginx :

ssl_protocols TLSv1.2 TLSv1.3;
/etc/nginx/nginx.conf

En outre, vous devez spécifier les suites de chiffrement pour vous assurer qu'aucune suite vulnérable n'est prise en charge.

Pour sélectionner les meilleures suites de chiffrement, ajoutez une directive ssl_ciphers à la section serveur pour sélectionner les chiffres.

Il est recommandé d'utiliser la directive suivante:

ssl_prefer_server_ciphers on;
/etc/nginx/nginx.conf

Cette directive permettra de décider des chiffres à utiliser côté serveur et non côté client. 😃

Mettez à jour votre serveur

Ca va de soit mais c'est souvent pas fait, pour ce faire vous pouvez suivre mon article présent ici.

La gala-Gixy! 🐱‍👤

Gixy est un outil open-source qui vous permet de vérifier si votre serveur web nginx présente des erreurs de configuration typiques. Une fois que vous avez préparé votre configuration nginx, il est toujours bon de la vérifier avec Gixy.

Enfin voilà, vous aurez pour commencer, quelques bases pour sécuriser un minima votre serveur web Nginx.