
Nginx est un serveur web/proxy inverse et proxy de messagerie (IMAP/POP3) léger et performant. Il fonctionne sous UNIX, GNU/Linux, les variantes BSD, Mac OS X, Solaris et Microsoft Windows. Selon Netcraft, 13,50% de tous les domaines sur Internet utilisent le serveur web Nginx. Nginx est l'un des rares serveurs écrits pour résoudre le problème du C10K. Contrairement aux serveurs traditionnels, Nginx ne s'appuie pas sur des threads pour traiter les demandes. Au lieu de cela, il utilise une architecture événementielle (asynchrone) beaucoup plus évolutive. Nginx alimente plusieurs sites Web à fort trafic, tels que WordPress, Hulu, Github et SourceForge.
Cette page rassemble des conseils pour améliorer la sécurité des serveurs web nginx fonctionnant sur des systèmes d'exploitation Linux ou de type UNIX.
Niveau de difficulté | Facile |
Privilèges de la racine | Oui |
Exigences | Terminal Linux ou Unix |
Catégorie | Serveur Web |
Compatibilité avec les systèmes d'exploitation | AIX-Alma-Alpine-Arch-BSD-Debian-Fedora-FreeBSD-HP-UX-Linux-macOS- Mint - NetBSD -OpenBSD-openSUSE- Pop!_OS -RHEL- Rocky -Stream-SUSE-Ubuntu-Unix-WSL |
Durée de lecture estimée | 20 minutes |
Fichiers de configuration par défaut et port Nginx
- /usr/local/nginx/conf/ ou /etc/nginx/- Le répertoire de configuration du serveur nginx et /usr/local/nginx/conf/nginx.conf est le fichier de configuration principal.
- /usr/local/nginx/html/ ou /var/www/html- L'emplacement par défaut du document.
- /usr/local/nginx/logs/ ou /var/log/nginx - L'emplacement par défaut du fichier journal.
- Nginx Port HTTP par défaut TCP 80
- Nginx Port HTTPS par défaut : TCP 443
Vous pouvez tester les changements de configuration de nginx comme suit :
# /usr/local/nginx/sbin/nginx -t
OU
# nginx -t
Exemples de résultats :
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/nginx/conf/nginx.conf test is successful
Pour charger les changements de configuration, tapez :
# /usr/local/nginx/sbin/nginx -s reload
OU
# nginx -s reload
Pour arrêter le serveur, tapez :
# /usr/local/nginx/sbin/nginx -s stop
OU
# nginx -s stop
#1 : Activer SELinux
Security-Enhanced Linux (SELinux) est une fonctionnalité du noyau Linux qui fournit un mécanisme de prise en charge des politiques de sécurité de contrôle d'accès qui offre une grande protection. Elle peut arrêter de nombreuses attaques avant que votre système ne s'enracine. Voyez comment activer SELinux pour les systèmes basés sur CentOS / RHEL.
Faire un verrouillage booléen
Exécutez la commande getsebool -a et verrouillez le système :
getsebool -a | less getsebool -a | grep off getsebool -a | grep on
Pour sécuriser la machine, regardez les paramètres qui sont définis sur 'on' et changez-les en 'off' s'ils ne s'appliquent pas à votre configuration à l'aide de la commande setsebool. Définissez les booléens SE Linux corrects pour maintenir la fonctionnalité et la protection. Veuillez noter que SELinux ajoute 2 à 8 % de frais généraux à une installation typique de RHEL ou CentOS.
#2 : Autoriser des privilèges minimaux via les options de montage
Servez toutes vos pages web / fichiers html / php via des partitions séparées. Par exemple, créez une partition appelée /dev/sda5 et montez sur le /nginx. Assurez-vous que /nginx est monté avec les permissions noexec, nodev et nosetuid. Voici mon entrée /etc/fstab pour le montage de /nginx :
LABEL=/nginx /nginx ext3 defaults,nosuid,noexec,nodev 1 2
Notez que vous devez créer une nouvelle partition en utilisant les commandes fdisk et mkfs.ext3.
#3 : Linux /etc/sysctl.conf Hardening
Vous pouvez contrôler et configurer les paramètres du noyau Linux et du réseau via le fichier /etc/sysctl.conf.
# Avoid a smurf attack net.ipv4.icmp_echo_ignore_broadcasts = 1 # Turn on protection for bad icmp error messages net.ipv4.icmp_ignore_bogus_error_responses = 1 # Turn on syncookies for SYN flood attack protection net.ipv4.tcp_syncookies = 1 # Turn on and log spoofed, source routed, and redirect packets net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # No source routed packets here net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # Turn on reverse path filtering net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # Make sure no one can alter the routing tables net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 # Don't act as a router net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Turn on execshild kernel.exec-shield = 1 kernel.randomize_va_space = 1 # Tuen IPv6 net.ipv6.conf.default.router_solicitations = 0 net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.default.autoconf = 0 net.ipv6.conf.default.dad_transmits = 0 net.ipv6.conf.default.max_addresses = 1 # Optimization for port usefor LBs # Increase system file descriptor limit fs.file-max = 65535 # Allow for more PIDs (to reduce rollover problems); may break some programs 32768 kernel.pid_max = 65536 # Increase system IP port limits net.ipv4.ip_local_port_range = 2000 65000 # Increase TCP max buffer size setable using setsockopt() net.ipv4.tcp_rmem = 4096 87380 8388608 net.ipv4.tcp_wmem = 4096 87380 8388608 # Increase Linux auto tuning TCP buffer limits # min, default, and max number of bytes to use # set max to at least 4MB, or higher if you use very high BDP paths # Tcp Windows etc net.core.rmem_max = 8388608 net.core.wmem_max = 8388608 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1
Voir aussi :
- Linux Tuning Le sous-système VM (mémoire)
- Linux ajuste la pile réseau (taille des tampons) pour augmenter les performances du réseau
#4 : Supprimer tous les modules Nginx indésirables
Vous devez minimiser le nombre de modules qui sont compilés directement dans le binaire de nginx. Cela minimise les risques en limitant les capacités autorisées par le serveur Web. Vous pouvez configurer et installer nginx en utilisant uniquement les modules nécessaires. Par exemple, pour désactiver les modules SSI et autoindex, vous pouvez taper :
# ./configure --without-http_autoindex_module --without-http_ssi_module
# make
# make install
Tapez la commande suivante pour voir quels modules peuvent être activés ou désactivés lors de la compilation du serveur nginx :
# ./configure --help | less
Désactivez les modules nginx dont vous n'avez pas besoin.
(Facultatif) Changer l'en-tête de la version de Nginx
Editez src/http/ngx_http_header_filter_module.c, entrez :
# vi +48 src/http/ngx_http_header_filter_module.c
Trouver la ligne
static char ngx_http_server_string[] = "Server: nginx" CRLF; static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
Modifiez-les comme suit :
static char ngx_http_server_string[] = "Server: Ninja Web Server" CRLF; static char ngx_http_server_full_string[] = "Server: Ninja Web Server" CRLF;
Sauvegardez et fermez le fichier. Maintenant, vous pouvez compiler le serveur. Ajoutez ce qui suit dans nginx.conf pour désactiver le numéro de version de nginx affiché sur toutes les pages d'erreur générées automatiquement :
server_tokens off;
Voir Comment cacher la version de Nginx sous Linux et Unix pour d'autres options de configuration possibles.
#5 : Utiliser mod_security (uniquement pour les serveurs Apache backend)
mod_security fournit un pare-feu au niveau des applications pour Apache. Installez mod_security sur tous les serveurs web Apache dorsaux. Cela permettra de stopper de nombreuses attaques par injection.
#6 : Installer la politique SELinux pour renforcer le serveur web Nginx.
Par défaut, SELinux ne protège pas le serveur web nginx. Cependant, vous pouvez installer et compiler la protection comme suit. Tout d'abord, installez le support SELinux requis au moment de la compilation :
# yum -y install selinux-policy-targeted selinux-policy-devel
Téléchargez des politiques SELinux ciblées pour renforcer le serveur web nginx sur les serveurs Linux à partir de l'adresse suivante accueil du projet page :
# cd /opt
# wget http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc
Untar la même :
# tar -zxvf se-ngix_1_0_10.tar.gz
Compilez le même
# cd se-ngix_1_0_10/nginx
# make
Exemples de résultats :
Compiling targeted nginx module /usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod Creating targeted nginx.pp policy package rm tmp/nginx.mod.fc tmp/nginx.mod
Installez le module SELinux nginx.pp qui en résulte :
# /usr/sbin/semodule -i nginx.pp
#7 : Pare-feu basé sur les Iptables restrictifs
Le script de pare-feu suivant bloque tout et ne fait qu'autoriser :
- Demandes HTTP entrantes (port TCP 80)
- Requêtes ping ICMP entrantes
- Requêtes sortantes ntp (port 123)
- Demandes smtp sortantes (port TCP 25)
#!/bin/bash IPT="/sbin/iptables" #### IPS ###### # Get server public ip SERVER_IP=$(ifconfig eth0 | grep 'inet addr:' | awk -F'inet addr:' '{ print $2}' | awk '{ print $1}') LB1_IP="204.54.1.1" LB2_IP="204.54.1.2" # Do some smart logic so that we can use damm script on LB2 too OTHER_LB="" SERVER_IP="" [[ "$SERVER_IP" == "$LB1_IP" ]] && OTHER_LB="$LB2_IP" || OTHER_LB="$LB1_IP" [[ "$OTHER_LB" == "$LB2_IP" ]] && OPP_LB="$LB1_IP" || OPP_LB="$LB2_IP" ### IPs ### PUB_SSH_ONLY="122.xx.yy.zz/29" #### FILES ##### BLOCKED_IP_TDB=/root/.fw/blocked.ip.txt SPOOFIP="127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32 168.254.0.0/16 224.0.0.0/4 240.0.0.0/5 248.0.0.0/5 192.0.2.0/24" BADIPS=$( [[ -f ${BLOCKED_IP_TDB} ]] && grep -E -v "^#|^$" ${BLOCKED_IP_TDB}) ### Interfaces ### PUB_IF="eth0" # public interface LO_IF="lo" # loopback VPN_IF="eth1" # vpn / private net ### start firewall ### echo "Setting LB1 $(hostname) Firewall..." # DROP and close everything $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP # Unlimited lo access $IPT -A INPUT -i ${LO_IF} -j ACCEPT $IPT -A OUTPUT -o ${LO_IF} -j ACCEPT # Unlimited vpn / pnet access $IPT -A INPUT -i ${VPN_IF} -j ACCEPT $IPT -A OUTPUT -o ${VPN_IF} -j ACCEPT # Drop sync $IPT -A INPUT -i ${PUB_IF} -p tcp ! --syn -m state --state NEW -j DROP # Drop Fragments $IPT -A INPUT -i ${PUB_IF} -f -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL ALL -j DROP # Drop packets $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " Packets " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL NONE -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # Drop XMAS $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " XMAS Packets " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP # Drop FIN packet scans $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " Fin Packets Scan " $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags FIN,ACK FIN -j DROP $IPT -A INPUT -i ${PUB_IF} -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP # Log and get rid of broadcast / multicast and invalid $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type broadcast -j LOG --log-prefix " Broadcast " $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type broadcast -j DROP $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type multicast -j LOG --log-prefix " Multicast " $IPT -A INPUT -i ${PUB_IF} -m pkttype --pkt-type multicast -j DROP $IPT -A INPUT -i ${PUB_IF} -m state --state INVALID -j LOG --log-prefix " Invalid " $IPT -A INPUT -i ${PUB_IF} -m state --state INVALID -j DROP # Log and block spoofed ips $IPT -N spooflist for ipblock in $SPOOFIP do $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j LOG --log-prefix " SPOOF List Block " $IPT -A spooflist -i ${PUB_IF} -s $ipblock -j DROP done $IPT -I INPUT -j spooflist $IPT -I OUTPUT -j spooflist $IPT -I FORWARD -j spooflist # Allow ssh only from selected public ips for ip in ${PUB_SSH_ONLY} do $IPT -A INPUT -i ${PUB_IF} -s ${ip} -p tcp -d ${SERVER_IP} --destination-port 22 -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -d ${ip} -p tcp -s ${SERVER_IP} --sport 22 -j ACCEPT done # allow incoming ICMP ping pong stuff $IPT -A INPUT -i ${PUB_IF} -p icmp --icmp-type 8 -s 0/0 -m state --state NEW,ESTABLISHED,RELATED -m limit --limit 30/sec -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p icmp --icmp-type 0 -d 0/0 -m state --state ESTABLISHED,RELATED -j ACCEPT # allow incoming HTTP port 80 $IPT -A INPUT -i ${PUB_IF} -p tcp -s 0/0 --sport 1024:65535 --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A OUTPUT -o ${PUB_IF} -p tcp --sport 80 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT # allow outgoing ntp $IPT -A OUTPUT -o ${PUB_IF} -p udp --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p udp --sport 123 -m state --state ESTABLISHED -j ACCEPT # allow outgoing smtp $IPT -A OUTPUT -o ${PUB_IF} -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT $IPT -A INPUT -i ${PUB_IF} -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT ### add your other rules here #### ####################### # drop and log everything else $IPT -A INPUT -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix " DEFAULT DROP " $IPT -A INPUT -j DROP exit 0
Consultez les tutoriels suivants pour plus d'informations :
- Comment configurer un pare-feu UFW sur un serveur Ubuntu 16.04 LTS ?
- Tutoriel de configuration des pare-feu Iptables CentOS / Redhat
- Linux : 20 exemples d'Iptables pour les nouveaux SysAdmins
- Consultez également les exemples de commandes ufw et iptables.
#8 : Contrôler les attaques par dépassement de tampon
Modifiez le fichier nginx.conf et définissez les limites de taille de la mémoire tampon pour tous les clients.
# vi /usr/local/nginx/conf/nginx.conf
Modifiez et définissez les limites de taille de la mémoire tampon pour tous les clients comme suit :
## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##
Où,
- taille_corps_buffer_client 1k - (par défaut 8k ou 16k) Cette directive spécifie la taille du tampon du corps de la requête du client.
- client_header_buffer_size 1k - La directive définit la taille du tampon d'en-tête pour l'en-tête de la requête du client. Pour la grande majorité des requêtes, une taille de tampon de 1K est suffisante. Augmentez cette taille si vous avez un en-tête personnalisé ou un gros cookie envoyé par le client (par exemple, le client wap).
- client_max_body_size 1k- La directive assigne la taille maximale acceptée pour le corps de la requête du client, indiquée par la ligne Content-Length dans l'en-tête de la requête. Si la taille est supérieure à celle indiquée, le client reçoit l'erreur "Request Entity Too Large" (413). Augmentez cette valeur lorsque vous recevez des téléchargements de fichiers via la méthode POST.
- large_client_header_buffers 2 1k - La directive attribue le nombre maximal et la taille des tampons pour les gros en-têtes à lire à partir de la requête du client. Par défaut, la taille d'un tampon est égale à la taille de la page, selon la plate-forme, il s'agit de 4K ou 8K. Si, à la fin de la requête, la connexion passe à l'état keep-alive, ces tampons sont libérés. 2x1k acceptera 2kB de données URI. Cela permettra également de lutter contre les mauvais robots et les attaques DoS.
Vous devez également contrôler les délais d'attente pour améliorer les performances du serveur et couper les clients. Modifiez-le comme suit :
## Start: Timeouts ## client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; ## End: Timeouts ##
- client_body_timeout 10 ; - La directive définit le délai de lecture du corps de la requête du client. Le délai d'attente est défini uniquement si le corps de la requête n'est pas obtenu en une seule étape de lecture. Si après ce délai le client n'envoie rien, nginx renvoie l'erreur "Request time out" (408). La valeur par défaut est de 60.
- client_header_timeout 10 ; - La directive attribue un délai d'attente à la lecture du titre de la requête du client. Le délai d'attente n'est fixé que si un en-tête n'est pas obtenu en un seul pas de lecture. Si après ce délai le client n'envoie rien, nginx renvoie l'erreur "Request time out" (408).
- keepalive_timeout 5 5 ; - Le premier paramètre attribue le délai d'attente pour les connexions keep-alive avec le client. Le serveur fermera les connexions après ce délai. Le deuxième paramètre, facultatif, attribue la valeur du temps dans l'en-tête Keep-Alive : timeout=time de la réponse. Cet en-tête peut convaincre certains navigateurs de fermer la connexion, afin que le serveur n'ait pas à le faire. Sans ce paramètre, nginx n'envoie pas d'en-tête Keep-Alive (bien que ce ne soit pas ce qui rend une connexion "keep-alive").
- send_timeout 10 ; - La directive attribue un délai de réponse au client. Le délai n'est pas établi sur le transfert entier de la réponse, mais seulement entre deux opérations de lecture, si après ce temps le client ne prend rien, alors nginx ferme la connexion.
#9 : Contrôle des connexions simultanées
Vous pouvez utiliser le module NginxHttpLimitZone pour limiter le nombre de connexions simultanées pour la session assignée ou, dans un cas particulier, à partir d'une adresse IP. Modifiez le fichier nginx.conf :
### Directive describes the zone, in which the session states are stored i.e. store in slimits. ### ### 1m can handle 32000 sessions with 32 bytes/session, set to 5m x 32000 session ### limit_zone slimits $binary_remote_addr 5m; ### Control maximum number of simultaneous connections for one session i.e. ### ### restricts the amount of connections from a single ip address ### limit_conn slimits 5;
L'option ci-dessus limite les clients distants à un maximum de 5 connexions "ouvertes" simultanément par adresse IP distante.
#N°10 : Autoriser l'accès à notre domaine uniquement
Si le robot ne fait que scanner un serveur au hasard pour tous les domaines, refusez-le. Vous ne devez autoriser que les demandes de domaines virtuels ou de reverse proxy configurés. Vous ne voulez pas afficher les requêtes utilisant une adresse IP :
## Only requests to our Host are allowed i.e. nixcraft.in, images.nixcraft.in and www.nixcraft.in if ($host !~ ^(nixcraft.in|www.nixcraft.in|images.nixcraft.in)$ ) { return 444; } ##
#11 : Limitez les méthodes disponibles
GET et POST sont les méthodes les plus courantes sur Internet. Les méthodes des serveurs Web sont définies dans RFC 2616 . Si un serveur web ne nécessite pas la mise en œuvre de toutes les méthodes disponibles, celles-ci doivent être désactivées. L'exemple suivant filtrera et n'autorisera que les méthodes GET, HEAD et POST :
## Only allow these request methods ## if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } ## Do not accept DELETE, SEARCH and other methods ##
En savoir plus sur les méthodes HTTP
- La méthode GET est utilisée pour demander des documents tels que http://www.hebergementwebgratuit.com/index.php.
- La méthode HEAD est identique à GET, sauf que le serveur NE DOIT PAS renvoyer un corps de message dans la réponse.
- La méthode POST peut concerner n'importe quoi, comme le stockage ou la mise à jour de données, la commande d'un produit ou l'envoi d'un courriel en soumettant le formulaire. Cette méthode est généralement traitée à l'aide de scripts côté serveur tels que PHP, PERL, Python, etc. Vous devez utiliser cette méthode si vous souhaitez télécharger des fichiers et traiter des formulaires sur le serveur.
#12 : Comment puis-je refuser certains agents utilisateurs ?
Vous pouvez facilement bloquer les agents utilisateurs, c'est-à-dire les scanners, les bots et les spammeurs qui pourraient abuser de votre serveur.
## Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; } ##
Bloquer les robots appelés msnbot et scrapbot :
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot) { return 403; }
#12 : Comment bloquer les pourriels de recommandation ?
Le spam de référence est un déni de service. Il peut nuire à votre classement dans les moteurs de recherche via les journaux Web (s'ils sont publiés), car le champ de référence renvoie à leur site de spam. Vous pouvez bloquer l'accès aux spammeurs de référence avec ces lignes.
## Deny certain Referers ### if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { # return 404; return 403; } ##
#13 : Comment arrêter le Hotlinking d'images ?
Le hotlinking d'image ou HTML signifie que quelqu'un établit un lien vers votre site vers l'une de vos images, mais l'affiche sur son propre site. Le résultat final est que vous finirez par payer des factures de bande passante et que le contenu semblera faire partie du site du pirate. Cela se fait généralement sur les forums et les blogs. Je vous suggère fortement de bloquer et d'arrêter le hotlinking d'images au niveau de votre serveur lui-même.
# Stop deep linking or hot linking location /images/ { valid_referers none blocked www.example.com example.com; if ($invalid_referer) { return 403; } }
Exemple : Réécriture et affichage de l'image
Un autre exemple avec un lien vers l'image interdite :
valid_referers blocked www.example.com example.com; if ($invalid_referer) { rewrite ^/images/uploads.*.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last }
Voir aussi :
- Comment faire : Utiliser la carte nginx pour bloquer le hotlinking des images. Ceci est utile si vous voulez bloquer des tonnes de domaines.
#14 : Restrictions de répertoire
Vous pouvez définir le contrôle d'accès pour un répertoire spécifique. Tous les répertoires web doivent être configurés au cas par cas, en autorisant l'accès uniquement lorsque cela est nécessaire.
Limitation de l'accès par adresse IP
Vous pouvez limiter l'accès au répertoire par adresse IP au répertoire /docs/ :
location /docs/ { ## 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; }
Protéger le répertoire par un mot de passe
Tout d'abord, créez le fichier de mots de passe et ajoutez un utilisateur appelé vivek :
# mkdir /usr/local/nginx/conf/.htpasswd/
Editez nginx.conf et protégez les répertoires requis comme suit :
### Password Protect /personal-images/ and /delta/ directories ### location ~ /(personal-images/.*|delta/.*) { auth_basic "Restricted"; auth_basic_user_file /usr/local/nginx/conf/.htpasswd/passwd; }
Une fois qu'un fichier de mots de passe a été généré, les utilisateurs suivants peuvent être ajoutés avec la commande suivante :
# htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName
#15 : Configuration SSL de Nginx
HTTP est un protocole en texte clair et il est ouvert à la surveillance passive. Vous devriez utiliser le protocole SSL pour crypter votre contenu pour les utilisateurs :
- Comment faire : Créer un certificat SSL auto-signé sur Nginx pour CentOS / RHEL
- Comment configurer Nginx avec un certificat SSL gratuit Let's Encrypt sur Debian ou Ubuntu Linux
- Comment installer le certificat SSL/TLS gratuit de Letsencrypt pour Nginx sur Alpine Linux
- Comment configurer le passage SSL/TLS de Nginx avec l'équilibrage de charge TCP ?
- nginx : Configuration du proxy inverse SSL (proxy SSL à charge équilibrée)
#16 : Conseils de sécurité pour Nginx et PHP
PHP est l'un des langages de script côté serveur les plus populaires. Editez /etc/php.ini comme suit :
# Disallow dangerous functions disable_functions = phpinfo, system, mail, exec ## Try to limit resources ## # Maximum execution time of each script, in seconds max_execution_time = 30 # Maximum amount of time each script may spend parsing request data max_input_time = 60 # Maximum amount of memory a script may consume (8MB) memory_limit = 8M # Maximum size of POST data that PHP will accept. post_max_size = 8M # Whether to allow HTTP file uploads. file_uploads = Off # Maximum allowed size for uploaded files. upload_max_filesize = 2M # Do not expose PHP error messages to external users display_errors = Off # Turn on safe mode safe_mode = On # Only allow access to executables in isolated directory safe_mode_exec_dir = php-required-executables-path # Limit external access to PHP environment safe_mode_allowed_env_vars = PHP_ # Restrict PHP information leakage expose_php = Off # Log all errors log_errors = On # Do not register globals for input data register_globals = Off # Minimize allowable PHP post size post_max_size = 1K # Ensure PHP redirects appropriately cgi.force_redirect = 0 # Disallow uploading unless necessary file_uploads = Off # Enable SQL safe mode sql.safe_mode = On # Avoid Opening remote files allow_url_fopen = Off
Voir aussi :
- Sécurité PHP : Limiter les ressources utilisées par le script
- Paramètres PHP.INI : Désactiver exec, shell_exec, system, popen et autres fonctions pour améliorer la sécurité
#17 : Exécutez Nginx dans une prison chroot (conteneurs) si possible.
Le fait de placer nginx dans une prison chroot minimise les dommages causés par une effraction potentielle en isolant le serveur Web dans une petite section du système de fichiers. Vous pouvez utiliser une configuration traditionnelle de type chroot avec nginx. Si possible, utilisez les jails FreeBSD, XEN, les conteneurs Linux sur une Debian/Ubuntu, LXD sur une Fedora, ou la virtualisation OpenVZ qui utilise le concept de conteneurs.
#18 : Limite les connexions par IP au niveau du pare-feu
Un serveur web doit garder un œil sur les connexions et limiter les connexions par seconde. C'est le service 101. Tant pf que iptables peuvent limiter les utilisateurs finaux avant d'accéder à votre serveur nginx.
Iptables Linux : Limiter les connexions Nginx par seconde
L'exemple suivant abandonne les connexions entrantes si l'IP fait plus de 15 tentatives de connexion au port 80 dans les 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
BSD PF : Limiter les connexions Nginx par seconde
Editez votre /etc/pf.conf et mettez-le à jour comme suit. Ce qui suit limitera le nombre maximum de connexions par source à 100. 15/5 spécifie le nombre de connexions par seconde ou par intervalle de secondes, c'est-à-dire que le taux limite le nombre de connexions à 15 dans un intervalle de 5 secondes. Si quelqu'un enfreint nos règles, il est ajouté à notre table abusive_ips et bloqué pour toute nouvelle connexion. Enfin, le mot-clé flush tue tous les états créés par la règle de correspondance qui proviennent de l'hôte qui dépasse ces limites.
webserver_ip="202.54.1.1" tablepersist block in quick from pass in on $ext_if proto tcp to $webserver_ip port www flags S/SA keep state (max-src-conn 100, max-src-conn-rate 15/5, overload flush)