"Quand Apache se vautre, c’est qu’il est temps de passer à Nginx et quand Nginx se vautre, c’est qu’il est temps de relire ton code." Inconnu.
====== Aller plus loin avec Nginx ====== ===== Scripts d'auto-install Nginx ===== Voir : * https://github.com/stylersnico/nginx-openssl-chacha-naxsi (Avec [[https://github.com/stylersnico/my-webserver]]) * https://github.com/VirtuBox/plesk-nginx ===== Convertir un .htaccess Apache vers Nginx ===== Voir : [[http://winginx.com/en/htaccess]] ===== Masquer les informations relatives à Nginx ===== Dans le fichier ''/etc/nginx/nginx.conf'' : nano /etc/nginx/nginx.conf [...] server_tokens off; ===== Affichage du contenu des répertoire ne contenant pas de fichier d'index ===== Dans votre fichier de configuration d’hôte : autoindex on; autoindex_exact_size off; autoindex_localtime on; ===== Protéger un dossier par mot de passe ===== Comme pour Apache, on va utiliser l'utilitaire ''htpasswd'', mais comme Apache n'est pas installé, il faut installer l'outil à part : apt-get install apache2-utils On génère donc un mot de passe pour l'utilisateur voulu : htpasswd -cm /etc/nginx/.htpasswd Et on va configurer notre site pour prendre en charge l'identification : nano /etc/nginx/sites-enabled/my-site #Dans le bloc "location" du dossier à protéger location / { [...] auth_basic "Restricted Content"; auth_basic_user_file /etc/nginx/.htpasswd; } ===== Outrepasser l'erreur "could not build the server_names_hash" ===== Si l'on se retrouve avec l'erreur ''could not build the server_names_hash, you should increase server_names_hash_bucket_size'', modifier sa configuration Nginx : http { [...] server_names_hash_bucket_size 64; } Plus d'infos ici : ''https://gist.github.com/muhammadghazali/6c2b8c80d5528e3118613746e0041263'' ===== Autoriser ou bloquer des IP ===== Dans votre fichier de configuration d'hôte : server { [...] # Autoriser l'IP 10.1.1.2 allow 10.1.1.2; # Refuser le reste deny all; ===== Reverse Proxy ===== ==== Base ==== Définition d'un fichier d'hôte au niveau du reverse proxy : # On définie notre alias, en ajoutant plus d'un serveur pour mettre en place la HA si souhaitée ou même du load balancing, upstream mydomain { server 10.1.1.101; # server 10.1.1.102; # server 10.1.1.103; } server { # Le nom du serveur sous lequel doit être servi le site aux clients server_name my.domain.tld; location / { proxy_http_version 1.1; # Serveur de destination de notre requête proxy_pass http://mydomain; # Rajout d’en-tête pour transmettre quelques informations, telle que l'IP réelle du client proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_redirect http:// https://; # Timeout entre le reverse proxy et le backend proxy_connect_timeout 30; proxy_send_timeout 30; # Désactivation de la mise en cache proxy_buffering off; } } ==== Récupérer l'IP client réelle derrière un reverse proxy Nginx ==== Dans la configuration du reverse proxy Nginx, on a : proxy_set_header X-Forwarded-For $remote_addr; On édite son fichier de configuration de l'hôte : # Plusieurs sources sont acceptées, que ce soit une simple adresse IP ou même un bloc, IPv4 comme IPv6. set_real_ip_from 192.168.1.0/24; set_real_ip_from 2001:0db8::/32; set_real_ip_from 10.0.0.1; real_ip_header X-Forwarded-For; real_ip_recursive on; ==== Forward https ==== Des fois, il peut être utile de force le redirect, quand notre reverse proxy est en ''https://'' et notre backend seulement en ''http://'' : proxy_pass http://10.1.1.101; proxy_redirect http:// https://; ==== Microcaching sur un reverse proxy ==== On va mettre en cache nos données pendant seulement 1s, d’où le nom micro : intérêt limité pour sites à peu de trafic ou bien statiques, mais peut s'avérer utile tout de même, par exemple avec un #MastoDDOS \\ \\ Via : [[https://www.nginx.com/blog/benefits-of-microcaching-nginx/]] \\ \\ Soit la configuration de reverse proxy basique suivante : http { [...] server { listen 80; location / { proxy_http_version 1.1; # Autoriser les 'keepalives' pour les connexions proxy_set_header Connection ""; # Optimisation de l'encoding proxy_set_header Accept-Encoding ""; proxy_pass http://mon-app; } } upstream mon-app { # Nombre max de connexions à conserver même en mode 'idle' : http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive keepalive 20; server 10.1.1.101:80; } } / On va enfin déclarer nos caches : http { [...] # Déclaration de création d'un emplacement de cache 'nginxCache' proxy_cache_path /tmp/nginx/cache keys_zone=nginxCache:10m levels=1:2 inactive=60m max_size=1024m; server { # Utilisation de notre cache 'nginxCache' proxy_cache nginxCache; proxy_cache_lock on; proxy_cache_valid 200 1s; proxy_cache_use_stale updating; proxy_buffering off; [...] } } Explication de la ligne de création du cache ''proxy_cache_path'' : * ''/tmp/nginx/cache'' : Emplacement physique de notre dossier de cache, * ''keys_zone=nginxCache:10m'' : Déclaration du nom (''nginxCache'') de notre cache en mémoire, et sa taille en MB : pas la taille de disque alloué au cache, mais la taille en mémoire allouée aux informations des données en cache (metadatas), * ''levels=1:2'' : Définit la façon dont sont stockées les données : ici ''1:2'' implique que les fichiers sont stockés dans des sous-dossiers sous le nom de leur empreinte md5, * ''inactive=60m'' : Durée après laquelle les données en cache non utilisées sont supprimées de ce cache (peut être exprimé en minutes ''m'' ou bien en secondes ''s'' ou encore en heures ''h''), * ''max_size=1024m'' : Taille maximale physique allouée aux données en cache. Pour la partie ''server'' et utilisation du cache : * ''proxy_cache nginxCache'' : Nous dit que nous allons ici utiliser la zone de cache ''nginxCache'', * ''proxy_cache_lock on'' : Limitation des requêtes de mise en cache, et mise en file d'attente de celles-ci, * ''proxy_cache_valid 200 1s;'' : * ''proxy_cache_use_stale updating'' : Dit à Nginx de servir le fichier en cache même si celui-ci est en train d’être actualisé, * ''proxy_buffering off;'' : On supprime les buffers, si l'on sert de gros fichiers, par exemple, de la musique ou des vidéos, pour les servir directement. On voit bien donc avec ''proxy_cache_lock on'' et ''proxy_cache_use_stale updating'' que l'on tente de diminuer au maximum le nombre d'appels du reverse proxy vers nos serveurs backend. \\ \\ \\ Aller plus loin avec le cache Nginx : [[https://www.nginx.com/blog/nginx-high-performance-caching/]], [[https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching]] & [[https://serversforhackers.com/c/nginx-caching]] ==== Caching au niveau de PHP ==== On définit toujours notre cache fastCGI cette fois : fastcgi_cache_path /tmp/nginx/fastcgicache keys_zone=fastcgiCache:10m levels=1:2 inactive=60m max_size=1024m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; Et cette fois-ci, le cache sera appliqué au niveau de notre bloc d'appel à PHP : location ~ \.php$ { # Base PHP fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php7-fpm.sock; fastcgi_index index.php; include fastcgi.conf; # On utilise notre cache fastcgi_cache fastcgiCache; # On cache les requetes de type 200, 301 et 302 pour 1 minute par exemple fastcgi_cache_valid 200 301 302 1m; # Voir exemple précédent fastcgi_cache_use_stale updating; #Si l'on veut définir des blocs ou le cache sera désactivé : fastcgi_cache_bypass $no_cache; fastcgi_no_cache $no_cache; # Voir https://serverfault.com/questions/680650/nginx-fastcgi-cache-hide-set-cookie-when-serving-from-cache fastcgi_hide_header "Set-Cookie"; } On a définit le fait de ne pas utiliser de cache quand $no_cache est forcé, on peut l'utiliser de cette façon par exemple : server { listen 80; root /var/www; index index.php; server_name www.domain.tld; # 0 : cache autorisé set $no_cache 0; # Pour les pages de login et d'administration d'un Wordpress, on va désactiver le cache if ($request_uri ~* "/(wp-admin/|wp-login.php)") { # 1 : cache désactivé set $no_cache 1; } [...] ===== Cache des fichiers statiques & compression ===== Mise en cache longue durée (1an ici) de nos fichiers statiques : location ~* \.(jpg|jpeg|jpe|png|gif|ico|css|js|svg)$ { # On désactive les logs d'accès aux ressources statiques, aucune importance access_log off; # Définit que ces fichiers peuvent être mis en cache par n'importe qui : proxy ou client final add_header Cache-Control public; expires 365d; } Compression ''gzip'' sur certains types de fichiers (dans n'importe quel bloc) : # On active la compression gzip on; # On choisit un niveau de compression, de 1 à 9 gzip_comp_level 5; # Dire au proxy de conserver fichier compressé et non compressé gzip_vary on; # On ne compresse pas si taille inférieur à 1ko gzip_min_length 1024; # On compresse même si le client se connecte via proxy gzip_proxied any; # On désactive la compression pour les vieux browsers gzip_disable "MSIE [1-6]\."; # Les fichiers qui passent par la compression gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; Et on peut mixer : location ~ ^/(images)/ { add_header Pragma public; add_header Cache-Control public; expires 365d; gzip_static on; gzip_comp_level 5; gzip_vary on; gzip_min_length 1024; gzip_proxied any; gzip_disable "MSIE [1-6]\."; } ===== Cache des metadatas ===== # Mise en place de l'accès asynchrone aux fichiers aio on; # Le cache lui-même open_file_cache max=2000 inactive=1m; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; ===== Load Balancer ===== Dans notre fichier de configuration d'hôte : upstream myloadbalancer { server 10.2.2.1; server 10.2.2.2; server 10.2.2.3; } [...] location / { proxy_pass http://myloadbalancer; } Si l'on veut rajouter des priorisations de serveur, on doit jouer sur le poids ''weight'' : upstream myloadbalancer { server 10.2.2.1 weight=10; server 10.2.2.2 weight=20; server 10.2.2.3 weight=50; } Mettre en défaut un serveur qui ne répondrait pas : server 10.2.2.1 max_fails=4 fail_timeout=20s; * L'option ''ip_hash'' permet d'enregistrer l'IP visiteur, et de toujours le renvoyer vers le même serveur, * Loption ''least_conn'' renvoie la requête vers le serveur ayant le moins de connexions en cours, * Et enfin, l'option de serveur ''backup'' équivaut à un disque spare dans un RAID, il ne fait rien tant que tout est OK, et s'active pour prendre le relais d'un serveur du pool qui ne répondrait pas. upstream myloadbalancer { least_conn; ip_hash; server 10.2.2.1 weight=10 max_fails=4 fail_timeout=20s; server 10.2.2.2 weight=20 max_fails=4 fail_timeout=20s; server 10.2.2.3 weight=50 max_fails=4 fail_timeout=20s; server 10.2.2.4 backup; } Et comme pour un simple reverse proxy, on oublie pas de forward l'IP réelle à nos serveurs. ===== Rate Limit (ou comment emmerder les gens avec des erreurs 429) ===== Dans le fichier de configuration : # Nommez la zone à sa convenance, # le rate peut être exprimé en requêtes par seconde /s ou bien par minute /m limit_req_zone $binary_remote_addr zone=mazone:10m rate=10r/s; # On active ensuite les zones dans les blocs voulus server { location / { limit_req zone=mazone burst=20 nodelay; [...] } Avec : * ''$binary_remote_addr'' qui représente une IP unique, utilisé à la place du classique ''$remote_addr'' pour un soucis d'économie mémoire, * ''mazone:10m'' définie le nom de la zone crée, ainsi que sa taille mémoire allouée, sachant que 1M peut contenir environ 16.000 IP, 10M peuvent donc gérer 160.000 IP, en cas de surcharge, les plus anciennes sont supprimées au profit des plus récentes, * Le ''rate'' défini le nombre de requêtes autorisées, soit en requêtes par minutes, soit par seconde. Le tick étant en ''ms'', 10 requêtes par seconde équivaut à une requête toutes les 100ms. * Le ''burst'' permet de mettre en attente les requêtes qui dépasseraient le rate de base. Ici donc, si on a déjà nos 10 requêtes de faites, les 20 suivantes seront placées en file d'attente, et les suivantes en erreur. * ''nodelay'', sans rentrer dans les détails, fluidifie la file d'attente et la mise en attente des requêtes entrantes. Exemple avancé : geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0; } map $limit $limit_key { 0 ""; 1 $binary_remote_addr; } limit_req_zone $limit_key zone=mazone:10m rate=10r/s; server { location / { limit_req zone=req_zone burst=10 nodelay; [...] } } * Le bloc ''geo'' attribue la valeur ''1'' par défaut à la variable ''$limit'', sinon ''0'' si l'IP est autorisée, * Le bloc ''map'', définie si oui, ou non, en fonction de la variable ''$limit'' quelle zone - ou non - on active, * La zone est ensuite appliquée à l'IP, ou non appliquée si l'IP a été autorisée. A savoir aussi que l'on peut définir, et appliquer plusieurs règles dans le même bloc. \\ \\ On peut aussi définir la page d'erreur dédiée en cas de dépassement (de base, une ''erreur 503'') : limit_req_zone $limit_key zone=mazone:10m rate=10r/s; limit_req_status 429; On peut aussi changer la façon dont Nginx log les informations relatives aux limites. De base, il log en tant qu'''error'', on peut forcer les logs en tant qu'avertissement (''warn'') par exemple : server { location / { limit_req_zone $limit_key zone=mazone:10m rate=10r/s; # Choix disponibles : info, notice, warn, error limit_req_log_level warn; [...] } } ==== Pour les connexions ==== Tout comme une limite pour les requêtes, il existe une limite pour les connexions. Juste à savoir que ça peut être problématique (façon polie pour dire chiant), si ''HTTP2'' (ou encore ''SPDY'') est activé : le nombre de connexions peut exploser très vite. \\ \\ Au lieu de ''limit_req'', on utilisera donc ''limit_conn'', mais la syntaxe reste quasiment la même : http { # On définie notre zone (ou plusieurs si besoin) limit_conn_zone $binary_remote_addr zone=mazoneconnexions:10m; [...] server { [...] location / { [...] # Une seule connexion simultanée par IP, au revoir les améliorations obtenues par HTTP2 limit_conn mazoneconnexions 1; [...] } } } On peut définir le plafond par ''IP'', ou bien par bloc ''server'' : http { # Ici on limite bien par IP à l'aide de $binary_remote_addr limit_conn_zone $binary_remote_addr zone=limiteparip:10m; # Ici, on joue avec la variable $server_name pour définir la limite limit_conn_zone $server_name zone=limiteparserver:10m; [...] server { [...] # Limites par IP limit_conn limiteparip 10; # Limite par serveur limit_conn limiteparserver 100; } } Tout comme pour la limitation des requêtes, les informations liées à la limitation des connexions peuvent être loggées avec un statut personnalisé : limit_conn_log_level {info,notice,warn,error}>/code> De la même façon, le code erreur renvoyé peut être personnalisé : limit_conn_status 429; Pour s'amuser à tester les limites, on peut regarder du côté de ''https://github.com/sportebois/nginx-rate-limit-sandbox'' ===== Redirections simples ===== ==== domain.tld vers www.domain.tld ==== Soit notre fichier de configuration : server { listen 80; server_name domain.tld; # Simple redirection return 301 http://www.domain.tld$request_uri; } server { listen 80; server_name www.domain.tld; [...] } ==== http vers https ==== server { listen 80; server_name www.domain.tld; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name www.domain.tld; [...] } ==== Redirection des attaques possibles ==== location ~ ^/(xampp|phpmyadmin|licenses|webalizer|server-status|server-info|cpanel|configuration.php|htaccess|wp-admin) { access_log off; log_not_found off; deny all; } ==== Ne pas autoriser de scripts exécutables dans certains dossiers ==== location ~* /(images|cache|media|logs|tmp)/.*.(php|pl|py|jsp|asp|sh|cgi)$ { return 403; } ==== Sécuriser les fichiers qui fuitent la version de Wordpress installé ==== location ~ /(\.|wp-config.php|readme.html|licence.txt) { return 404; } ===== Changer le type de fichier par défaut ===== Si Nginx de base considère tous les fichiers comme ''application/octet-stream'', on peut tout de même forcer pour le changer, sans recourir au module ''more_headers'' : location /folder/ { types { } default_type text/plain; } ===== Threads pool ===== Dans le fichier de configuration principal de Nginx, souvent ''/etc/nginx/nginx.conf'', on ajoutera dans ce que l'on appelle le ''main context'', la partie principale du fichier, en dehors tout bloc ''{ }'' : # Activation de la prise en charge des threads aio threads; # Ensuite, on définit nos pools thread_pool pool1 threads=16 max_queue=16384; thread_pool pool2 threads=16 max_queue=0; thread_pool pool3 threads=32 max_queue=65536; thread_pool pool4 threads=32; En définissant nos pools, on leur donne donc : * Un ''nom'', pool1, pool2, pool3 ou pool4 ici, * Un ''nombre dédié de processus possible simultanément'', ici 16 ou 32, * Enfin, la ''taille de la fille d'attente'' : au minimum 0 pour désactiver la file, et au maximum 65536. Si la taille de la file n'est pas spécifiée, elle prend la valeur 65536 par défaut. \\ \\ Maintenant que nos pools sont déclarés, il faut les utiliser. Tout comme leur déclaration ne se fait que dans le bloc ''main context'', leur utilisation ne peut être faite au contraire que dans des blocs secondaires : ''http'', ''server'', ou ''location''. Par exemple : http { server { server_name sub1.domain.tld aio threads=pool3; [...] } } server { server_name sub2.domain.tld aio threads=pool3; [...] } } server { server_name www.domain.tld location /path1 { aio threads=pool3; [...] } location /path2 { aio threads=pool4; [...] } } } Pour en savoir plus sur une utilisation avancée : [[https://www.nginx.com/blog/thread-pools-boost-performance-9x/]] ===== Module : GeoIP ===== Vérifier que Nginx a bien été build avec le module : nginx -V | grep --with-http_geoip_module Si oui, tout est bon, on continue : on va télécharger les DB GeoIP et les installer au bon endroit : mkdir /etc/nginx/geoip cd /etc/nginx/geoip wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz gunzip GeoIP.dat.gz rm GeoIP.dat.gz wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz gunzip GeoLiteCity.dat.gz rm GeoLiteCity.dat.gz On édite notre fichier de configuration Nginx pour les prendre en compte : nano /etc/nginx/nginx.conf http { [...] geoip_country /etc/nginx/geoip/GeoIP.dat; geoip_city /etc/nginx/geoip/GeoLiteCity.dat; [...] } On ajoute à la configuration PHP via le fichier de configuration fastCGI les différentes variables accessibles : nano /etc/nginx/fastcgi_params [...] fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code; fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3; fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name; fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code; fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3; fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name; fastcgi_param GEOIP_REGION $geoip_region; fastcgi_param GEOIP_CITY $geoip_city; fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code; fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code; fastcgi_param GEOIP_LATITUDE $geoip_latitude; fastcgi_param GEOIP_LONGITUDE $geoip_longitude; De même, si l'on est sur un Nginx en mode reverse proxy, et que l'on souhaite transmettre ces informations au backend, on ajoutera à notre configuration proxy : proxy_set_header GEOIP_COUNTRY_CODE $geoip_country_code; proxy_set_header GEOIP_COUNTRY_CODE3 $geoip_country_code3; proxy_set_header GEOIP_COUNTRY_NAME $geoip_country_name; proxy_set_header GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code; proxy_set_header GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3; proxy_set_header GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name; proxy_set_header GEOIP_REGION $geoip_region; proxy_set_header GEOIP_CITY $geoip_city; proxy_set_header GEOIP_POSTAL_CODE $geoip_postal_code; proxy_set_header GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code; proxy_set_header GEOIP_LATITUDE $geoip_latitude; proxy_set_header GEOIP_LONGITUDE $geoip_longitude; ===== Module : WebDAV ===== Pour utiliser le module ''WebDAV'', nous auront besoin d'un paquet supplémentaire, ''nginx-extras'' : sudo apt-get install nginx-extras Pour connaitre les différences entre les paquets Nginx disponibles, consulter [[https://askubuntu.com/questions/553937/what-is-the-difference-between-the-core-full-extras-and-light-packages-for-ngi|What is the difference between the core, full, extras and light packages for nginx?]] \\ \\ Et on configure notre bloc serveur Nginx en fonction : server { server_name my.domain.tld; [...] # En accès libre, avec simple autorisation via IP location /webdav/ { root /var/www/dav; client_body_temp_path /temp; dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS; create_full_put_path on; dav_access user:rw group:rw all:rw; autoindex on; # Si l'on veut spécifier une restriction d'accès via addresses IP limit_except GET PROPFIND OPTIONS{ allow 10.0.0.0/8; deny all; } allow all; } # Protection par compte:password, voir la page de création de fichier .htpasswd location /webdav-password/ { root /var/www/dav; client_body_temp_path /temp; dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS; create_full_put_path on; dav_access user:rw group:rw all:rw; autoindex on; # Bloc pour l'identification auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; } } Le partage sera enfin accessible via son adresse [[davs://my-user@my.domain.tld]] ===== Module : autres modules intéressant à regarder ===== * [[https://github.com/openresty/headers-more-nginx-module]] : énorme flexibilité du côté des headers, que ce soit l'ajout, l'édition ou la suppression, * [[https://github.com/openresty/lua-nginx-module]] : prise en charge du langage LUA dans Nginx, * [[https://github.com/apache/incubator-pagespeed-ngx]] : Pagespeed pour Nginx, ===== Outil : utiliser h5ai pour lister le contenu des dossiers ===== On se place à la racine de l'emplacement du site, et on télécharge et install le paquet : cd /var/www/monsite wget https://release.larsjung.de/h5ai/h5ai-0.29.0.zip unzip h5ai-0.29.0.zip rm h5ai-0.29.0.zip On édite ensuite notre fichier de configuration Nginx, et on ajoute h5ai comme index : index index.html index.php /_h5ai/public/index.php; ===== Outil : Monitoring Nginx ===== On utilisera Ngxtop : apt-get install python-pip pip install ngxtop Source : [[https://github.com/lebinh/ngxtop]] ===== Outil : générateur de configuration Nginx ===== Voir : [[https://nginxconfig.io]] ===== Outil : rendre son site accessible via Tor ===== Via : [[https://memo-linux.com/son-site-sur-le-reseau-tor-en-onion-avec-nginx/]] On installe Tor : apt-get install tor On édite le fichier de configuration : nano /etc/tor/torrc Et on y ajoute les lignes : HiddenServiceDir /var/lib/tor/domain.tld/ HiddenServicePort 80 10.1.1.101:80 HiddenServicePort 443 10.1.1.101:443 On relance Tor pour valider la configuration : systemctl restart tor Pour connaître la nouvelle URL du site avec le TLD .onion : cat /var/lib/tor/tondomaine.com/hostname On peut affiner le nom de domaine avec l'outil ''Shallot'' : cd /tmp git clone https://github.com/katmagic/Shallot.git cd Shallot ./configure && make # c'est ici que l'on peut forcer à rechercher un texte pour l'appliquer ./shallot libox On copie la clé avec en-tête dans le fichier ''/var/lib/tor/domain.tld/private_key'' et on remplace l'ancienne URL par la nouvelle dans le fichier ''/var/lib/tor/domain.tld/hostname''. \\ \\ Il suffit maintenant d'éditer le fichier de configuration de Nginx, et d'appliquer le domaine : server { [...] server_name my.domain.tld liboxrandomstring.onion; [...] } ===== Bonus : configuration et optimisation du kernel pour Nginx ===== Via le fichier de configuration ''/etc/sysctl.conf'', on lui modifie/ajoute : # 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 # Increase system IP port limits net.ipv4.ip_local_port_range = 2000 65000 # 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 # Tune 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 # This will increase the amount of memory available for socket input/output queues net.ipv4.tcp_rmem = 4096 25165824 25165824 net.core.rmem_max = 25165824 net.core.rmem_default = 25165824 net.ipv4.tcp_wmem = 4096 65536 25165824 net.core.wmem_max = 25165824 net.core.wmem_default = 65536 net.core.optmem_max = 25165824 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 # Recycle Zombie connections net.inet.tcp.fast_finwait2_recycle=1 net.inet.tcp.maxtcptw=200000 # Host cache net.inet.tcp.hostcache.hashsize=4096 net.inet.tcp.hostcache.cachelimit=131072 net.inet.tcp.hostcache.bucketlimit=120 # Increase number of ports net.inet.ip.portrange.first=2000 net.inet.ip.portrange.last=100000 net.inet.ip.portrange.hifirst=2000 net.inet.ip.portrange.hilast=100000 kern.ipc.semvmx=131068 # Disable Ping-flood attacks net.inet.tcp.msl=2000 net.inet.icmp.bmcastecho=1 net.inet.icmp.icmplim=1 net.inet.tcp.blackhole=2 net.inet.udp.blackhole=1 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_tw_recycle = 1 # Turn on execshild kernel.exec-shield = 1 kernel.randomize_va_space = 1 # Increase number of files kern.maxfiles=65535 kern.maxfilesperproc=16384 # Allow for more PIDs (to reduce rollover problems); may break some programs 32768 kernel.pid_max = 65536 # Optimization for port usefor LBs # Increase system file descriptor limit fs.file-max = 65535 # Use swap when we have less than 10% of the physical memory available vm.swappiness=10 # Increase page share factor per process vm.pmap.pv_entry_max=54272521 vm.pmap.shpgperproc=20000 # Increase number of connections vfs.vmiodirenable=1 kern.ipc.somaxconn=3240000 net.inet.tcp.rfc1323=1 net.inet.tcp.delayed_ack=0 net.inet.tcp.restrict_rst=1 kern.ipc.maxsockbuf=2097152 kern.ipc.shmmax=268435456 # Increase maximum amount of memory allocated to shm kernel.shmmax = 1073741824 Et on charge les modifications avec : sysctl -p ===== Exporter sa configuration Nginx (pour tests, comparaison, aide...) ===== nginx -T > my-conf.conf ===== Guides supplémentaires ===== Voir ''https://code.tutsplus.com/series/nginx-guide--cms-792''