Nginx : Installation et configuration d'une alternative d'Apache

From Deimos.fr / Bloc Notes Informatique
Jump to: navigation, search


Nginx Logo

Software version 1.2.1
Operating System Debian 7
Website Nginx Website
Last Update 29/08/2014
Others

1 Introduction

Nginx [engine x] est un logiciel de serveur Web (ou HTTP) écrit par Igor Sysoev, dont le développement a débuté en 2002 pour les besoins d'un site russe à très fort trafic.

J'ai cherché pendant quelques temps une alternative à Apache car un peu trop gourmant. En découvrant lighttpd je m’étais rendu compte que d’autre serveur existait derrière Apache et IIS. Il était temps de creuser la question.

2 Installation

Pour l'installation, on est sur Debian donc c'est toujours aussi simple :

Command aptitude
aptitude install nginx

Puis on va le démarrer :

Command aptitude
/etc/init.d/nginx start

3 Configuration

3.1 php-fpm

Ceci est la solution la plus optimale pour les machines multi threadées (plusieurs coeurs donc).

3.1.1 Installation

Command
aptitude install php5-fpm

3.1.2 Configuration

Pour la configuration nous allons créer une configuration basique (supprimez ci possible la configuration de base) (nous la changerons plus tard, mais ça vous donne une idée d'une configuration minimale qui fonctionne) :

Configuration File /etc/nginx/sites-available/www.deimos.fr
server {
    listen       80;
    server_name  www.deimos.fr;
    root   /var/www/deimos.fr;
    index  index.html index.htm index.php;
 
    location ~ \.php$ {
        fastcgi_index  index.php;
        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        # fastcgi_pass    127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Nous allons changer le type d'écoute de TCP en socks :

Configuration File /etc/php5/fpm/pool.d/www.conf
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses on a
;                            specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php5-fpm.sock

Appliquez ensuite la configuration :

Command
ln -s /etc/nginx/sites-available/www.deimos.fr /etc/nginx/sites-enabled/www.deimos.fr

Ensuite redémarrez php-fpm et nginx !

3.1.2.1 PHP-FPM Status

Si vous avez besoin de monitorer PHP-FPM, vous aurez certainement besoin d'avoir les informations sur votre PHP-FPM. Pour cela, il faut éditer le fichier suivant et décommenter ces lignes :

Configuration File /etc/php5/fpm/pool.d/www.conf
[...]
pm.status_path = /fpm-status
[...]

Editez ensuite votre configuration d'Nginx et placez y ceci :

Configuration File /etc/nginx/sites-enabled/default
[...]
    # PHP-FPM Status
    location /fpm-status {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        # User access
        auth_basic "Please logon"; 
        auth_basic_user_file /etc/nginx/access/htaccess;
    }
[...]

Afin d'éviter que n'importe qui y est accès, j'y ai placé un htaccess, mais à vous de voir la sécurité que vous préférez.

Redémarrez PHP-FPM et Nginx, puis accédez à votre serveur comme ceci :

Ce qui vous donnera quelque chose comme ceci dans la version non détaillée :

pool:                 www
process manager:      dynamic
start time:           18/Dec/2013:19:00:41 +0100
start since:          52972
accepted conn:        5268
listen queue:         0
max listen queue:     0
listen queue len:     0
idle processes:       3
active processes:     1
total processes:      4
max active processes: 4
max children reached: 0

3.2 PHP Fast CGI

Cette méthode est fonctionnelle mais pas l'optimale. Optez pour php-fpm si vous pouvez.

3.2.1 Installation

Pour qu'Nginx supporte le php, nous allons installer ceci :

Command aptitude
aptitude install php5-cgi

Puis nous allons créer un service init pour ce fast cgi :

Configuration File /etc/init.d/php-fcgi
#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-fcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop php-cgi in external FASTCGI mode
# Description:       Start and stop php-cgi in external FASTCGI mode
### END INIT INFO
 
# Author: Kurt Zankl <kz@xon.uni.cc>
# Modified by Deimos <deimos@deimos.fr>
 
# Do NOT "set -e"
 
BIND=127.0.0.1:9000
USER=www-data
PHP_FCGI_CHILDREN=15
PHP_FCGI_MAX_REQUESTS=1000
 
PATH=/usr/bin:/sbin:/usr/sbin:/bin
PHP_CGI=/usr/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS="- USER=$USER PATH=$PATH PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND"
RETVAL=0
 
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
 
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
 
do_start()
{
        echo -n "Starting PHP FastCGI : "
        start-stop-daemon --start --quiet --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS
        RETVAL=$?
        echo "$PHP_CGI_NAME."
}
 
do_stop()
{
        echo -n "Stopping PHP FastCGI : "
        killall -q -w -u $USER $PHP_CGI
        RETVAL="$?"
        echo "$PHP_CGI_NAME."
}
 
case "$1" in
   start)
      do_start
   ;;
   stop)
      do_stop
   ;;
   restart)
      do_stop
      do_start
   ;;
   *)
      echo "Usage: php-fcgi {start|stop|restart}"
      exit 3
    ;;
