« Nginx » : différence entre les versions
(5 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 893 : | Ligne 893 : | ||
= [https://doc.owncloud.org/server/latest/admin_manual/installation/nginx_examples.html ownCloud] = | = [https://doc.owncloud.org/server/latest/admin_manual/installation/nginx_examples.html ownCloud] = | ||
= [ | = Mediawiki = | ||
== [https://www.mediawiki.org/wiki/Manual:Short_URL/Nginx Pretty URL avec php-fpm] == | |||
<filebox fn=/etc/nginx/nginx.conf lang=bash collapsed> | |||
# Explicit access to the root website, redirect to main page | |||
location = / { | |||
return 301 /wiki/Accueil; | |||
} | |||
location ^~ /cache/ { | |||
deny all; | |||
} | |||
# Allow access to those folders | |||
location ^~ /images/ { } | |||
location ^~ /sitemap/ { } | |||
location = /sitemap.xml { } | |||
# Handling for the article path (pretty URLs) | |||
location ^~ /wiki/ { | |||
rewrite ^/wiki/(?<pagename>.*)$ /index.php; | |||
} | |||
# Every other entry point will be disallowed | |||
location / { | |||
return 404; | |||
} | |||
location ~ \.php$ { | |||
include snippets/fastcgi-php.conf; | |||
fastcgi_pass unix:/run/php/php-fpm.sock; | |||
} | |||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { | |||
try_files $uri =404; | |||
expires max; | |||
log_not_found off; | |||
} | |||
</filebox> | |||
<filebox fn=LocalSettings.php lang=php collapsed> | |||
$wgArticlePath = "/wiki/$1"; | |||
</filebox> | |||
== Pretty URL avec uwsgi == | == Pretty URL avec uwsgi == | ||
<filebox fn=/etc/nginx/nginx.conf lang=bash> | <filebox fn=/etc/nginx/nginx.conf lang=bash collapsed> | ||
# only in production | # only in production | ||
error_page 403 404 = /index.php; | error_page 403 404 = /index.php; | ||
Ligne 938 : | Ligne 980 : | ||
expires max; | expires max; | ||
} | } | ||
</filebox> | </filebox> | ||
<filebox fn=LocalSettings.php lang=php collapsed> | |||
<filebox fn=LocalSettings.php lang=php> | |||
$wgArticlePath = "/wiki/$1"; | $wgArticlePath = "/wiki/$1"; | ||
</filebox> | </filebox> | ||
== URL classique == | == [https://www.nginx.com/resources/wiki/start/topics/recipes/mediawiki/ URL classique] == | ||
<filebox fn=/etc/nginx/nginx.conf lang=bash> | <filebox fn=/etc/nginx/nginx.conf lang=bash collapsed> | ||
server { | server { | ||
listen 80; | listen 80; | ||
Ligne 1 047 : | Ligne 1 066 : | ||
sudo systemctl start nginx | sudo systemctl start nginx | ||
</kode> | </kode> | ||
{{info | The default served page at <nowiki>http://127.0.0.1</nowiki> is /usr/share/nginx/html/index.html}} | {{info | The default served page at {{boxx|<nowiki>http://127.0.0.1</nowiki>}} is /usr/share/nginx/html/index.html}} |
Dernière version du 30 octobre 2023 à 15:35
Configuration
user
Le user et le group par défaut est http. |
worker_processes
Idéalement égal au nombre de processeurs.
nproc grep -c ^processor /proc/cpuinfo |
pid
Définit dans quel fichier le Process Id du serveur Nginx est stocké.
Par défaut /run/nginx.pid
worker_connections
Définit le nombre maximum de connexions simultanées qu'un worker process peut ouvrir.
sendfile, tcp_nopush et tcp_nodelay
- tcp_nodelay force l’envoi immédiat des données contenues dans la socket, quelle que soit la taille du paquet.
- tcp_nopush fait exactement le contraire de tcp_nodelay, il force à n’envoyer que des paquets ayant atteint la MSS, qui est égale au MTU moins les 40 octets d’en-tête.
- sendfile force l’utilisation de l’appel système sendfile(2) pour tout ce qui concerne l’envoi de fichiers. Très performant pour les fichiers statiques stockés localement.
keepalive_timeout
Temps en secondes pendant lequel la connexion restera ouverte.
gzip
Zipper les réponses.
/etc/nginx/nginx.conf |
gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types application/javascript image/svg+xml text/css; |
Configuration du bloc server
listen
Définit l'adresse et le port qui seront écoutés.
/etc/nginx/nginx.conf |
# default_server définit le serveur par défaut si aucune correspondance n'est trouvée listen 80 default_server; |
server_name
Détermine quel bloc server sera utilisé en fonction de la requête.
Ordre de priorité:
- exact name
- longest wildcard name starting with an asterisk, e.g. “*.example.org”
- longest wildcard name ending with an asterisk, e.g. “mail.*”
- first matching regular expression (in order of appearance in a configuration file)
Si aucun server_name ne correspond c'est le serveur possédant l'instruction listen 80 default_server qui sera utilisé, sinon le premier serveur. |
root
Définit le chemin le dossier racine pour les requêtes.
Un root différent peut être définit pour chaque location.
Si le chemin contient des espaces l'encadrer avec des guillemets simple. |
index
Définit les fichiers à utiliser lorsque la requête se termine par /.
Encodage de caractères
Définit l'encodage de caractères par défaut pour les types text/plain or text/html.
Cette définition écrase celle spécifiée dans la balise meta.
/etc/nginx/nginx.conf |
charset utf-8; |
error_log
/etc/nginx/nginx.conf |
# par défaut error_log stderr error; # écrit dans le journal à partir du niveau error server { # définir un fichier particulier pour le log error_log /var/log/nginx/mon_site_error.log; |
Il n'est pas possible de modifier le format du log d'erreurs: YYYY/MM/DD HH:MM:SS [LEVEL] PID#TID: *CID MESSAGE |
access_log
/etc/nginx/nginx.conf |
# par défaut access_log /var/log/nginx/access.log combined; # écrit dans le fichier access.log au format combined # format combined log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; server { # définir un fichier particulier pour le log access_log /var/log/nginx/mon_site_access.log; # désactiver le log access access_log off; # ne pas logguer les erreurs de fichiers non trouvés log_not_found off; # compresser le log access_log /path/to/log.gz combined gzip=9 flush=5m; # By default, the buffer size is equal to 64K bytes, and the compression level is set to 1. # The compression level can be set between 1 (fastest, less compression) and 9 (slowest, best compression). |
« nginx -V » pour obtenir les valeurs par défaut des variables définies lors de la compilation.
|
Les conditions ne fonctionnent qu'à partir de la version 1.7: invalid parameter "if=loggable" |
log_format
/etc/nginx/nginx.conf |
# formats prédéfinits http { log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; # combined + $http_x_forwarded_for log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # pour un log multi serveur car il contient $server_name log_format global '[$time_local] $status $server_name ' '$remote_addr "$request" - ' '"$http_referer" - "$http_user_agent"'; |
$time_local | heure à laquelle la requête a été trairée |
$status | code de retour: 200 Ok, 403 Forbidden, 404 Not Found |
$remote_addr | adresse ip du client |
$http_referer | url de la page précédente |
$request | la requête |
$http_user_agent | information sur le client: logiciel, OS |
$request_time | temps de traitement de la requête |
$server_name | le nom du serveur correspondant à la requête |
$http_x_forwarded_for | vraie adresse ip du client provenant d'un proxy HTTP ou d'un répartiteur de charge |
$cookie_COOKIE | contenu du cookie COOKIE |
$http_HEADER | contenu du header HEADER (ex: http_user_agent) |
map
/etc/nginx/nginx.conf |
# les ip locales 192.168.0.x ne seront pas loguées # map doit être définit dans http map $remote_addr $loggable { ~^192\.168\.0\. 0; 0; # 0 → ne pas logguer default 1; } access_log /path/to/access.log combined if=$loggable; # utiliser plusieurs paramètres en les concaténant en un seul string # les tests de correspondance se font donc sur ce string concaténé map $remote_addr$request $loggable { ~^192\.168\.0\. 0; # ne pas logguer les ip 192.168.0.x "~*GET /wiki/" 1; # logguer les requêtes qui contiennent GET /wiki/ default 0; # ne pas logguer le reste } |
Buffer limitations
/etc/nginx/nginx.conf |
# default is 8k or 16k client_body_buffer_size 1K; client_header_buffer_size 1k; # If size is greater the given one, then the client gets the error "Request Entity Too Large" (413). # Increase this when you are getting file uploads via the POST method. client_max_body_size 1k; # Default: large_client_header_buffers 4 8k; # Context: http, server large_client_header_buffers 8 32k; # Default: proxy_buffers 8 4k|8k; # Context: http, server, location proxy_buffers 8 32k; # Default: proxy_buffer_size 4k|8k; # Context: http, server, location proxy_buffer_size 64k; |
Timeout
/etc/nginx/nginx.conf |
# The default is 60 client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; |
location
Permet de modifier la configuration en fonction de la requête.
/etc/nginx/nginx.conf |
server { # correspond seulement à la requête / location = / { } # emplacement par défaut # si aucun autre emplacement ne correspond, c'est celui-ci qui sera utilisé location / { } # correspond aux requêtes commençant par /mon_dossier/ # mais la recherche de correspondances continue location /mon_dossier/ { } # correspond aux requêtes commençant par /mon_dossier2/ # la recherche de correspondances s'arrête ici: ^~ location ^~ /mon_dossier2/ { } # expressions rationnelles: ~ sensible à la casse ~* insensible à la casse location ~* \.(gif|jpg|jpeg)$ { } location ~ /(dossier1|dossier2)/ { } # les locations peuvent s'imbriquer location /dossier/ { location ~* \.png$ { } } |
Ordre de vérification des correspondances:
- Directives avec le préfixe « = ». S'il y a correspondance la recherche s'arrête là.
- Directives avec une chaîne de caractères. La recherche continue sauf si le prefix « ^~ » a été utilisé.
En cas de correspondances multiples c'est la directive la plus longue qui l'emporte. - Directives avec une expression rationnelle dans l'ordre dans lesquelles elles ont été définies.
S'il n'y a pas de correspondance, c'est la correspondance avec la directive n°2 la plus longue qui est utilisée.
^~ ne fonctionne pas avec les regex. |
Les arguments (arg=value) ne sont pas pris en compte pour la correspondance. |
Configuration du bloc location
allow / deny
/etc/nginx/nginx.conf |
# interdit l'accès au site à tous sauf à 192.168.0.0/24 allow 192.168.0.0/24; deny all; # interdit l'accès aux pages dont l'url contient Spécial à tous sauf à 192.168.0.1 location ~ Spécial { allow 192.168.0.1; deny all; } # utilisation d'un fichier de configuration contenant toutes les ip à exclure include /etc/nginx/blacklist; |
/etc/nginx/blacklist |
deny x.x.x.x; deny y.y.y.y; |
Les autorisations sont analysées dans l'ordre, la première correspondance est appliquée. Il faut donc les écrire des plus spécifiques aux plus globales. |
En cas d'interdiction le serveur envoie le signal d'erreur 403 Forbidden |
internal
Restreint l'accès aux requêtes internes.
Dans le cas d'une requête externe, l'erreur 404 est renvoyée. |
try_files
Test si $uri existe, si ce n'est pas le cas, test si uri/fichier1.html existe puis $uri/fichier2.html
Si un des fichiers existe, il est utilisé. Si aucun fichier de la liste n'existe, une redirection interne est faite vers le dernier.
/etc/nginx/nginx.conf |
try_files $uri $uri/fichier1.html $uri/fichier2.html; # Si aucun fichier de la liste n'existe, redirection vers la location @other try_files $uri $uri/fichier1.html $uri/fichier2.html @other; location @other { } # génère l'erreur 404 si aucun fichier de la liste n'existe try_files $uri $uri/fichier1.html $uri/fichier2.html =404; |
rewrite
/etc/nginx/nginx.conf |
# réécrit les urls: /index.php?title=Sujet → /index.php/Sujet location = /index.php { rewrite .* /index.php/$arg_title? permanent; } # réécrit les urls: /index.php/Sujet → /index.php?title=Sujet location / { try_files $uri $uri/ @rewrite; } location @rewrite { rewrite ^/(.*)$ /index.php?title=$1&$args; } |
Les arguments sont ajoutés à la fin de la nouvelle. Pour éviter cela, ajouter un '?' à la fin de la nouvelle url. |
alias
/etc/nginx/nginx.conf |
root /srv/http/mon_site; location ^~ /autre_dossier { alias /un/autre/dossier; # la requête /autre_dossier/fichier.html reverra le fichier /un/autre/dossier/fichier.html # alors que la requête /dossier/fichier.html reverra le fichier /srv/http/mon_site/fichier.html } # Si la location correspond à la fin de l'alias, il est préférable d'utiliser la directive root location ^~ /dossier { alias /data/dossier; } location ^~ /dossier { root /data; } |
error_page
Permet de définir les pages à afficher en cas d'erreurs.
/etc/nginx/nginx.conf |
# redirige vers la page 404.html en cas d'erreur 404 error_page 404 /404.html; # redirige vers la page 404.html en cas d'erreur 404 et retourne le code 200 au lieu du code 404 error_page 404 =200 /404.html; # pourl'erreur 403 (forbidden), il faut en plus authoriser l'accès à la page d'erreur error_page 403 /error403.html; location = /error403.html { # internal: page error403.html accessible seulement via ce mécanisme et pas directement internal; allow all; } |
Index Of
/etc/nginx/nginx.conf |
autoindex on; # par défaut à off |
expires
/etc/nginx/nginx.conf |
# forcer les scripts, css et images à rester en cache location ~* \.(js|css|swf|png|jpg|jpeg|gif|ico|bmp|svg)$ { expires max; access_log off; } |
- max → sets the Expires header to 31 December 2037 23:59:59 GMT
- 10d → en cache pendant 10 jours (m: minutes, h: hours, d: days, w: weeks, M: months, y: years)
Virtual Hosts
Les hôtes virtuels de NGINX sont appelés blocs serveur.
/etc/nginx/nginx.conf |
http { # hôte virtuel site1 server { server_name site1; } # hôte virtuel site2 ou alias2 ou *.domain.com ou une expression rationnelle server { server_name site2 alias2 *.domain.com ~^www\d+\.example\.com$; } # hôte virtuel par défaut # si aucune autre correspondance n'a été faite, c'est cet hôte qui est utilisé server { listen 80 default_server; index index.html; root /usr/share/nginx/html; } |
Rewrite rules
/etc/nginx/nginx.conf |
# redirection d'un ancien domaine vers un nouveau server { server_name www.old-name.com old-name.com; return 301 $scheme://www.new-name.com$request_uri; } # Enabling pretty permalinks location / { try_files $uri $uri/ /index.php?$args; } # Dropping requests for unsupported file extensions location ~ .(aspx|php|jsp|cgi)$ { deny all; } # Custom rerouting rewrite ^/listings/(.*)$ /listing.html?listing=$1 last; |
if
/etc/nginx/nginx.conf |
location / { if ($my_var) { # vrai si $my_var non-vide et différente de '0' return 200; } if (!-e $my_var) { # not return 200; } |
Variables
variable | valeur | commentaire |
---|---|---|
$1 .. $9 | correspond aux groupes 1 à 9 dans le cadre d'une expression rationnelle | |
$document_root | /srv/http/monsite | définit par la directive root /usr/share/webapps/mysite; |
$fastcgi_script_name | /page.php | nom du fichier de script |
$fastcgi_path_info | /article/123 | pour la requête /page.php/article/123 |
$uri | /page.php/article/123 | pour la requête /page.php/article/123 |
$arg_name | text | pour la requête /page.php?name=text |
Limitation d'accès
Authentification simple
/etc/nginx/nginx.conf |
auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; |
/etc/nginx/.htpasswd |
user_name:mot_de_passe_hashé |
# génération de la ligne a ajouter au fichier de mots de passe (/etc/nginx/.htpasswd) printf "USER:$(openssl passwd -apr1)\n" >> /etc/nginx/.htpasswd # -apr1 → MD5-based password algorithm, Apache variant |
htpasswd
htpasswd fait partie du paquet apache |
# création du fichier .htpasswd et ajout de l'utilisateur user_name htpasswd -c /etc/nginx/.htpasswd user_name # ajout d'autres utilisateur une fois le fichier créé htpasswd /etc/nginx/.htpasswd user_name # afficher l'utilisateur et le mot de passe haché dans la console htpasswd -n user_name |
Sécurité
Par défaut, c'est l’algorithme MD5 qui est utilisé pour encrypter les mots de passe. Il utilise un grain de sel (salt). |
Connexions simultanées
/etc/nginx/nginx.conf |
# définition de la zone mémoire partagée, utilisée pour partager le compteur associé à la clé de la zone mémoire # limit_conn_zone CLÉ zone=NOM:TAILLE; limit_conn_zone $binary_remote_addr zone=addr:10m; # définit la limitation du nombre de connexions simultanées limit_conn addr 1; |
$binary_remote_addr → adresse IP du client. Permet de définir une limitation du nombres de connexions simultanées par client (adresse IP). $server_name → nom du serveur. Permet de définir une limitation du nombres de connexions simultanées par serveur. |
Nombre de requêtes par seconde
Permet de limiter le nombre de requêtes par seconde provenant d'une même ip, et ainsi de se protéger contre le flood / DoS.
/etc/nginx/nginx.conf |
# créé une zone de 10 megabyte appelée « flood » # elle enregistrera le nombre de requêtes par clé, # ici $binary_remote_addr (adresse ip du client au format binaire pour économiser de l'espace mémoire) # 1r/s → 1 requête par secondes ; 30r/m → 30 requêtes par minutes limit_req_zone $binary_remote_addr zone=flood:10m rate=1r/s; # applique la limitation de requête # si le nombre de requêtes dépasse le ratio # les requêtes suivantes sont mise en attente dans la limite de burst (par défaut à 0) # au delà de burst les requêtes sont terminées avec le code d'erreur 503 (Service Temporarily Unavailable) limit_req zone=flood burst=5; # l'option nodelay permet de traiter les requêtes burst sans délai (plus de respect du ratio) # rate=5r/s équivalent à rate=1r/s burst=4 nodelay # définit le status à envoyer au client lorsqu'on termine la requête (503 par défaut) limit_req_status 444; # 444 code spécifique à nginx fermant la connexion et n'envoyant pas de réponse au client |
Exemple: limit_req_zone $binary_remote_addr zone=flood:10m rate=1r/s; limit_req zone=flood burst=2 nodelay; Envoie de 3 requêtes par secondes pendant 3 secondes Req.# | Time (sec) | Response 1 0 200 OK rate=1r/s 2 0 200 OK burst +1=1 3 0 200 OK burst +1=2 1 burst -1=1 4 1 200 OK rate=1r/s 5 1 200 OK burst +1=2 6 1 503 burst=2 requête rejetée 2 burst -1=1 7 2 200 OK rate=1r/s 8 2 200 OK burst +1=2 9 2 503 burst=2 requête rejetée
Sécurité
- Qualys SSL test
- Test des headers
- Hardening your HTTP response headers
- Guide to Deploying Diffie-Hellman for TLS
/etc/nginx/nginx.conf |
# hsts, 31536000 s = 1 an add_header Strict-Transport-Security "max-age=31536000"; # upgrade-insecure-requests → ensures that any HTTP assets are loaded using HTTPS add_header Content-Security-Policy "upgrade-insecure-requests"; # hide the server version server_tokens off; # By preventing a browser from framing your site you can defend against attacks like clickjacking add_header X-Frame-Options "SAMEORIGIN" always; # blocks the response if it detects a cross-site script. add_header X-Xss-Protection "1; mode=block" always; # support de Forward Secrecy (défaut: HIGH:!aNULL:!MD5) ssl_ciphers "HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers On; # Diffie-Hellman pour TLS ssl_dhparam /path/dhparams.pem; # fichier à générer avec: openssl dhparam -out dhparams.pem 2048 # performances ssl_stapling on; ssl_session_cache shared:SSL:10m; |
/etc/uwsgi/mysite.ini |
; masquer le header X-Powered-By PHP/x.x.x php-set = expose_php=Off |
SSL
Création d'un certificat
# choisir le dossier qui contiendra le certificat cd /etc/ssl/private # créer la clé privée # nombre de bits : 2048 ou 4096 openssl genrsa -out server.key 4096 chmod 400 server.key # créer le Certificate Signing Request (CSR) openssl req -new -sha512 -key server.key -out server.csr # Common Name doit correspondre au nom d'hôte (serveur.domaine.fr ou *.domaine.fr) # The "challenge password" is basically a shared-secret nonce between you and the SSL issuer, embedded in the CSR, # which the issuer may use to authenticate you should that ever be needed. # par défaut sha1 est utilisé # signer le certificat openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt |
Configuration
/etc/nginx/nginx.conf |
# redirection vers https server { server_name site.domaine.fr; listen 80; return 301 https://$server_name$request_uri; } server { server_name site.domaine.fr; listen 443 ssl; ssl_certificate /etc/ssl/private/server.crt; ssl_certificate_key /etc/ssl/private/server.key; } |
Découper le fichier de configuration
/etc/nginx/nginx.conf |
include /etc/nginx/servers/*.conf; |
/etc/nginx/servers/serveur1.conf |
server { listen 80; server_name serveur1.mon-domaine.fr; root /srv/http/serveur1; index index.php; include /etc/nginx/php_files.conf; } |
/etc/nginx/php_files.conf |
location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi.conf; } |
status
Permet de connaître
- le nombre de connexions actuellement ouvertes
- le nombre de connexions acceptés
- le nombre de requêtes gérées
- le nombre de requêtes par seconde = handles requests / handled connections
/etc/nginx/nginx.conf |
location /status { stub_status on; access_log off; allow x.x.x.x; deny all; } |
Bloquer certains user-agents
/etc/nginx/nginx.conf |
# bloque les user-agents wget et curl if ($http_user_agent ~ (Wget|curl) ) { return 403; } |
|
if / else
/etc/nginx/nginx.conf |
if ($request_method = POST ) { return 405; } # astuce pour les conditions multiples set $test ""; if ($request_method = POST) { set $test P; } if ($http_cookie_cccc) { set $test "${test}C"; } if ($test = PC) { # rewrite rule goes here. } # redirection vers une autre location location / { error_page 418 = @other; recursive_error_pages on; if ($something) { return 418; } } location @other { } |
uwsgi
uwsgi_modifier1
modifier1 | packet type |
---|---|
9 | Standard Running CGI scripts on uWSGI request followed by the HTTP request body |
14 | Standard Running PHP scripts in uWSGI request followed by the HTTP request body |
30 | Standard WSGI request followed by the HTTP request body. The PATH_INFO is automatically modified, removing the SCRIPT_NAME from it |
uwsgi_read_timeout
location ~ \.php5?$ { # par défaut à 60s uwsgi_read_timeout 90; |
PHP
php-fpm
# installation sudo pacman -S php-fpm # démarrage du service sudo systemctl start php-fpm # démarrer php-fpm au démarrage du système sudo systemctl enable php-fpm |
/etc/nginx/nginx.conf |
server { listen 80; server_name myserver; root /srv/http/myserverfolder; index index.html index.htm index.php; location ~ \.php$ { # test si le fichier php existe, sinon affiche l'erreur 404 au lieu du message "File not found." try_files $uri =404; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; include /etc/nginx/fastcgi.conf; # augmente le temps d'attente d'une réponse, par défaut à 60s fastcgi_read_timeout 300; } } |
502 Bad Gateway | php-fpm n'est pas démarré |
504 Gateway Time-out |
|
log
Ne semble pas marcher. |
/etc/php/php-fpm.d/www.conf |
php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on |
# créer le fichier de log avec les bons droits touch /var/log/fpm-php.www.log chmod 777 /var/log/fpm-php.www.log |
Empêcher les fichiers non-PHP d'être traiter par PHP
nginx gère l'url http://mon.site/image.gif/somefilename.php de cette façon:
- comme l'url se termine par php, elle est transmise au gestionnaire de FastCGI PHP
- PHP examine le path, trouve le fichier image.gif, et stocke /somefilename.php dans $_SERVER['PATH_INFO'], puis execute le contenu du fichier GIF comme du PHP.
Comme les formats d'images peuvent contenir un contenu arbitraire. Il est possible qu'une image contiennent du code PHP malveillant.
Solutions:
- cgi.fix_pathinfo=1 dans le fichier /etc/php/php.ini. Pose problème avec Wordpress.
- try_files $uri =404; dans le bloc location du fichier /etc/nginx/nginx.conf. Fonctionne si nginx et le gestionnaire de script FastCGI PHP sont sur le même serveur.
- Ajoutez un bloc location qui détecte les mauvaises URL.
- Exclure explicitement les urls d'upload du block location.
- Ne pas stocker sur le même serveur les fichiers uploadés et le gestionnaire de script FastCGI PHP.
Cache PHP
Modifiez la configuration PHP
/etc/nginx/nginx.conf |
set $session_root /var/www/dev/$1/sessions; fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/other/folder\nsession.save_path=$session_root"; |
L'utilisation de PHP_ADMIN_VALUE pose problème: une fois que le serveur contenant la directive est atteint la modification de la configuration PHP se propage à tous les serveur. |
ASP.NET
.Net Core
/etc/nginx/sites-available/webapp.conf |
server { listen 80; server_name webapp.local; location ^~ /api/ { rewrite ^/api(/.*)$ $1 break; proxy_pass http://localhost:5000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { proxy_pass http://localhost:5001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } |
HTTP Status Codes spécifiques à Nginx
Comparaison des modules Nginx / Apache / Lighttp
Modules
echo
/etc/nginx/nginx.conf |
load_module /usr/lib/nginx/modules/ngx_http_echo_module.so; http { server { location / { default_type text/plain; echo "hello, world!"; echo_sleep 1; # wait 1 second |
njs
/etc/nginx/nginx.conf |
load_module /usr/lib/nginx/modules/ngx_http_js_module.so; http { js_include /etc/nginx/scripts/my_script.js; server { location / { default_type text/plain; js_content my_function; |
/etc/nginx/scripts/my_script.js |
function my_function(r) { r.return(200, "Hello world!"); // redirection r.return(302, 'http://domain.net'); } function read_file() { var fs = require('fs'); try { // throw an exception if the file doesn't exist var file_content = fs.readFileSync('/tmp/my_file.txt', 'utf8'); if (file_content === '0\n') { // ... } } catch (e) { } } |
Erreurs
could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 6
/etc/nginx/nginx.conf |
# just below keepalive_timeout # increase from default 1024 to 4096 types_hash_max_size 4096; |
could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32
Nom de serveur trop long par rapport aux règlages → augmenter la taille autorisée des noms de serveur.
/etc/nginx/nginx.conf |
http { server_names_hash_bucket_size 64; |
client intended to send too large body
Augmenter la valeur de client_max_body_size
/etc/nginx/nginx.conf |
http, server, location { client_max_body_size 20m; # default 1m |
ownCloud
Mediawiki
Pretty URL avec php-fpm
/etc/nginx/nginx.conf |
# Explicit access to the root website, redirect to main page location = / { return 301 /wiki/Accueil; } location ^~ /cache/ { deny all; } # Allow access to those folders location ^~ /images/ { } location ^~ /sitemap/ { } location = /sitemap.xml { } # Handling for the article path (pretty URLs) location ^~ /wiki/ { rewrite ^/wiki/(?<pagename>.*)$ /index.php; } # Every other entry point will be disallowed location / { return 404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php-fpm.sock; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { try_files $uri =404; expires max; log_not_found off; } |
LocalSettings.php |
$wgArticlePath = "/wiki/$1"; |
Pretty URL avec uwsgi
/etc/nginx/nginx.conf |
# only in production error_page 403 404 = /index.php; location ~ \.php5?$ { include uwsgi_params; uwsgi_modifier1 14; uwsgi_pass unix:/run/uwsgi/mediawiki.sock; } location ^~ /wiki/ { rewrite ^/wiki/(.*)$ /index.php?title=$1; } # Restrictions based on the .htaccess files location ^~ /cache/ { deny all; } # location ^~ /images/ {} location ^~ /images/deleted/ { deny all; } location ^~ /images/temp/ { deny all; } location ^~ /includes/ { deny all; } location ^~ /languages/ { deny all; } location ^~ /maintenance/ { deny all; } location ^~ /maintenance/archives/ { deny all; } location ^~ /serialized/ { deny all; } location ^~ /tests/ { deny all; } # location ^~ /tests/qunit/ { allow all; } location ^~ /extensions/MobileFrontend/dev-scripts/ { deny all; } # location ^~ /extensions/MobileFrontend/tests/ {} # Restrictions d'accès supplémentaires location ^~ /mw-config/ { deny all; } location ^~ /extensions/ { deny all; } location ^~ /resources/ { deny all; } location ^~ /resources/assets/ { allow all; } location ^~ /docs/ { internal; } location ^~ /vendor/ { internal; } # Hide any .htaccess files location ~ /.ht { deny all; } location ~* \.(js|css|png|jpg|jpeg|svg|gif|ico)$ { try_files $uri /index.php; expires max; } |
LocalSettings.php |
$wgArticlePath = "/wiki/$1"; |
URL classique
/etc/nginx/nginx.conf |
server { listen 80; server_name myserver; root /srv/http/myserverfolder; index index.php; # Restrictions based on the .htaccess files location ~ /cache|images/deleted|languages|maintenance|maintenance/archives|serialized|tests/ { deny all; } # est-ce vraiment utile ? # location ~ /docs|extensions|includes|mw-config|resources|scripts/ { # internal; # } # ne semble pas nécessaire # réécrit les urls: /index.php/Sujet → /index.php?title=Sujet # location / { # try_files $uri $uri/ @rewrite; # } # location @rewrite { # rewrite ^/(.*)$ /index.php?title=$1&$args; # } # est-ce vraiment utile ? # Keep images and CSS around in browser cache for as long as possible, to cut down on server load # location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { # try_files $uri /index.php; # expires max; # log_not_found off; # } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi.conf; } |
Le fichier robots.txt devra correspondre aux urls de type /index.php?title=MonTitre |
Wordpress
/etc/nginx/nginx.conf |
server { location / { try_files $uri $uri/ /index.php?$args; } # Add trailing slash to */wp-admin requests. rewrite /wp-admin$ $scheme://$host$uri/ permanent; # Directives to send expires headers and turn off 404 error logging. location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom| jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } # Uncomment one of the lines below for the appropriate caching plugin (if used). #include global/wordpress-wp-super-cache.conf; #include global/wordpress-w3-total-cache.conf; # Pass all .php files onto a php-fpm/php-fcgi server. location ~ [^/]\.php(/|$) { include uwsgi_params; uwsgi_modifier1 14; uwsgi_pass unix:/run/uwsgi/wordpress.sock; } } |
Wordpress a besoin d'autoriser l'ip du serveur pour ses taches cron. |
Installation
sudo pacman -S nginx # démarrer le serveur sudo systemctl start nginx |
The default served page at http://127.0.0.1 is /usr/share/nginx/html/index.html |