Cet article est adapté aux débutants puisque les données sont présentées du plus simple au plus complexe. Au début de ma carrière d'ingénieur DevOps, je manquais de tels matériaux. Je vais essayer de parler du fonctionnement de Nginx et de quelques trucs et astuces tirés de l'expérience pratique.
NGINX est construit sur une architecture non bloquante et pilotée par les événements. Il a un processus principal, plusieurs processus de travail et deux processus de gestion de cache. Pour voir cela, il suffit de lancer la commande ps avec les switchs :
ps -ef --forest | grep nginx
Le processus principal s'exécute en tant que racine et effectue des opérations nécessitant une élévation, telles que :
configuration de lecture ;
ouverture des ports ;
création de nouveaux processus.
Les ouvriers font tout le travail :
Habituellement, le nombre de travailleurs est égal au nombre de cœurs de processeur. Cela vous permet d'utiliser les ressources système aussi efficacement que possible.
Worker_processes écoute sur deux types de sockets :
Les worker_processes attendent un événement en utilisant deux types d'API : epoll ou kqueue . Lors de la réception d'un nouvel événement client sur le socket d'écoute, le worker_process crée une nouvelle connexion socket.
Ayant reçu un événement sur le socket de connexion, le worker_process exécute cette requête. Après traitement de l'événement, il n'est pas bloqué, mais il se met en veille et minimise ainsi le nombre de changements de contexte d'un système d'exploitation.
Avec l'architecture ci-dessus, la mise à jour de la configuration NGINX est aussi simple que l'envoi d'un signal SIGHUP au processus principal. Avec NGINX correctement configuré, chaque processus de travail est capable de traiter des centaines de milliers de connexions en même temps.
Après cela, les worker_processes cesseront d'accepter de nouvelles connexions, et les connexions actuelles, ayant traité l'événement, seront fermées (sans attendre le keep-alive). Dès que toutes les connexions sont fermées, le worker_process se termine. Cela vous permet de mettre à jour la configuration du serveur sans perdre les connexions, les ressources inactives ou interrompre le service client.
1. Vérifier l'exactitude de la configuration écrite avant de l'appliquer
Après avoir modifié ou créé une configuration, vous devez vérifier la syntaxe et l'exactitude de l'écriture du fichier de configuration. Nginx vous permet de vérifier l'exactitude de l'écriture de la configuration avec la commande suivante :
nginx -t
2. Recharger Nginx sans redémarrer le service
Il est recommandé d'appliquer les paramètres sans redémarrer le service. Cela ne met pas fin aux connexions en cours et élimine la période d'attente lors du chargement du service, c'est-à-dire qu'il n'y a pas de temps d'arrêt :
nginx -s reload
ou
/etc/init.d/nginx reload
ou
service nginx reload
3. Désactiver les jetons de serveur Nginx
Par défaut, la directive server_tokens dans Nginx affiche le numéro de version de Nginx. Il est directement visible sur toutes les pages d'erreur générées automatiquement et dans toutes les réponses HTTP dans l'en-tête du serveur.
Cela peut conduire à la divulgation d'informations - un utilisateur non autorisé peut découvrir votre version de Nginx. Il serait utile de désactiver la directive server_tokens
dans le fichier de configuration Nginx en définissant :
server_tokens off;
4. Désactiver les anciens protocoles SSL/TLS
ssl_protocols TLSv1.2 TLSv1.3;
5. Désactivez toutes les méthodes HTTP indésirables
Désactivez toutes les méthodes HTTP qui ne seront pas utilisées et n'ont pas besoin d'être implémentées sur le serveur Web.
Si vous ajoutez la condition suivante au bloc d'emplacement du fichier de configuration de l'hôte virtuel Nginx, le serveur n'autorisera que les méthodes GET, HEAD
et POST
et filtrera les méthodes telles que DELETE
et TRACE
:
location / { limit_except GET HEAD POST { deny all; } }
Une autre approche consiste à ajouter la condition suivante à la section serveur (ou au bloc serveur). Il peut être considéré comme plus générique, mais vous devez être prudent avec les instructions if dans le contexte d'emplacement :
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; }
6. Installer et configurer les journaux d'accès et d'erreurs Nginx
Les journaux d'accès et d'erreurs Nginx sont activés par défaut et situés respectivement dans logs/error.log
et logs/access.log,
.
Vous pouvez utiliser la directive error_log dans le fichier de configuration Nginx si vous souhaitez modifier l'emplacement. Vous pouvez également utiliser cette directive pour spécifier les journaux à consigner en fonction de leur niveau de gravité.
Par exemple, la gravité critique obligera Nginx à consigner les problèmes critiques et tous les problèmes dont le niveau de gravité est supérieur aux critiques. Pour définir le niveau de gravité sur critique, définissez la directive error_log comme suit :
error_log logs/error.log crit;
Vous pouvez trouver une liste complète des niveaux de gravité error_log dans la documentation officielle de Nginx.
Vous pouvez également modifier la directive access_log dans le fichier de configuration Nginx pour spécifier un emplacement non standard pour les journaux d'accès.
Enfin, vous pouvez utiliser la directive log_format pour personnaliser le format des messages journalisés, comme décrit dans la documentation Nginx.
7. Connexions des travailleurs Nginx
Un paramètre crucial que nous configurons est le nombre de processus de travail et le nombre de connexions de travail dans le fichier de configuration Nginx /etc/nginx/nginx.conf
.
Nous allons progressivement ajuster le flux de travail et les connexions des travailleurs à une valeur supérieure ou inférieure pour gérer les attaques DDoS :
events { worker_connections 20000; }
Ce paramètre permet à chaque processus de travail de gérer jusqu'à 20 000 connexions.
8. Demander une limite de débit
Parmi les nombreuses tactiques utiles pour prévenir les attaques DDoS, l'une des plus simples et des plus efficaces consiste à limiter le débit du trafic entrant.
Par exemple, vous pouvez spécifier le taux auquel NGINX accepte les demandes entrantes au taux moyen pour votre service à partir d'une adresse IP client spécifique pour une période spécifiée.
Nous avons défini la directive limit_req_zone dans le fichier de configuration Nginx pour limiter le nombre de requêtes :
limit_req_zone $binary_remote_addr zone=req_per_ip:1m rate=30r/m; server { location /login { limit_req zone=req_per_ip; } }
Cet exemple crée une zone de stockage nommée one qui peut contenir jusqu'à 16 000 (1m) adresses IP uniques, et 30r/m signifie que seules 30 requêtes par minute sont autorisées.
Nous utilisons ensuite la directive limit_req pour limiter la vitesse des connexions à un emplacement ou un fichier spécifique, dans ce cas, connectez-vous.
9. Limiter le nombre de connexions
Vous pouvez limiter le nombre de connexions qui peuvent s'ouvrir à partir d'une seule adresse IP client, et ici nous définissons les directives limit_conn_zone et limit_conn
pour restreindre le nombre de connexions par adresse IP :
limit_conn_zone $binary_remote_addr zone=conn_per_ip:1m; server { location / { limit_conn conn_per_ip 10; } }
Cet exemple crée une zone de stockage nommée conn_per_ip
pour stocker les requêtes pour la clé spécifiée, dans ce cas, l'adresse IP du client, $binary_remote_addr. La directive limit_conn
définit ensuite dix connexions à partir de l'adresse IP de chaque client.
10. Options de temporisation
Les connexions lentes peuvent représenter une tentative de maintenir les connexions ouvertes pendant une longue période. Par conséquent, le serveur ne peut pas accepter de nouvelles connexions :
server { client_body_timeout 5s; client_header_timeout 5s; }
Dans cet exemple, la directive client_body_timeout
spécifie la durée d'attente de Nginx entre les entrées du corps du client et client_header_timeout
spécifie la durée d'attente de Nginx entre les entrées d'en-tête du client. Les deux sont réglés sur 5 secondes.
11. Limitez la taille des requêtes
De même, de grandes valeurs de tampon ou de grandes tailles de requêtes HTTP facilitent les attaques DDoS. Ainsi, nous limitons les valeurs de tampon suivantes dans le fichier de configuration Nginx pour atténuer les attaques DDoS :
client_body_buffer_size 200K; client_header_buffer_size 2k; client_max_body_size 200k; large_client_header_buffers 3 1k;
Où,
client_body_buffer_size 1k
— (par défaut 8k ou 16k) La directive spécifie la taille du tampon du corps de la requête client ;
client_header_buffer_size 1k
- la directive définit la taille du tampon d'en-tête pour l'en-tête de requête du client. Une taille de tampon de 1 Ko est suffisante pour la grande majorité des requêtes.
Augmentez cette valeur si vous avez un en-tête personnalisé ou un cookie géant envoyé par un client (comme un client wap) ;
client_max_body_size 1k
- la directive définit la taille maximale autorisée du corps de la requête client, spécifiée par la ligne Content-Length dans l'en-tête de la requête.
Si la taille est supérieure à celle spécifiée, le client reçoit une erreur "Request Entity Too Large" (413). Augmentez cette valeur lorsque vous téléchargez des fichiers à l'aide de la méthode POST ;
large_client_header_buffers 2 1k
- la directive attribue le nombre et la taille maximum de tampons pour lire les grands en-têtes à partir d'une requête client.
Par défaut, la taille d'un buffer est égale à la taille de la page selon la plateforme, c'est soit 4K soit 8K.
Si la connexion passe à l'état keep-alive à la fin de la demande de travail, alors ces tampons sont libérés.
Par exemple, 2x1k acceptera un URI de données de 2 Ko. Cela aidera également à combattre les mauvais bots et les attaques DoS.
12. Liste noire IP
Si vous pouvez identifier les adresses IP clientes utilisées pour l'attaque, vous pouvez les mettre sur liste noire avec la directive de refus afin que NGINX et NGINX Plus n'acceptent pas leurs connexions ou requêtes :
location / { deny 111.111.111.4; deny 111.111.111.0/24; }
Dans cet exemple, le premier Deny bloque une adresse IP spécifique et le second Deny bloque toute la plage d'adresses IP.
13. Liste blanche IP
Si l'accès à votre site Web ou à votre application n'est autorisé qu'à partir d'un ou plusieurs ensembles ou plages d'adresses IP client spécifiques, vous pouvez utiliser les directives allow et deny ensemble pour autoriser uniquement ces adresses à accéder au site ou à l'application :
location / { allow 111.111.111.4; deny all; }
Vous pouvez limiter l'accès aux seules adresses d'un réseau local spécifique. Ici, la directive deny all bloque toutes les adresses IP des clients qui ne se trouvent pas dans la plage spécifiée par la directive allow.
14. Bloquer l'accès à un fichier ou à un emplacement
Vous pouvez utiliser Nginx pour bloquer complètement l'accès à un fichier ou à un emplacement. Par exemple, si vous constatez que le fichier register.php est la cible d'une attaque, vous pouvez bloquer complètement l'accès à ce fichier :
location /register { deny all; return 444; }
Cela supprimera toutes les requêtes qui tentent d'accéder à ce fichier. Le code 444 ferme la connexion sans réponse.
15. Activer la protection basée sur sysctl
Activez la protection basée sur sysctl. Nous pouvons modifier le noyau et les variables système sur notre serveur. Editez le fichier /etc/sysctl.conf
et mettez ces deux lignes à 1 comme suit :
net.ipv4.conf.all.rp_filter = 1 net.ipv4.tcp_syncookies = 1
Le premier paramètre active la protection contre l'usurpation d'adresse IP et le second paramètre active la protection des cookies TCP SYN.
16. Nginx comme équilibreur de charge
Lorsque Nginx est utilisé comme équilibreur de charge, les paramètres peuvent être configurés pour limiter le nombre de connexions par serveur :
upstream domain { server 111.111.111.4:80 max_conns=100; server 111.111.111.5:80 max_conns=100; queue 20 timeout=10s; }
Ici, la directive max_conns spécifie le nombre de connexions que Nginx peut ouvrir sur le serveur. La directive queue limite le nombre de requêtes mises en file d'attente lorsque tous les serveurs de ce groupe ont atteint la limite de connexion.
Enfin, la directive timeout spécifie combien de temps une requête peut être conservée dans la file d'attente.
17. Refuser certains agents utilisateurs
Vous pouvez facilement bloquer les agents utilisateurs, c'est-à-dire les robots d'exploration, les bots et les spammeurs qui pourraient abuser de votre serveur :
## Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; }
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot|PxBroker) { return 403; }
18. Bloquer les spams de parrainage
Le spam de référence est dangereux. Cela peut nuire à votre classement SEO via les blogs (s'ils sont publiés) puisque le champ de référence renvoie à leur site de spam. Avec ces lignes, vous pouvez bloquer l'accès aux spammeurs référents :
if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { return 403; }
19. Arrêtez le hotlinking des images
Un lien hypertexte d'image ou HTML signifie que quelqu'un relie votre site à l'une de vos images mais l'affiche sur son site.
Vous finirez par payer pour la bande passante et faire en sorte que le contenu ressemble à une partie d'un site. Cela se fait généralement sur des forums et des blogs. Je vous recommande fortement de bloquer et d'arrêter le hotlinking d'images au même niveau de votre serveur :
location /images/ { valid_referers none blocked www.domain.com domain.com; if ($invalid_referer) { return 403; } }
20. Limite le nombre de connexions par adresse IP au niveau du pare-feu
Le serveur Web doit surveiller les connexions et limiter le nombre de connexions par seconde. Cela sert 101. pf et iptables peuvent bloquer les utilisateurs finaux avant d'accéder à votre serveur Nginx.
Iptables Linux : limitation des connexions Nginx par seconde.
Dans l'exemple suivant, les connexions entrantes seront supprimées si l'IP effectue plus de 15 tentatives de connexion sur le port 80 en 60 secondes :
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set && \ /sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP && \ service iptables save
21. Désactiver le reniflage de type de contenu dans certains navigateurs
Si une réponse spécifie un type de contenu incorrect, les navigateurs peuvent traiter la réponse de manière inattendue.
Si le type de contenu est déterminé comme étant un format textuel affichable, le navigateur tentera généralement d'interpréter la réponse comme étant dans ce format, quel que soit le contenu réel de la réponse.
De plus, certains autres types de contenu spécifiés peuvent parfois être interprétés comme HTML en raison de bizarreries dans certains navigateurs. Cela pourrait conduire à un contenu autrement « sûr », tel que des images rendues au format HTML, permettant des attaques de script intersite dans certaines conditions. Ajoutez ce qui suit à votre configuration :
add_header X-Content-Type-Options nosniff;
22. Activer le filtre de script intersite (XSS)
Ajoutez la ligne suivante à votre fichier de configuration pour activer l'en-tête X-XSS-Protection sur votre serveur Web Nginx. Lorsque vous avez terminé, enregistrez vos modifications et rechargez Nginx :
add_header X-XSS-Protection "1; mode=block";
23. Configurer la prise en charge HTTP/2
HTTP/2 est le successeur du protocole réseau HTTP 1.x. HTTP/2 est largement utilisé pour réduire la latence, minimiser la surcharge du protocole, ajouter la prise en charge de la hiérarchisation des requêtes et accélérer le chargement des applications Web.
Par conséquent, il est essentiel de se tenir au courant des techniques et des stratégies d'optimisation des performances. L'objectif principal de HTTP/2 est de réduire le temps de chargement global d'une page Web, ce qui optimise les performances.
Il met également l'accent sur l'utilisation des ressources réseau et serveur, ainsi que sur une sécurité accrue, car le cryptage SSL/TLS est obligatoire lors de l'utilisation de HTTP/2.
Comme condition préalable, assurez-vous que la version de Nginx est 1.9.5 ou supérieure lors de sa construction, sinon vous devrez l'ajouter manuellement et le serveur doit activer SSL/TLS. Votre bloc de serveur HTTPS devrait maintenant ressembler à ceci :
server { listen 443 ssl http2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; }
24. Ajouter une politique de sécurité de contenu (CSP)
CSP est une couche de sécurité supplémentaire qui permet de détecter et d'atténuer certains types d'attaques, notamment les scripts intersites (XSS) et les attaques par injection de données. Ces attaques sont utilisées pour le vol de données, la corruption de sites Web et la distribution de logiciels malveillants :
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
25. Surveillance de Nginx
L'état de votre serveur doit être surveillé en permanence. Vous pouvez regarder ce que le serveur renvoie en lui envoyant périodiquement des requêtes, par exemple, via des services tiers payants. Ou vous pouvez tout ajuster, et il existe de nombreuses façons de le faire - plus à ce sujet dans le blog Nginx .
Au lieu de conclure
Il est essentiel d'être flexible et de développer une configuration pour chaque cas séparément.