esac
exit $RETVAL

Puis nous allons mettre à jours dans les RC par défaut et démarrer le tout :

Command
cd /etc/init.d
chmod 755 /etc/init.d/php-fcgi
update-rc.d php-fcgi defaults
/etc/init.d/php-fcgi start

3.2.2 Configuration

Pour configurer le support du PHP, éditez le fichier de base d'Nginx et adaptez :

Configuration File /etc/nginx/sites-available/default
server {
       listen   80;
       server_name  localhost;

       access_log  /var/log/nginx/localhost.access.log;

       location / {
               root   /var/www/nginx-default;
               index  index.html index.htm index.php;
       }

       location /doc {
               root   /usr/share;
               autoindex on;
               allow 127.0.0.1;
               deny all;
       }

       location /images {
               root   /usr/share;
               autoindex on;
       }

       #error_page  404  /404.html;

       # redirect server error pages to the static page /50x.html
       #
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
               root   /var/www/nginx-default;
       }

       # proxy the PHP scripts to Apache listening on 127.0.0.1:80
       #
       #location ~ \.php$ {
               #proxy_pass   http://127.0.0.1;
       #}

       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
       #
       location ~ \.php$ {
               root /var/www/nginx-default;
               include /etc/nginx/fastcgi_params;
               fastcgi_pass   127.0.0.1:9000;
               fastcgi_index  index.php;
               fastcgi_param  SCRIPT_FILENAME  /var/www/nginx-default/$fastcgi_script_name;
       }

       # deny access to .htaccess files, if Apache's document root
       # concurs with nginx's one
       #
       #location ~ /\.ht {
               #deny  all;
       #}
}

3.3 nginx.conf

Voici la configuration du serveur globale. J'ai mis des commentaires sur les lignes importantes :

Configuration File /etc/nginx/nginx.conf
user www-data;
# Number of working processworker_processes 2;worker_rlimit_nofile    2000;pid /var/run/nginx.pid;
 
events {
    # Maximum connection number    worker_connections 2048;    use epoll;
    # multi_accept on;
}
 
