Passer au contenu principal

Comment protéger vos APIs en installant et en configurant ModSecurity dans Nginx

Au quotidien, notre équipe DevOps construit une multitude d’architectures pour fournir une base solide pour les intégrations et les développements ultérieurs. D’autres fois, notre travail est de revoir les architectures existantes, de les réorganiser et de proposer des améliorations, la plupart du temps la sécurité au périmètre est un point à renforcer. Par conséquent, dans cet article, nous vous parlerons de certaines des améliorations que nous proposons généralement par défaut dans la plupart des situations et nous expliquerons comment protéger vos APIs en installant et en configurant ModSecurity dans Nginx.

Glosario de términos: Hardening, Réseau Tor, User Agent y WAF

Ensuite, certains des termes dont nous parlerons au cours de l’article seront définis :

Bastionné ou Hardening

Bastionné ou Hardening  est le processus de renforcement des configurations par défaut que les systèmes d’exploitation apportent dans le but d’améliorer la sécurité, d’éviter l’escalade de privilèges, d’éviter les vulnérabilités, les services ou les ports exposés sans utilisation.

Réseau Tor

Réseau Tor est un réseau créé par un logiciel créé sur le réseau Internet, il utilise le cryptage, le VPN et les sauts entre les nœuds de ce réseau pour fournir l’anonymat, il est généralement utilisé par les pirates pour cacher leur IP, ce réseau peut être utilisé à des fins simplement d’anonymat et recherche ou à des fins moins légales.

User Agent

User Agent fait référence à l’identifiant où sont affichées les informations sur le service et la version, il se trouve généralement dans les en-têtes des services, des scanners de logiciels, des serveurs Web et des services en général.

WAF

Web Application Firewall (WAF) est un pare-feu applicatif, tout comme un pare-feu réseau fonctionne en filtrant les paquets dans ses politiques ou règles, un WAF est spécialisé dans la couche applicative, filtrant en profondeur le trafic au niveau applicatif, pouvant détecter les attaques et établir des règles de filtrage ou personnalisées ou défini dans la norme OWASP.

Cas d’utilisation ou champ d’application

Généralement, le contexte est toujours le même ou très similaire, des serveurs web ou des machines virtuelles Linux/Windows qui entrent dans la plateforme en tant que serveur d’application web, proxy ou équilibreur.

Le facteur commun est que normalement ces systèmes d’exploitation sont trouvés par défaut, ce qui n’est pas recommandé dans un ordinateur à la frontière entre Internet et notre réseau interne.

La réalité que nous rencontrons

De nos jours, presque toutes les organisations ont un pare-feu réseau ou NGF et une zone DMZ, ce qui se passe généralement, c’est que le pare-feu réseau si les politiques n’ont pas été très bien ajustées, les services exposés au niveau de l’application sont généralement ignorés qu’il n’est pas correctement limité au service, hôte ou application que nous exposons, et c’est que la bonne chose serait d’appliquer les signatures du système d’exploitation (Ubuntu Linux, serveur Windows etc …), puis d’appliquer le signatures du service (Apache, Nginx, ISS), puis les signatures applicatives.

Une fois ces réglages terminés nous pouvons ajouter le module WAF de base, certains pare-feux ont ce module, ce module n’agit pas avec la même efficacité qu’un WAF, principalement parce qu’il ne l’est pas, mais il ajoute une certaine amélioration, par contre nous avons politiques anti DDoS A ce propos, si votre firewall dispose de cette option, il est conseillé de l’activer, nous savons que ces fonctions sont des fonctions supplémentaires et qu’elles ne seront pas aussi efficaces que le hardware ou l’host dédié.

Dans certaines organisations, nous nous retrouvons avec le scénario précédent et nous faisons nos recommandations. De plus, lorsque nous commençons à déployer notre architecture ou à auditer ou rectifier l’architecture du client, nous ajoutons quelques améliorations de base.

