Etape 7 – Le serveur WEB : Nginx & SSL (Let’s Encrypt)
- Introduction
- Etape 1 (V1) – Installation – Boot EFI & ZFS on Debian Bullseye avec Proxmox (sans cryptage / serveur local)
- Prochainement: Etape 1 (V2) – Installation – Disque crypté LUKS RAID & Debian Bullseye avec Proxmox
- Etape 1 (V1) – Installation – ZFS Native Encryption & Debian Bullseye avec Proxmox
- Etape 2 – Le firewall IPv4 : Shorewall
- Etape 3 – Le firewall IPv6 : Shorewall6
- Etape 4 – Le serveur DHCP : isc-dhcp-server
- Etape 5 – Le serveur DNS : Bind9
- Etape 6 – La base de données : MariaDB
- Etape 7 – Le serveur WEB : Nginx & SSL (Let’s Encrypt)
- Etape 8 – Le partage de fichier : SAMBA (Compatible Time Machine Monterey)
- Etape 9 – Le serveur de MAIL : Postfix / Dovecot / Rspamd
1. Introduction
Il existe plusieurs serveurs WEB, le plus utilisé pendant longtemps fut APACHE, désormais place à Nginx créé par Igor Sysoev.
Nous allons voir ici comment l’installer
2. Recompilation ou utilisation de mon dépôt
J’utilise le package pagespeed développé par Google. Il faut donc soit recompiler le paquet ou utiliser mon dépôt où j’ai mis le dernier paquet provenant de backport recompilé.
2.1 Recompilation
Pas confiance ou vous avez envie de faire vous même, pas de soucis !
Puis suivez les instructions suivantes…
- D’abord on ajoute les backports à la suite des lignes déjà existantes dans le fichier
/etc/apt/sources.list
:
# Backports
deb http://deb.debian.org/debian/ stretch-backports main contrib non-free
deb-src http://deb.debian.org/debian/ stretch-backports main contrib non-free
- Il faut maintenant mettre en place un environnement de développement en place :
apt install --yes dpkg-dev devscripts
apt -t stretch-backports build-dep nginx
apt install --yes build-essential zlib1g-dev libpcre3 libpcre3-dev unzip uuid-dev
- On récupère les fichiers (modifier 1.13.35.2-stable par la dernière version):
cd /usr/src
mkdir nginx_pagespeed
apt -t stretch-backports source nginx
nginx_dir=$(basename $(find . -name "nginx-*" -type d))
NPS_VERSION=1.13.35.2-stable
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip
unzip v${NPS_VERSION}.zip
nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
cd "$nps_dir"
NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
NPS_RELEASE_NUMBER=${NPS_RELEASE_NUMBER/stable/}
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})
rm $(basename ${psol_url})
cd ..
mv "$nps_dir" "$nginx_dir"/debian/modules/ngx_pagespeed
echo "debian/modules/ngx_pagespeed/psol/lib/Release/linux/x64/pagespeed_js_minify" > "$nginx_dir"/debian/source/include-binaries
apt -t stretch-backports source nginx
Revient à rechercher les liens des fichiers sur le site packages.debian.org :
wget http://http.debian.net/debian/pool/main/n/nginx/nginx_1.13.3-1~bpo9+1.dsc
wget http://http.debian.net/debian/pool/main/n/nginx/nginx_1.13.3.orig.tar.gz
wget http://http.debian.net/debian/pool/main/n/nginx/nginx_1.13.3-1~bpo9+1.debian.tar.xz
dpkg-source -x nginx_1.13.3-1~bpo9+1.dsc
De cette façon rien ne vous empêche de tenter de récupérer des versions testing voire unstable (par rapport à la logique debian mais qui sont parfois plus interessante que la version backports)
- Modifiez le fichier
/usr/src/nginx_pagespeed/nginx-Y.XX.Z/debian/rules
comme suit :
# configure flags
common_configure_flags := \
--with-cc-opt="$(debian_cflags)" \
--with-ld-opt="$(debian_ldflags)" \
--prefix=/usr/share/nginx \
--conf-path=/etc/nginx/nginx.conf \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log \
--lock-path=/var/lock/nginx.lock \
--pid-path=/run/nginx.pid \
--modules-path=/usr/lib/nginx/modules \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--with-debug \
--with-pcre-jit \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-http_auth_request_module \
--with-http_v2_module \
--with-http_dav_module \
--with-http_slice_module \
--with-threads \
--add-dynamic-module=$(MODULESDIR)/ngx_pagespeed
- On prépare l’environnement :
cd /usr/src/nginx_pagespeed
rm *.dsc
rm *.debian.tar.xz
rm v${NPS_VERSION}.zip
mv "$nginx_dir" "$nginx_dir"-Perso
mv "${nginx_dir/nginx-/nginx_}".orig.tar.gz "${nginx_dir/nginx-/nginx_}"-Perso.orig.tar.gz
cd "$nginx_dir"-Perso/debian
dch -i
- On vous demande alors de mettre à jour le changelog, modifiez comme suit :
nginx (X.YY.Z-Perso-1) UNRELEASED; urgency=low
* Non-maintainer upload.
* Add Google ngx_pagespeed (1.13.35.2-stable)
-- Votre Nom < votreadresse@email.fr > Sun, 11 Mar 2018 00:55:29 +0100
- On lance la compilation :
cd ..
debuild
- Et il faut installer les .deb à la main (ou les mettre sur votre repo local) :
dpkg -i nginx-extras_1.13.9-Perso-1_amd64.deb
- N’oubliez pas de satisfaire toutes les dépendances (bon courage) et de terminer sur :
apt install -f
2.2 Depuis mon dépôt deb.drgeek.io
Pas envie de vous prendre la tête ? Bonne idée. Vous pouvez donc utiliser mon dépôt (que je vais essayer de garder à jour).
- On ajoute donc cette ligne à la suite des lignes déjà existantes dans le fichier
/etc/apt/sources.list
:
# DrGeek
deb http://deb.drgeek.io/stretch/nginx_pagespeed ./
- Et on lance les lignes suivantes dans le terminal :
apt-key adv --recv-keys --keyserver pgpkeys.mit.edu BAD338C0F38B8DA1
apt update
apt install --yes nginx-extras
3. Extensions
3.1 PHP & Cie
Maintenant que le serveur web est installé, il faut installer php et ses modules dont un gestionnaire de cache.
apt install --yes php-apcu php-curl php-fpm php-gd php-xml php-zip php-geoip php-mcrypt php-mysql
Il y aura de nombreuses dépendances et c’est normal. Il s’agit ici des modules les plus recommandés, en fonction de vos besoins vous pouvez être amenés à en installer d’autres.
3.2 Node.JS
wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
apt install --yes nodejs
4. Configuration
4.1 Personnalisation du répertoire et de l’utilisateur (optionnel)
Ceci est tout à fait optionnel mais je vous conseille de créer un utilisateur pour le web et d’éventuellement déplacer le répertoire dédié (avec création d’un dataset si vous utilisez de ZFS) :
zfs create rpool/serveur/web
adduser --home /serveur/web userweb
chown userweb:userweb -R /serveur/web
4.2 Fichier /etc/nginx/nginx.conf
user userweb;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# On cache l'affichage de la version
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# SSL
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
log_format debugperso "Debug : ${fastcgi_script_name} - ${fastcgi_path_info} - $request_filename - $document_root ++ $fastcgi_script_name";
# Gzip Settings
gzip on;
# Virtual Host Configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
4.3 Fichier /etc/php/7.0/fpm/pool.d/www.conf
[www]
user = userweb
group = userweb
listen = /run/php/php7.0-fpm.sock
listen.owner = userweb
listen.group = userweb
listen.mode = 0666
pm = dynamic
pm.max_children = 60
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 35
pm.process_idle_timeout = 5s
chdir = /
security.limit_extensions = .php .php3 .php4 .php5 .php7
Pour les explications :
– pm.max_children : le nombre max de processus que va créer PHP-FPM
– pm.min_spare_servers : nombre minimum de processus en idle (repos)
– pm.max_spare_servers : nombre maximum de processus en idle (repos)
– pm.start_servers : nombre de processus au démarrage.
Pour les calculs :
– pm.max_children = (RAM Processeur – 500MB) / memory_limit du fichier php.ini) : pour un serveur ayant 8GB 7500MB / 128MB = 58 (60 pour arrondir).
– pm.min_spare_servers = 20% de pm.max_children (= 0,2 x 60 = 12 arrondi 10)
– pm.max_spare_servers = 60% de pm.max_children (= 0,6 x 60 = 36 arrondi 35))
– pm.start_servers = min_spare_servers + (max_spare_servers – min_spare_servers) / 2 (= 12 + (60-12)/ 2= 34) (moi j’ai mis 20 je trouve ça déjà suffisant)
4.X IP extérieure non bindée sur l’interface
- Si Votre adresse IP publique n’est pas directement bindée sur une interface (par exemple si votre serveur est en DMZ mais derrière une box par exemple il faut rajouter la ligne suivant dans le fichier /etc/systctl.conf sinon nginx refusera de se lancer :
# Autoriser à binder les IP non locale
net.ipv4.ip_nonlocal_bind = 1
Et on recharge la configuration :
sysctl -p /etc/sysctl.conf
5. SSL par Let’s Encrypt
Let’s Encrypt délivre gratuitement des certificats SSL.
- Pour cela il suffit d’avoir si ce n’est pas déjà le cas, les back-ports dans vos sources (
/etc/apt/sources.list
) :
# Backports
deb http://deb.debian.org/debian/ stretch-backports main contrib non-free
deb-src http://deb.debian.org/debian/ stretch-backports main contrib non-free
- Et on lance l’installation de certbot :
apt install --yes -t stretch-backports python3-certbot-nginx
- On édite le futur site ssl dans nginx (à adapter en fonction du domaine) :
# Redirection 80 -> 443
server {
listen 80 default_server;
server_name _;
return 301 https://ssl.mondaine.fr;
}
server {
listen 80;
server_name www.mondomaine.fr;
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://ssl.mondaine.fr;
}
}
- Il suffit d’activer le site et de lancer certbot :
ln -s /etc/nginx/sites-available/mondomainessl /etc/nginx/sites-enabled/mondomainessl
systemctl restart nginx
mkdir /var/www/letsencrypt
certbot --authenticator webroot --installer nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): monemail@mondomaine.fr
-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A
-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
-------------------------------------------------------------------------------
(Y)es/(N)o: N
Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: ssl.mondomaine.fr
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ssl.mondomaine.fr
Input the webroot for ssl.mondomaine.fr: (Enter 'c' to cancel): /var/www/letsencrypt
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/mondomainessl
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://ssl.mondomaine.fr
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=ssl.mondomaine.fr
-------------------------------------------------------------------------------
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/ssl.mondomaine.fr/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/ssl.mondomaine.fr/privkey.pem
Your cert will expire on 2018-12-28. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
- On édite de nouveau le site nginx (à adapter en fonction du domaine) :
# Redirection 80 -> 443
server {
listen 80 default_server;
listen [::]:80;
server_name _;
return 301 https://ssl.mondaine.fr;
}
server {
listen 80;
listen [::]:80;
server_name www.mondomaine.fr;
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://ssl.mondaine.fr;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ssl.mondaine.fr;
ssl on;
ssl_certificate /etc/letsencrypt/live/ssl.mondaine.fr/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ssl.mondaine.fr/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
root /var/www/monsupersite;
}
}
- Quand tout est paramétré on test le renouvellement :
certbot renew --dry-run
6. Exemples de fichier
Pour un site non php
Pour un listing de fichier avec un skin
Pour wordpress
access_log /var/log/nginx/debugperso.log debugperso;