Nginx

De Banane Atomic
Aller à la navigationAller à la recherche

Configuration

user

Le user et le group par défaut est http.

worker_processes

Idéalement égal au nombre de processeurs.

Bash.svg
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é:

  1. exact name
  2. longest wildcard name starting with an asterisk, e.g. “*.example.org”
  3. longest wildcard name ending with an asterisk, e.g. “mail.*”
  4. 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.

How nginx processes a request

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
PID: logging process id, TID: thread id, CID: connection id

Mais on peut choisir le niveau de log: debug, info, notice, warn, error, crit, alert, emerg

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.
  • --http-log-path=/var/log/nginx/access.log
  • --error-log-path=stderr
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:

  1. Directives avec le préfixe « = ». S'il y a correspondance la recherche s'arrête là.
  2. 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.
  3. 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é
Bash.svg
# 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
Bash.svg
# 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).
L’algorithme SHA (-s) n'utilise pas de grain de sel (salt).

L'algorithme bcrypt (-B) peut être encrypté avec l'option -C. Le désencryptage prend du temps de calcul.

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é

/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

Bash.svg
# 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;
}
  • « ~ » sensible à la casse
  • « ~* » non sensible à la casse

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 { }

If Is Evil

Installation

Bash.svg
sudo pacman -S nginx

# démarrage du service
sudo systemctl start nginx
 
# démarrer php-fpm au démarrage du système
sudo systemctl enable nginx
Test si le serveur est fonctionnel: 127.0.0.1 affiche la page par défaut /usr/share/nginx/html/index.html

uwsgi

uwsgi et nginx

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

Bash.svg
location ~ \.php5?$ {
    # par défaut à 60s
    uwsgi_read_timeout 90;

PHP

php-fpm

Bash.svg
# 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;
    }
}
Erreurs
502 Bad Gateway php-fpm n'est pas démarré
504 Gateway Time-out
  • un service uwsgi pointe vers le même dossier
  • PhpStorm debug le service

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
Bash.svg
# 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:

  1. comme l'url se termine par php, elle est transmise au gestionnaire de FastCGI PHP
  2. 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/nginx.conf
server {
    listen        80;
    server_name   webappcore.local;
    location / {
        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;
    }
}

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 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 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";

Pretty URL avec php-fpm

/etc/nginx/nginx.conf
location / {
    # Do this inside of a location so it can be negated
    location ~ \.php$ {
        try_files       $uri =404;
        fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
        include         /etc/nginx/fastcgi.conf;
    }
}

# Handling for the article path
location /wiki {
    fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
    include         /etc/nginx/fastcgi.conf;
    # article path should always be passed to index.php
    fastcgi_param SCRIPT_FILENAME	$document_root/index.php;
}
LocalSettings.php
$wgArticlePath = "/wiki/$1";
$wgUsePathInfo = true;

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

Bash.svg
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