http {
	##
	# Basic Settings
	##
 
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
        map_hash_bucket_size 64;
        # Security to hide version	server_tokens off; 
	server_names_hash_bucket_size 64;
	# server_name_in_redirect off;
 
        # Grow this 2 values if you get 502 error message        fastcgi_buffers 256 16k;        fastcgi_buffer_size 32k;        # Nginx cache to boost performances        fastcgi_cache_path /usr/share/nginx/cache levels=1:2            keys_zone=mycache:10m            inactive=1h max_size=256m; 
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
 
	##
	# Logging Settings
	##
 
	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;
 
	##
	# Gzip Settings
	##
 
	gzip on;	gzip_disable "msie6";        gzip_static on;	gzip_vary on;	gzip_proxied any;	gzip_comp_level 6;	gzip_buffers 16 8k;	gzip_http_version 1.1;	gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; 
	##
	# nginx-naxsi config
	##
	# Uncomment it if you installed nginx-naxsi
	##
 
	#include /etc/nginx/naxsi_core.rules;
 
	##
	# nginx-passenger config
	##
	# Uncomment it if you installed nginx-passenger
	##
 
	#passenger_root /usr;
	#passenger_ruby /usr/bin/ruby;
 
	##
	# Virtual Host Configs
	##
 
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

3.4 drop.conf

Ce fichier va nous permettre de ne pas logger des informations non indispensable et empêcher de donner accès à des fichiers pouvant être sensible :

Configuration File /etc/nginx/drop.conf
# Do not log robots.txt if not found
location = /robots.txt  { access_log off; log_not_found off; }
# Do not log favicon.ico if not found
location = /favicon.ico { access_log off; log_not_found off; }  
# Do not give access to hidden files
location ~ /\.          { access_log off; log_not_found off; deny all; }
# Do not give access to vim backuped files
location ~ ~$           { access_log off; log_not_found off; deny all; }

Ensuite dans vos fichiers de configuration, il suffira de rajouter ces 2 lignes :

Configuration File /etc/nginx/sites-enabled/*
server {
[...]
    # Drop config    include drop.conf;}

3.5 Les VirtualHosts

On peut tout comme sur Apache faire des virtualhost. On va créer par exemple le blog deimos.fr :

Configuration File /etc/nginx/site-available/blog
server {
       listen   80;
       server_name  blog.deimos.fr;

       access_log  /var/log/nginx/localhost.access.log;

       location / {
               root   /var/www/nginx-default/blog;
               index  index.html index.htm index.php;
       }

       location /doc {
               root   /usr/share;
               autoindex on;
               allow 127.0.0.1;
               deny all;
       }

       location /images {
               root   /usr/share;
               autoindex on;
       }
}

Ici, sur le port 80, sera accessible blog.deimos.fr.

On va activer cette conf :

Command ln
ln -s /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/blog

Il ne reste plus qu'a reloader le serveur et ça fonctionne :-)

3.6 Les htaccess

Pour faire des restrictions sur certains des sites, voici une des solutions les plus vieilles mais efficace, les htaccess ! Pour les activer, nous allons avoir besoin du binaire htpasswd :

Command aptitude
aptitude install apache2-utils

Nous allons maintenant générer un fichier contenant les logins et mot de passe avec un premier utilisateur :

Command htpasswd
htpasswd -c /etc/nginx/htaccess deimos

On rentre le mot de passe et ça roule. On va le déclarer dans la conf, dans mon virtalhost précédemment créer

Configuration File /etc/nginx/site-available/blog
server {
       listen   80;
       server_name  blog.deimos.fr;

       access_log  /var/log/nginx/localhost.access.log;

       location / {
               root   /var/www/nginx-default/blog;
               index  index.html index.htm index.php;
               auth_basic "Restricted";
               auth_basic_user_file /etc/nginx/htaccess;
       }

       location /doc {
               root   /usr/share;
               autoindex on;
               allow 127.0.0.1;
               deny all;
       }

       location /images {
               root   /usr/share;
               autoindex on;
       }
}

Il ne reste plus qu'a reloader le serveur et ça fonctionne :-)

3.7 Le port par défaut

Pour stipuler le port par défaut, vous pouvez utiliser un include dans vos fichiers de configuration qui feront appel à un fichier comprenant le port. De la sorte il sera très facile de modifier d'un coup le port par défaut :

Configuration File /etc/nginx/listen_port.conf
listen 80;

Et donc dans les fichiers de configuration :

Configuration File /etc/nginx/sites-available/*.conf
server {
    include listen_port.conf;
[...]

3.8 SSL

3.8.1 Installation

Pour l'installation du SSL, par rapport à Apache qui ne permet pas nativement et simplement de faire du SSL sur des VirtalHost, c'est beaucoup plus simple avec Nginx :

Command aptitude
aptitude install openssl

3.8.2 Configuration

Dans un premier temps, on va générer des clefs SSL :

Command
mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl
openssl req -new -x509 -nodes -out server.crt -keyout server.key

Bon là, je l'ai mis dans un dossier ssl avec la conf nginx, mais vu que l'on peut avoir plusieurs certificats, je vous encourage à faire une arborescence :

Configuration File /etc/nginx/sites-available/webmail
 server {
        listen   443 ssl;        server_name  localhost;
 
        ssl_certificate /etc/nginx/ssl/server.crt;        ssl_certificate_key /etc/nginx/ssl/server.key;        # Resumption        ssl_session_cache shared:SSL:10m;        # Timeout        ssl_session_timeout 10m;         # Security options        ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA;        ssl_prefer_server_ciphers on; 
        # HSTS (force users to come in SSL if they've already been once)
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
 
        access_log  /var/log/nginx/localhost.access.log;
 
        location / {
                root   /var/www/nginx-default/webmail;
                index  index.html index.htm index.php;
        }
 
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
                root /var/www/nginx-default;
                include /etc/nginx/fastcgi_params;
                fastcgi_pass   unix:/var/run/php5-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /var/www/nginx-default/$fastcgi_script_name;
        }
 }

On va activer cette conf :

Command ln
ln -s /etc/nginx/sites-available/webmail /etc/nginx/sites-enabled/webmail

Et on redémarre le serveur Nginx pour que ce soit pris en compte.

Vous pouvez tester la sécurité de votre serveur SSL : https://www.ssllabs.com/ssltest/index.html

3.8.2.1 Forcer une connexion en SSL

Il est possible de configurer son virtualhost de façon classique mais de vouloir absolument une redirection vers du SSL. Pour cela, c'est très simple il suffit simplement de rajouter ceci :

Configuration File /etc/nginx/sites-available/www.deimos.fr
server {
    listen      80;
    server_name www.deimos.fr;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

3.9 Le cache FastCGI

Le cache FastCGI est utile pour augmenter la rapidité de votre site web. On va donc mettre quelques Mb pour le cache et le mettre dans un tmpfs histoire d'accélérer encore plus le tout. Dans la configuration principale, nous allons créer ce cache :

Configuration File /etc/nginx/nginx.conf
[...]
http {
    [...]
    fastcgi_cache_path /usr/share/nginx/cache levels=1:2
        keys_zone=mycache:10m
        inactive=1h max_size=256m;
    [...]
}
[...]

Ici je créer un cache appelé "mycache" d'une taille de 256Mb.

Dans vos configurations de VirtualHost, ajoutez ces lignes :

Configuration File /etc/nginx/sites-enabled/www.deimos.fr
[...]
        location ~ \.php$ {
                fastcgi_cache mycache;                fastcgi_cache_key $request_method$host$request_uri;                fastcgi_cache_valid any 1h;                include fastcgi_params;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_intercept_errors on;
        }
[...]

Ensuite nous allons créer un dossier de cache tmpfs (lisez cette doc pour plus d'infos) :

Configuration File /etc/fstab
[...]
tmpfs /usr/share/nginx/cache    tmpfs   defaults,size=256m   0   0
[...]

Puis nous allons créer le dossier de cache, le monter et ensuite redémarrer nginx :

Command
mkdir /usr/share/nginx/cache
mount /usr/share/nginx/cache
/etc/init.d/nginx restart

3.10 Page de maintenance

Voici une manière élégante de créer une page de maintenance :

Configuration File /etc/nginx/sites-enabled/www.deimos.fr
server {
[...]
   location / {
      try_files /maintenance.html $uri $uri/ @maintenance;
   }
 
   location @maintenance {
      return 503;
   }
}

Il ne vous reste plus qu'à insérer une page maintenance.html à la racine de votre site et cette page s'affichera le temps que vous fassiez vos modifications. Sinon vous pouvez toujours utiliser cette méthode :

Configuration File /etc/nginx/sites-enabled/www.deimos.fr
server {
[...]
    location / {
        if (-f $document_root/maintenance.html) {
             return 503;
        }
        [...]
    }
 
    error_page 503 @maintenance;
    location @maintenance {
        rewrite ^(.*)$ /maintenance.html break;
    }
}

3.11 Limiter le flood et les sniffers

Il peut arriver qu'une personne malveillante tente de mettre à genoux votre serveur en faisant beaucoup de requêtes qui saturent généralement les processus PHP et fait monter vos CPU à 100%. Afin d'éviter cela, il est possible de limiter le nombre de requêtes par IP en utilisant le module limit_req[1]. Pour activer ce module, insérez cette ligne dans votre configuration core (globale) d'Nginx:

Configuration File /etc/nginx/nginx.conf
http {
[...]
    # Flood/DoS protection
    limit_req_zone $binary_remote_addr zone=limit:10m rate=5r/s;
    limit_req_log_level notice;
[...]
}

Voici les options utilisées ici:

  • zone=limit: les IP seront stockées dans une zone appelée limit de 10M. Prévoyez assez d'espace sur cette zone pour éviter des erreurs 503 s'il n'y a plus d'espace. Une zone d'1M peut contenir 16 000 entrées de type binary_remote_addr.
  • rate: on autorise 5 requêtes par secondes.
  • log_level: vous pouvez supprimer cette ligne si vous ne souhaitez pas savoir dans les logs si les limites sont atteintes. Ici je souhaites tracer ce genre d'événements.

Ensuite, il faut informer sur quel virtualhost ou location, nous souhaitons appliquer cette mesure de sécurité:

Configuration File /etc/nginx/sites-enabled/
    location ~ \.php$ {
        limit_req zone=limit burst=5 nodelay;        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }

Là encore on retrouve des options:

  • zone: j'utilise la zone limit précédemment déclarée dans la configuration http (core)
  • burst: j'autorise le burst à 5 connexions maximum
  • nodelay: si vous souhaitez que les requêtes soient tout de même servies mêmes si elles sont ralenties, utilisez le paramètre nodelay.

Il ne reste plus qu'à redémarrer nginx.

4 Configuration d'applications

Par défaut, j'utilise www.deimos.fr pour faire des redirections vers d'autres VirtualHost :

Configuration File /etc/nginx/sites-available/www.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    server_name www.deimos.fr;
 
    access_log /var/log/nginx/www.deimos.fr_access.log;
    error_log /var/log/nginx/www.deimos.fr_error.log;
 
    # Blog redirect
    rewrite ^/$ $scheme://blog.deimos.fr permanent;
    rewrite ^/blog(/.*)?$ $scheme://blog.deimos.fr$1 permanent;
 
    # Blocnotesinfo redirect
    rewrite ^/blocnotesinfo(/.*)?$ $scheme://wiki.deimos.fr$1 permanent;
 
    # Piwik
    rewrite ^/piwik(/.*)?$ $scheme://piwik.deimos.fr$1 permanent;
 
    # Gitweb
    rewrite ^/gitweb(/.*)?$ $scheme://git.deimos.fr$1 permanent;
 
    # Drop config
    include drop.conf;
}

4.1 Server status

Il est possible de base d'avoir des informations sur l'état du serveur, de ce type :

Configuration File /etc/nginx/sites-available/www.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    server_name www.deimos.fr;
 
    access_log /var/log/nginx/www.deimos.fr_access.log;
    error_log /var/log/nginx/www.deimos.fr_error.log;
 
    # Nginx status    location /server-status {        # Turn on nginx stats        stub_status on;        # I do not need logs for stats        access_log off;        # Allow from localhost        allow 127.0.0.1;        # Deny others        deny all;    }     # PHP-FPM status    location /php-fpm_status {        include fastcgi_params;        fastcgi_pass unix:/var/run/php5-fpm.sock;        # I do not need logs for stats        access_log off;        # Allow from localhost        allow 127.0.0.1;        # Deny others        deny all;    }     # Cache APC    location /apc-cache {        root /usr/share/doc/php-apc;    }     location ~ \.php$ {        include fastcgi_params;        fastcgi_pass unix:/var/run/php5-fpm.sock;        fastcgi_intercept_errors on;        # I do not need logs for stats        access_log off;        # Allow from localhost        allow 127.0.0.1;        # Deny others        deny all;    } 
    # Blog redirect
    rewrite ^/$ $scheme://blog.deimos.fr permanent;
    rewrite ^/blog(/.*)?$ $scheme://blog.deimos.fr$1 permanent;
 
    # Blocnotesinfo redirect
    rewrite ^/blocnotesinfo(/.*)?$ $scheme://wiki.deimos.fr$1 permanent;
 
    # Piwik
    rewrite ^/piwik(/.*)?$ $scheme://piwik.deimos.fr$1 permanent;
 
    # Gitweb
    rewrite ^/gitweb(/.*)?$ $scheme://git.deimos.fr$1 permanent;
 
    # Drop config
    include drop.conf;
}

Configurez convenablement les adresses autorisées ou bien placez une authentification classique via htpasswd.

Voici le résultat donné lorsqu'on accède à la page (http://www.deimos.fr/server-status) :

Active connections: 11 
server accepts handled requests
 8109 8109 58657 
Reading: 0 Writing: 1 Waiting: 10

4.2 Wordpress

Pour la configuration de Wordpress sous Nginx, voici un exemple :

Configuration File /etc/nginx/sites-available/blog.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
    ssl_session_timeout 5m;
 
    server_name blog.deimos.fr;
    root /usr/share/nginx/www/deimos.fr/blog;
    index index.php;
 
    access_log /var/log/nginx/blog.deimos.fr_access.log;
    error_log /var/log/nginx/blog.deimos.fr_error.log;
 
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
 
    location ~ \.php$ {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }
 
    # Drop config
    include drop.conf;
 
    # BEGIN W3TC Browser Cache
    gzip on;
    gzip_types text/css application/x-javascript text/x-component text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
    location ~ \.(css|js|htc)$ {
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
    }
 
    location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
        expires 3600s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
    }
 
    location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
    }
    # END W3TC Browser Cache
 
    # BEGIN W3TC Minify core
    rewrite ^/wp-content/w3tc/min/w3tc_rewrite_test$ /wp-content/w3tc/min/index.php?w3tc_rewrite_test=1 last;
    rewrite ^/wp-content/w3tc/min/(.+\.(css|js))$ /wp-content/w3tc/min/index.php?file=$1 last;
    # END W3TC Minify core
}
}

4.3 Mediawiki

Pour une mise en place de Mediawiki avec Nginx et les URL courtes, voici la configuration à adopter. J'ai également mis du SSL et forcé les redirections de la page de login vers du SSL :

Configuration File /etc/nginx/sites-available/wiki.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
    ssl_session_timeout 5m;
 
    server_name wiki.deimos.fr wiki.m.deimos.fr;
    root /usr/share/nginx/www/deimos.fr/blocnotesinfo;
 
    client_max_body_size 5m;
    client_body_timeout 60;
 
    access_log /var/log/nginx/wiki.deimos.fr_access.log;
    error_log /var/log/nginx/wiki.deimos.fr_error.log;
 
    location / {
        rewrite ^/$ $scheme://$host/index.php permanent;
        # Short URL redirect
        try_files $uri $uri/ @rewrite;
    }
 
    location @rewrite {
        if (!-f $request_filename){
            rewrite ^/(.*)$ /index.php?title=$1&$args;
        }
    }
 
    # Force SSL Login
    set $ssl_requested 0;
    if ($arg_title ~ Sp%C3%A9cial:Connexion) {
        set $ssl_requested 1;
    }
    if ($scheme = https) {
        set $ssl_requested 0;
    }
    if ($ssl_requested = 1) {
        return 301 https://$host$request_uri;
    }
 
    # Drop config
    include drop.conf;
 
    # Deny direct access to specific folders
    location ^~ /(maintenance|images)/ {
        return 403;
    }
 
    location ~ \.php$ {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
 
    location = /_.gif {
        expires max;
        empty_gif;
    }
 
    location ^~ /cache/ {
        deny all;
    }
 
    location /dumps {
        root /usr/share/nginx/www/deimos.fr/blocnotesinfo/local;
        autoindex on;
    }
 
    # BEGIN W3TC Browser Cache
    gzip on;
    gzip_types text/css application/x-javascript text/x-component text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
    location ~ \.(css|js|htc)$ {
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
    }
 
    location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
        expires 3600s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
    }
 
    location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        add_header X-Powered-By "W3 Total Cache/0.9.2.4";
        try_files $uri $uri/ @rewrite;
    }
    # END W3TC Browser Cache
}

4.4 Gitweb

Sous Nginx, il va falloir autoriser certaines extensions dans php-fpm :

Configuration File /etc/php5/fpm/pool.d/www.conf
[...]
security.limit_extensions = .php .php3 .php4 .php5 .cgi
[...]

Et voici un exemple de configuration à adapter à vos besoins :

Configuration File /etc/nginx/sites-available/git.deimos.fr
server {
    listen 80;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
    ssl_session_timeout 5m;
 
    server_name git.deimos.fr;
    root /usr/share/gitweb/;
 
    access_log /var/log/nginx/git.deimos.fr_access.log;
    error_log /var/log/nginx/git.deimos.fr_error.log;
 
    index gitweb.cgi;
 
    location /gitweb.cgi {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        include fastcgi_params;
        fastcgi_pass  unix:/run/fcgiwrap.socket;
    } 
}

Ensuite nous allons avoir besoin d'un wrapper cgi :

Command aptitude
aptitude install fcgiwrap

Créez le lien, puis reloadez la configuration :

Command
cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/git.deimos.fr .
/etc/init.d/nginx reload
/etc/init.d/fcgiwrap restart
/etc/init.d/php5-fpm reload

4.5 Git

J'ai passé pas mal de temps à faire cohabiter Git over http(s) et Gitweb, mais ça y est ça fonctionne.

Notes Notes
Préférez la méthode Gitweb uniquement si vous n'avez pas besoin de de git over http(s)

Voici la méthode que j'ai utilisé :

Configuration File /etc/nginx/sites-available/git.deimos.fr
server {
    listen 80;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
    ssl_session_timeout 5m;
 
    server_name git.deimos.fr;
    root /usr/share/gitweb/;
 
    access_log /var/log/nginx/git.deimos.fr_access.log;
    error_log /var/log/nginx/git.deimos.fr_error.log;
 
    index gitweb.cgi;
 
    # Drop config
    include drop.conf;
 
    # Git over https
    location /git/ {
        alias /var/cache/git/;
        if ($scheme = http) {
            rewrite ^ https://$host$request_uri permanent;
        }
    } 
 
    # Gitweb
    location ~ gitweb\.cgi {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        include fastcgi_params;
        fastcgi_pass  unix:/run/fcgiwrap.socket;
    } 
}

Ici j'ai mon git over https qui fonctionne (le http est redirigé vers https) et mon gitweb également puisque tout ce qui est gitweb.cgi est matché. Maintenant, pour la partie git, nous allons devoir autoriser les repository que nous voulons. Pour celà, il va falloir renommer un fichier dans notre repository et lancer une commande :

Command
cd /var/cache/git/myrepo.git
hooks/post-update{.sample,}
su - www-data -c 'cd /var/cache/git/myrepo.git && /usr/lib/git-core/git-update-server-info'

Remplacez www-data par l'utilisateur qui a les droits sur le repository. Utilisez www-data pour que ce soit nginx qui ait les droits. Ensuite, vous avez les droits pour cloner :

Command git
git clone http://www.deimos.fr/git/deimosfr.git deimosfr

4.6 Piwik

Pour Piwik, voici la configuration :

Configuration File /etc/nginx/sites-available/piwik.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
    ssl_session_timeout 5m;
 
    server_name piwik.deimos.fr;
    root /usr/share/nginx/www/deimos.fr/piwik;
    index index.php;
 
    access_log /var/log/nginx/piwik.deimos.fr_access.log;
    error_log /var/log/nginx/piwik.deimos.fr_error.log;
 
    # Drop config
    include drop.conf; 
 
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
 
    location ~ \.php$ {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }
 
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

4.7 ownCloud

4.7.1 ownCloud 4.X

Voici la configuration d'ownCloud 4.X pour Nginx :

Configuration File /etc/nginx/sites-available/owncloud.deimos.fr
server {
    include listen_port.conf;
    listen 443 default ssl;
    ssl on;
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
 
    server_name owncloud.deimos.fr;
    root /usr/share/nginx/www/deimos.fr/owncloud;
    index index.php;
    client_max_body_size 1024M;
 
    access_log /var/log/nginx/cloud.deimos.fr_access.log;
    error_log /var/log/nginx/cloud.deimos.fr_error.log;
 
    # Force SSL
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }   
 
    # deny direct access
    location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
        deny all;
    }
 
    # default try order
    location / {
        try_files $uri $uri/ @webdav;
    }
 
    # owncloud WebDAV
    location @webdav {
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }
 
    location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_cache mycache;
        fastcgi_cache_key $request_method$host$request_uri;
        fastcgi_cache_valid any 1h;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }
 
    # Drop config
    include drop.conf;
}

4.7.2 ownCloud 5.X

Et pour la version 5 :

Configuration File /etc/nginx/sites-available/owncloud.deimos.fr
server {
    include listen_port.conf;
    listen 443 default ssl;
    ssl on; 
 
    ssl_certificate /etc/nginx/ssl/deimos.fr/server-unified.crt;
    ssl_certificate_key /etc/nginx/ssl/deimos.fr/server.key;
 
    server_name cloud.deimos.fr;
    root /usr/share/nginx/www/deimos.fr/owncloud;
    index index.php;
    client_max_body_size 1024M;
 
    access_log /var/log/nginx/cloud.deimos.fr_access.log;
    error_log /var/log/nginx/cloud.deimos.fr_error.log;
 
    # Force SSL 
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }   
 
    rewrite ^/caldav((/|$).*)$ /remote.php/caldav$1 last;
    rewrite ^/carddav((/|$).*)$ /remote.php/carddav$1 last;
    rewrite ^/webdav((/|$).*)$ /remote.php/webdav$1 last;
 
    error_page 403 = /core/templates/403.php;
    error_page 404 = /core/templates/404.php;
 
    location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
            deny all;
    }   
 
    location / { 
        rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
        rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
        rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
        rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
        rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
        try_files $uri $uri/ index.php;
    }   
 
    location ~ ^(?<script_name>.+?\.php)(?<path_info>/.*)?$ {
        try_files $script_name = 404;
        fastcgi_cache_valid any 1h; 
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }   
 
    location ~* ^.+.(jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
        expires 30d;
        # Optional: Don't log access to assets
        access_log off;
    }   
 
    # Drop config
    include drop.conf;
}

4.8 Firefox Sync Server

Pour Firefox Server Sync, c'est de la proxyfication. On transfert les requêtes vers un autre service :

Configuration File /etc/nginx/sites-available/firefoxsync.deimos.fr
server {
    include listen_port.conf;
    listen 443 ssl;
 
    ssl_certificate /etc/nginx/ssl/server.crt;    ssl_certificate_key /etc/nginx/ssl/server.key;    ssl_session_timeout 5m; 
 
    # Force SSL 
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }   
 
    server_name firefoxsync.deimos.fr; 
    access_log /var/log/nginx/firefoxsync.deimos.fr_access.log;    error_log /var/log/nginx/firefoxsync.deimos.fr_error.log; 
    location / {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 10;
        proxy_pass http://localhost:5000/;
    }
 
    # Drop config
    include drop.conf;
}

4.9 Selfoss

Configuration File /etc/nginx/sites-available/feed.deimos.fr
server {
    include listen_port.conf;
 
    server_name feed.deimos.fr;
    root /usr/share/nginx/www/selfoss;
    index index.php;
 
    access_log /var/log/nginx/feed.deimos.fr_access.log;
    error_log /var/log/nginx/feed.deimos.fr_error.log;
 
    location ~* \ (gif|jpg|png) {
        expires 30d;
    }
 
    location ~ ^/favicons/.*$ {
        try_files $uri /data/$uri;
    }
 
    location ~* ^/(data\/logs|data\/sqlite|config\.ini|\.ht) {
        deny all;
    }
 
    location / {
        try_files $uri /public/$uri /index.php$is_args$args;
    }
 
    location ~ \.php$ {
        client_body_timeout 360;
        send_timeout 360;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_intercept_errors on;
    }
 
    # Drop config
    include drop.conf;
}

4.10 Seafile

Configuration File /etc/nginx/sites-available/seafile.deimos.fr
server {
    include listen_port.conf;
    server_name seafile.deimos.fr;
    # Force redirect http to https
    rewrite ^ https://$http_host$request_uri? permanent;
}
 
server {
    include ssl/deimos.fr_ssl.conf;
 
    include pagespeed.conf;
    server_name seafile.deimos.fr;
 
    root /usr/share/nginx/www/deimos.fr/seafile;
 
    access_log /var/log/nginx/seafile.deimos.fr_access.log;
    error_log /var/log/nginx/seafile.deimos.fr_error.log;
 
    # Max upload size
    client_max_body_size 1G;
 
    location / {
        fastcgi_pass    127.0.0.1:8090;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        fastcgi_param   PATH_INFO           $fastcgi_script_name;
        fastcgi_param   SERVER_PROTOCOL     $server_protocol;
        fastcgi_param   QUERY_STRING        $query_string;
        fastcgi_param   REQUEST_METHOD      $request_method;
        fastcgi_param   CONTENT_TYPE        $content_type;
        fastcgi_param   CONTENT_LENGTH      $content_length;
        fastcgi_param   SERVER_ADDR         $server_addr;
        fastcgi_param   SERVER_PORT         $server_port;
        fastcgi_param   SERVER_NAME         $server_name;
        fastcgi_param   REMOTE_ADDR         $remote_addr;
        fastcgi_param   HTTPS               on;
        fastcgi_param   HTTP_SCHEME         https;
    }
 
    # Webdav
    location /seafdav {
        fastcgi_pass    127.0.0.1:8080;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        fastcgi_param   PATH_INFO           $fastcgi_script_name;
 
        fastcgi_param   SERVER_PROTOCOL     $server_protocol;
        fastcgi_param   QUERY_STRING        $query_string;
        fastcgi_param   REQUEST_METHOD      $request_method;
        fastcgi_param   CONTENT_TYPE        $content_type;
        fastcgi_param   CONTENT_LENGTH      $content_length;
        fastcgi_param   SERVER_ADDR         $server_addr;
        fastcgi_param   SERVER_PORT         $server_port;
        fastcgi_param   SERVER_NAME         $server_name;
 
        fastcgi_param   HTTPS               on;
    }
 
    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;
        client_max_body_size 0;
    }
 
    location /media {
        root /var/www/deimos.fr/seafile/seafile-server-latest/seahub;
    }
}

4.11 Gogs

Regarding Gogs, this is simple because all you need to set is a proxy pass:

Configuration File /etc/nginx/sites-enabled/git.deimos.fr
server {
    include listen_port.conf;
    server_name git.deimos.fr;
    # Force redirect http to https
    rewrite ^ https://$http_host$request_uri? permanent;
}
 
server {
    include ssl/deimos.fr_ssl.conf;
 
    server_name git.deimos.fr;
 
    access_log /var/log/nginx/git.deimos.fr_access.log;
    error_log /var/log/nginx/git.deimos.fr_error.log;
 
    location / {
        proxy_pass    http://127.0.0.1:3000;
    }
}

5 FAQ

5.1 Comment analyser les règles qui passent

Vous pouvez voir le comportement de vos règles (redirect 301 par exemple) en utilisant curl :

Command curl
> curl -I "http://wiki.deimos.fr" 
HTTP/1.1 301 Moved Permanently
Server: nginx
Content-Type: text/html
Location: http://wiki.deimos.fr/index.php
Content-Length: 178
Accept-Ranges: bytes
Date: Wed, 16 Jan 2013 22:17:05 GMT
X-Varnish: 2038764987
Age: 0
Via: 1.1 varnish
Connection: keep-alive

Cela vous permet d'analyser comment fonctionne celui ci et détecter d'éventuels problèmes.

5.2 client intended to send too large body

Si vous avez ce genre de messages dans vos logs :

nginx client intended to send too large body

C'est tout simplement qu'Nginx ne vous autorise pas à envoyer des fichiers d'une taille aussi grande que vous le souhaitez. Pour cela il va falloir utiliser cette variable dans la partie 'server' :

client_max_body_size 10M;

Remplacez 10M par la valeur maximale que vous souhaitez autoriser.

5.3 Access denied.

Si vous obtenez ce type de message d'erreur, c'est du à PHP-FPM qui rencontre des problèmes sur la gestion des extensions. Vous avez le choix de rajouter l'extension en question :

Configuration File /etc/php5/fpm/pool.d/www.conf
security.limit_extensions = .php .php3 .php4 .php5 .cgi

ou bien de désactiver cette sécurité (non recommandé) :

Configuration File /etc/php5/fpm/pool.d/www.conf
security.limit_extensions = false

6 Ressources

Documentation on installing Nginx HTTP Server
http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/

Nagios check php-fpm
  1. ^ http://nginx.org/en/docs/http/ngx_http_limit_req_module.html