Installer son Serveur Web : NGINX, PHP-FPM et MariaDB
On va voir comment installer et configurer correctement NGINX, PHP-FPM et MariaDB en ajoutant des sources pour obtenir des versions à jour. Pour les sources de nginx, remplacer codename par sa distribution.
| Sites officiels | Liens utiles |
|---|---|
| NGINX | Doc NGINX |
| PHP | Manuel PHP |
| MariaDB | Documentation MariaDB |
Installer et configurer NGINX
Tout d'abord, avant de vouloir installer le serveur web NGINX, il faut déjà ajouter une source.
└─# apt-cache policy nginx
nginx:
Installé : 1.14.2-2+deb10u4
Candidat : 1.14.2-2+deb10u4
Table de version :
1.14.2-2+deb10u4 500
500 http://deb.debian.org/debian buster/main amd64 Packages
500 http://security.debian.org/debian-security buster/updates/main amd64 Packages
Si on utilise les repositories de base de Debian Buster, ceux-ci installent la version 1.14.2 de NGINX. Actuellement on en est à la 1.21.2. C'est pour ça qu'on ajoute les repositories du site officiel pour obtenir une version à jour.
Tout d'abord, on commence par ajouter le depot NGINX à Debian
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] '
http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" '
| sudo tee /etc/apt/sources.list.d/nginx.list
Il faut également ajouter la GPG Key à son Debian, sans quoi il nous affichera que la source n'est pas certifiée
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor '
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Afin d'être sûr qu'on va utiliser les repository Debian, on ajoute un Pinning :
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx
Et enfin, on effectue un apt-get update pour mettre à jour nos packets disponibles.
Si tout marche bien, voici ce qu'on devrait obtenir avec apt-cache policy nginx :
Si tout se passe comme il faut, on peut lancer l'installation
Voici les options de compilations du paquet nginx
NGINX Default Compilation Options
--prefix=/etc/nginx
--sbin-path=/usr/sbin/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
--http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx
--group=nginx
--with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module
--with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module
--with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module
--with-http_auth_request_module
--with-mail
--with-mail_ssl_module
--with-file-aio
--with-http_v2_module
--with-ipv6
L'option --with-ipv6 est nécessaire pour supporter IPv6. Voir Configurer nginx pour utiliser IPv6 pour la configuration détaillée.
Désormais, nginx est quasiment prêt à être utilisé, il reste à le configurer.
Voici une configuration personnelle :
File: /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 65536;
#worker_cpu_affinity 00000010 00000100 00001000 00010000;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 16384;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
resolver 127.0.0.1 1.1.1.1;
ignore_invalid_headers on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
more_set_headers Server: Jeremy Server;
more_set_headers Contact: wiki[at]jdelgado[dot]fr;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_types text/plain text/css application/json application/ld+json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/xml+xhtml application/javascript application/vnd.ms-fontobject font/ttf font/opentype image/svg+xml image/x-icon;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Évidemment, ce fichier n'est pas à recopier tel quel, mais il y a tout de même certains points importants à conserver :
userqui sera l'utilisateur qui exécutera les instances nginxworker_processesqui définira combien d'instances seront exécutées en simultanées (ce nombre doit correspondre au nombre de coeurslogiquesdu CPU). La commande nproc donne cette info. La valeurautoest censée définir le bon nombre de workers automatiquementincludequi permet d'inclure différents éléments de configuration ànginx.confpour le rendre plus clair. Les sites se trouvent dans sites-enabled et certains éléments de configuration dans conf.d/static/server_tokensune valeur très importante, celle-ci doit être mise àoff. Cette valeur évite à nginx de montrer des éléments importants tel que son numéro de version. Ces éléments peuvent être utilisés pour exploiter des failles sur nginx. Voir Être encore plus safe en customisant son header Server NGINX pour plus de détails.ignore_invalid_headersest également une directive assez intéréssante. Si des bots tentent de se connecter avec un header incorrect, nginx leur retourne une erreur 404.resolverpermet de spécifier les DNS utilisés dans les logs pour résoudre les noms de domaines
La directive more_set_headers permet de ne pas dévoiler son serveur web, et n'est disponible que via le package nginx-extras. Voir Être encore plus safe en customisant son header Server NGINX.
On inclut également différents fichiers :
File: /etc/nginx/conf.d/filecache.conf
File: /etc/nginx/conf.d/gzip.conf
###
# GZip Settings
###
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 9;
gzip_disable "msie6";
gzip_min_length 20;
gzip_proxied any;
gzip_types text/plain
text/css
text/xml
text/javascript
application/json
application/x-javascript
application/javascript
application/xml
application/xml+rss
gzip_vary on;
Ce fichier est assez important, il permet d'activer la compression gzip, ce qui signifie concrètement un gain de vitesse sur votre site internet.
gzippermet d'activer la compression gzipgzip_bufferspermet de spécifier le nombre de buffers qui vont être utilisés, ainsi que leur taillegzip_comp_levelspécifie l'agressivité de la compression gzip. Plus la valeur est forte (max 9), plus le CPU est sollicité — 4 est un bon compromis.gzip_disablepermet de désactiver la compression GZip selon l'User-Agent (par exemple, ici on désactive la compression gzip pourIE4 à IE6)gzip_min_lengthspécifie la longueur minimale d'un élément qui doit être gzippé. Il dépend du header Content-Lengthgzip_proxiedspécifie les éléments qui doivent être gzippés lorsque nginx agit comme reverse-proxygzip_typesest également une autre ligne importante. C'est ici qu'on spécifie lesMIME-Typesdes différents éléments qui vont être gzippésgzip_varyindique si un ajout va être effectué dans le header si le fichier a été gzippé
File: /etc/nginx/snippets/ssl.conf
###
# SSL Settings
###
# Ciphers for OpenSSL 1.1.1d (Bullseye)
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DHE-RSA-CHACHA20-POLY1305:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers off;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:64m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
ssl_session_timeout 12h;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=15768000;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "no-referrer";
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
Le fichier ssl.conf est à inclure seulement si l'on souhaite du SSL sur ses sites web. Voir Forcer le SSL sous NGINX pour les directives de redirection.
Certaines lignes sont importantes tels que ssl_ciphers qui permet de sélectionner quels ciphers seront utilisés pour coder l'échange entre son serveur web, et son client. Cette ligne est extrêmement importante car il y a actuellement de nombreux ciphers utilisés mais qui sont totalement dépassés. ssl_protocols permet lui également de ne pas passés par des protocoles complètement troués. Cependant, il faut faire attention avec ces 2 lignes, car en effet, elles peuvent provoquer des erreurs de sécurité côté navigateur, voir carrément entrainer un refus du navigateur. Nous activons également le protocole HSTS (Plus d'informations ici)
Pour avoir une bonne cipher list et de bons paramètres SSL, voir le Wiki Mozilla.
La configuration CSP (Content Security Policy) n'est pas couverte ici — c'est un protocole délicat à mettre en place, voir content-security-policy.com.
Voici désormais des snippets utiles pour ses différents blocks nginx :
File: /etc/nginx/snippets/protect.conf
Ce fichier nous permet d'éviter que des fichiers de configuration ou autres soient accessible par tout le monde. Il s'agit d'un fichier générique qui s'adapte au plus grand nombre de services, évidemment, il se peut que certains fichiers/dossiers ne soient pas protégés, dans ces cas-là, il faut les ajouter manuellement.
Snippets
Snippets utiles pour les vhosts (snippets/letsencrypt.conf) :
File: /etc/nginx/snippets/letsencrypt.conf
Installer et configurer PHP7-FPM
Commande à adapter selon les modules souhaités. Généralement suffisant pour 99% des installations. Pour installer une version spécifique de PHP, voir Installer une version custom de PHP:
apt-get -y install php-common php8.2 php8.2-bz2 php8.2-cli php8.2-common php8.2-curl php8.2-fpm php8.2-gd php8.2-geoip php8.2-gmp php8.2-igbinary php8.2-imagick php8.2-intl php8.2-json php8.2-mbstring php8.2-mcrypt php8.2-memcached php8.2-msgpack php8.2-mysql php8.2-opcache php8.2-readline php8.2-sqlite3 php8.2-xml php8.2-xmlrpc php8.2-zip
La configuration de base de PHP-FPM se situe dans /etc/php/8.2/fpm/ et ses sous-répertoires (adapter 8.2 à la version installée).
Éditer le fichier php.ini :
expose_php: Désactivation afin de ne pas exposer la version de PHupload_max_filesize: Modification de la taille maximale des fichiers qu'on peut upload avec PHPpost_max_size: Va avec la directive upload_max_filesize et doit être supérieur à cette dernièremax_file_uploads: Nombre de fichiers qu'on peut upload en parallèle. Par défaut à 20, peut suffir dans une majorité des cas
Petit customisation de la. configuration afin d'optimiser les performances. Il faut pour la plupart des CMS/Framework adapter les valeurs de l'OPcache. Pour WordPress, voici des valeurs adéquates :
opcache.memory_consumption = 128M
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=100000
opcache.fast_shutdown=1
Symfony fournit ses propres recommandations pour la configuration de l'OPcache. La variable opcache.max_accelerated_files peut être facilement calculée :
Pour cet exemple, 10000 fichiers sont largement suffisants. Aucune astuce n'existe pour calculer opcache.memory_consumption — il faut surveiller le monitoring.
Installer et configurer MariaDB
On met à jour les paquets disponibles :
Et enfin, on vérifie que la Candidate Version est la bonne :
Voilà le résultat attendu :
$ apt-cache policy mariadb-server
mariadb-server:
Installé : (aucun)
Candidat : 1:10.3.29-0+deb10u1
Table de version :
*** 1:10.3.29-0+deb10u1 500
500 http://apt.daevel.fr/debian buster/main amd64 Packages
100 /var/lib/dpkg/status
Si tout se passe comme il faut, on lance l'installation du serveur SQL
Pendant l'installation de mariadb-server, une fenêtre demande de spécifier un password.
Danger
Cette fenêtre définit le root password MariaDB. Utiliser un mot de passe solide — tous les sites hébergés sont exposés si ce mot de passe est faible ou vide.
Et on finit par le script made in MariaDB pour sécuriser le tout
Voir aussi
- Forcer le SSL sous NGINX — Configuration SSL/TLS et redirection HTTPS
- Configurer nginx pour utiliser IPv6 — Support IPv6 dans nginx
- Installer une version custom de PHP — Utiliser le dépôt Sury pour des versions récentes