Procédure effectuée:

  1. Nous générons d’abord un rapport pré-bastion sur tous les hôtes qui font partie de l’architecture ou du projet.
  2. Deuxièmement, nous partageons le résultat avec le client, nous faisons nos recommandations et voyons jusqu’où il veut aller.
  3. Le processus d’Hardening ou de bastion varie selon le système d’exploitation et il existe plusieurs guides ou outils pour le gérer, tels que CIS Benchmarks, nous préparons généralement des processus automatisés pour le bastion d’un grand nombre d’actifs, bien que nous ayons précédemment développé et testé l’automatisation de durcissement, alors nous pouvons utiliser Ansible ou combiner avec Bash ou PowerShell selon le cas.

En fin de compte, il s’agit d’intégrer le point de vue de la sécurité dans l’ensemble du workflow et dans tous les domaines.

Et ce n’est pas facultatif si nous voulons être à jour et protéger nos systèmes et applications, c’est là qu’apparaît le profil ou la méthodologie DevSecOps.

DevOps + Automatisation = Sécurité

DevOps + Automatisation = Sécurité

Nginx protégeant les applications

Comme nous l’avons mentionné précédemment, nous intégrons par défaut certaines améliorations de sécurité sur le bastion mentionné ci-dessus et sur le proxy ou l’équilibreur.

Dans cette section, nous allons commenter les améliorations techniques que nous avons ajoutées à NGINX et c’est qu’avec NGINX nous avons l’option du WAF open source appelé modsecurity ou sa version payante NGINX + appelée WAF.

Afin d’utiliser modsecurity, nous devons compiler la dernière version de Nginx en la préparant à utiliser le module modsecurity.

Cette fois, nous allons donner quelques instructions et exigences pour Centos 8 / Redhat.

Packages et référentiels requis

Ensuite, nous allons installer les packages nécessaires pour une distribution Redhat/Centos 8:

# dnf mettre à jour
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -y
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y


dnf install gcc-c++ flex bison yajl curl-devel zlib-devel pcre-devel autoconf automake git curl make libxml2-devel pkgconfig libtool httpd-devel redhat-rpm-config wget openssl openssl-devel nano -y

dnf --enablerepo=powertools install doxygen yajl-devel -y
dnf --enablerepo=remi install geoip-devel -y
yum install geoip-devel -y

Installation et compilation modsecurity 

Nous allons maintenant installer modsecurity, pour cela nous allons compiler, vous pouvez suivre les instructions suivantes:

# Nous allons cloner le dépôt modsecurity pour nginx dans le répertoire opt
cd /opt/ && git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity

# Nous entrons dans le répertoire, téléchargeons la dernière version et compilons le module.
cd ModSecurity
git submodule init
git submodule update
./build.sh && ./configure

make && make install
 
# nous descendons modsecurity-nginx
cd /opt
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git

Installation et compilation de Nginx avec compatibilité modsecurity 

Nous téléchargeons la dernière version stable à partir de la page officielle, décompressons, compilons et installons:

wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -xvzf nginx-1.18.0.tar.gz
cd /opt/nginx-1.18.0

./configure --user=nginx --group=nginx --with-pcre-jit --with-debug --with-http_ssl_module  --with-http_realip_module --add-module=/opt/ModSecurity-nginx

Mise en service de modsecurity

Exemple de fichier de configuration Nginx activant la sécurité mod:

#Exemple de modèle  /usr/local/nginx/conf/nginx.conf

user  nginx;
worker_processes  1;
pid  /run/nginx.pid;
events {
     worker_connections  1024;
 }

 http {
     include	  mime.types;
     default_type  application/octet-stream;
     sendfile        on;
     keepalive_timeout  65;
     server {
         listen       80;
         server_name  your-server-ip;
         modsecurity  on;
         modsecurity_rules_file  /usr/local/nginx/conf/modsecurity.conf;
         access_log  /var/log/nginx/access.log;
         error_log  /var/log/nginx/error.log;
         location / {
             root   html;
             index  index.html index.htm;
         }
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   html;

Rechargement et test de la configuration

Nous allons maintenant appliquer les modifications à configurer modsecurity, valider que la configuration est correcte et redémarrer le service:

#Configuration de la sécurité du module dans nginx

sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/g' /usr/local/nginx/conf/modsecurity.conf
sed -i 's/\/var\/log\/modsec_audit.log/\/var\/log\/nginx\/modsec_audit.log/g' /usr/local/nginx/conf/modsecurity.conf


#Nous testons la configuration
nginx -t

# Habilitamos el demonio e iniciamos el servicio nginx
systemctl daemon-reload
systemctl start nginx
systemctl enable --now nginx
systemctl status nginx

Configuration de la sécurité mod avec les règles OWASP

Nous téléchargeons les règles OWASP depuis son référentiel et les incluons dans la configuration de modsecurity:

git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/local/nginx/conf/owasp-crs
mv /usr/local/nginx/conf/owasp-crs/crs-setup.conf.example /usr/local/nginx/conf/owasp-crs/crs-setup.conf

echo "Include owasp-crs/crs-setup.conf" >> /usr/local/nginx/conf/modsecurity.conf
echo "Include owasp-crs/rules/*.conf" >> /usr/local/nginx/conf/modsecurity.conf

nginx -t 

# Si tout se passe bien, on redémarre.
systemctl restart nginx

Bloquer l’accès depuis Red Tor

Dans cette section, nous expliquerons la capacité de Nginx à bloquer une IP pour bloquer son accès.

Pour bloquer l’accès à certaines adresses IP dans Nginx, la syntaxe est la suivante.

deny 192.168.1.2;

deny 192.168.1.3;

Maintenant que vous savez comment bloquer les listes d’adresses IP, nous pouvons maintenant télécharger la liste des nœuds de sortie à partir de la source torproject.

Si nous créons un script pour télécharger la liste IP et formater la sortie, nous pouvons avoir une liste similaire à celle-ci :

deny 104.244.73.215;

deny 198.98.62.107;

deny 104.244.79.203;

deny 209.141.55.90;

deny 209.141.41.214;

deny 143.110.236.82;

deny 93.95.227.227;

Nous pouvons enregistrer la sortie ci-dessus dans un fichier, par exemple inclure /opt/nginx_deny_tor.txt;

Il est conseillé d’automatiser l’étape précédente pour maintenir la liste à jour, nous pourrions le faire avec CRONTAB.

Maintenant, si nous allons dans la documentation de Nginx, nous pouvons voir que parmi ses nombreuses options, une permet de bloquer une liste d’adresses IP, nous pouvons inclure la liste comme indiqué dans l’exemple:

location / {

   include /opt/nginx_deny_tor.txt;

   #…...etc...

}

Blocage des scanners de vulnérabilité ou similaires via user agent

location / {
   include /opt/nginx_deny_tor.txt;
   if ($http_user_agent ~* (^w3af.sourceforge.net|dirbuster|nikto|wpscan|SF|sqlmap|fimap|nessus|whatweb|Openvas|jbrofuzz|libwhisker|webshag)) {
        return 444;
   }

Comme vous pouvez le voir dans la section précédente, nous ajoutons un conditionnel basé sur l’User Agent à l’emplacement / la configuration, si elle correspond à l’une des options, la connexion sera fermée.

Nous pouvons modifier notre agent utilisateur dans le navigateur Firefox avec cet outil appelé User Agent Switcher à des fins de test.

Conclusion

  • Nous avons discuté de l’importance et de certains outils des systèmes de bastionnement.
  • Nous avons discuté de la façon dont nous pouvons ajouter la sécurité des modules à Nginx en tant que WAF.
  • Nous avons discuté de la façon de bloquer les connexions du Réseau Tor.
  • Nous avons expliqué comment fermer la connexion aux clients avec un User Agent indésirable.