Attention, cet article a plus d'une année d'ancienneté. Il est possible que les informations présentées ne soient plus à jour, spécialement dans le cadre d'un article technique.
Bonjour à tous,
Je me suis enfin décidé a mettre en place un vrai reverse proxy NGINX pour accéder à ce que j’ai chez moi, c’est à dire, mon nas et mon proxmox principalement.
Cela me permet d’avoir les derniers protocoles de chiffrement disponibles et de ne pas dépendre des serveurs web intégrés au NAS (synology) ou au Proxmox.
Je peux aussi appliquer les sécurités et restrictions qui me vont bien, sans avoir a bidouiller ces deux systèmes.
J’ai installé le tout sur mon Raspberry Pi 2 qui prenait la poussière (mais j’aurais pu le rajouter sur le Pi Zero).
Préparation du système et installation de NGINX :
Pour le système d’exploitation, j’ai simplement pris une Raspbian Jessie Lite, rien de plus, rien de moins.
Pour ce qui est de NGINX c’est comme d’habitude une installation par compilation que j’ai faite avec mon script qui est toujours mis à jour ici : https://github.com/stylersnico/nginx-openssl-chacha-naxsi.
Je suis repartie sur ma configuration de NGINX open sourcée ici : https://github.com/stylersnico/nginx-secure-config, mais en modifiant les paramètres TLS pour que ça soit infiniment plus restrictif :
ssl_protocols TLSv1.2; ssl_ecdh_curve X25519:sect571r1:secp521r1:secp384r1; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305-D:ECDHE-RSA-CHACHA20-POLY1305-D:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on;
Sur CryptCheck ça donne carrément ceci :
Eh oui, pas de 100% pour le support des chipers, la faute à AES128-GCM qui est obligatoire pour tous mes appareils qui ne supportent pas CHACHA20 mais qui aimeraient se connecter en HTTP2 (qui ne supporte pas AES256-GCM on le rappelle), mais on n’est déjà pas si mal.
Configuration du reverse proxy :
La première des choses à faire, c’est d’ajouter la configuration spécifique pour transformer nginx en reverse proxy :
nano /etc/nginx/conf.d/proxy.conf
On remplit avec ceci :
proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_hide_header Strict-Transport-Security; proxy_hide_header X-Powered-By; proxy_hide_header *; proxy_intercept_errors on; proxy_buffering on; proxy_cache_key "$scheme://$host$request_uri"; proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache:10m inactive=7d max_size=700m;
Ensuite, on créer les vhosts pour les différents reverses que l’on souhaite faire, dans mon cas un synology et un proxmox :
Le nas :
server { listen 80; server_name nas.domain.com; location '/.well-known/acme-challenge' { root /var/www/nas.domain.com/; try_files $uri /$1; } }
Le proxmox :
server { listen 80; server_name proxmox.domain.com; location '/.well-known/acme-challenge' { root /var/www/proxmox.domain.com/; try_files $uri /$1; } }
Eh oui, avant de configurer le reverse, on créer les certificats Let’s Encrypt en suivant et en adaptant la procédure ici : https://www.abyssproject.net/2016/02/creer-un-certificat-ecdsa-avec-lets-encrypt/
Une fois les cerficats générés, voici les vhost finaux :
Le nas :
server { listen 80; server_name nas.domain.com; return 301 https://$host$request_uri; location '/.well-known/acme-challenge' { root /var/www/nas.domain.com/; try_files $uri /$1; } } server { listen 443 http2; server_name nas.domain.com; ssl on; ssl_certificate /etc/letsencrypt/live-ecdsa/nas.domain.com/chain.pem; ssl_certificate_key /etc/letsencrypt/live-ecdsa/nas.domain.com/privkey-p384.pem; if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } location '/.well-known/acme-challenge' { root /var/www/nas.domain.com/; try_files $uri /$1; } location / { proxy_pass https://10.26.79.61:5001/; proxy_cache cache; proxy_cache_valid 12h; expires 12h; proxy_cache_use_stale error timeout invalid_header updating; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; } }
Le proxmox :
server { listen 80; server_name proxmox.domain.com; return 301 https://$host$request_uri; location '/.well-known/acme-challenge' { root /var/www/proxmox.domain.com/; try_files $uri /$1; } } server { listen 443 http2; server_name proxmox.domain.com; ssl on; ssl_certificate /etc/letsencrypt/live-ecdsa/proxmox.domain.com/chain.pem; ssl_certificate_key /etc/letsencrypt/live-ecdsa/proxmox.domain.com/privkey-p384.pem; if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; } location '/.well-known/acme-challenge' { root /var/www/proxmox.domain.com/; try_files $uri /$1; } location / { proxy_pass https://10.26.78.11:8006/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache cache; proxy_cache_valid 12h; expires 12h; proxy_cache_use_stale error timeout invalid_header updating; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; } }
Remplacez évidemment mes IP par les vôtres.
L’œil affûté aura remarqué que j’ai aussi ajouté une authentification basique en plus de celle qui sont sur le nas et le proxmox.
Pour générer le fichier qui contiendra votre nom d’utilisateur et votre mot de passe, on utilise les utilitaires apache :
apt-get install apache2-utils -y
Générez votre utilisateur avec cette commande :
htpasswd -c /etc/nginx/.htpasswd bob
Et redémarrez NGINX :
service nginx restart
Voilà, je ne me suis pas trop foulé au niveau de l’optimisation des performances, ni au niveau de l’authentification (auth_basic).
Je suis le seul utilisateur sur la chose et le nas est déjà protégé par une double authentification tandis que le cluster proxmox est coupé électriquement lorsque je ne m’en sers pas.
Toute la configuration est disponible sur Github : https://github.com/stylersnico/home-reverse-proxy
Source (pour la console VNC de proxmox) : https://www.jamescoyle.net/how-to/1736-reverse-proxy-proxmox-vnc-with-nginx
Salut,
Merci beaucoup pour ce tuto très complet et en français 🙂
Aujourd’hui en 2019, il faut remplacer tous les chemins contenant letsencrypt par certbot pour que ça fonctionne. Le github redirige même vers certbot.
Pour ceux qui souhaitent mettre un nextcloud derrière ce proxy, il est nécessaire de retirer le bloc suivant du fichier *.vhost:
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
A part ce léger update, tout fonctionne encore parfaitement deux ans plus tard et toujours avec une note de A+ sur ssllabs.com
Merci beaucoup Nicolas.
Hello, j’ai pas mal consulté ton site pour tout ce qui est « à la recherche de la configuration parfaite pour Nginx », je viens de terminer mon NAT sur Proxmox + mon reverse proxy Nginx sur mon serveur dedié Online (parce que j’ai pas d’IP failover) Cependant j’ai un seul petit truc qui ne fonctionne pas, j’arrive pas à retrouver le HSTS, du coup je suis noté F sur securityheaders.io, aurais-tu une idée ? J’ai bien mes lignes add_header dans le location / { } juste avant le proxy_pass pourtant En tout cas merci pour tes articles (« Quelle protection anti ransomware… Voir plus »
Salut,
Les headers nécessaires pour HSTS sont bien expliqués ici : https://www.abyssproject.net/2016/11/a-la-recherche-de-la-configuration-parfaite-pour-nginx/
Par contre, je te conseille d’y faire dans le nginx.conf directement pour que ça se répercute sur tout le serveur 🙂
Bonjour, est-ce que pendant la phase de certification/renouvellement l’authentification doit être coupée pour que certbot puisse authentifier le serveur? Si oui, aurais-tu une idée pour faire ça de façon plus « transparente »?
Bonjour,
Non, l’authentification ne devra pas être coupée, car on ne demande aucune authentification sur le dossier utilisé par Let’s Encrypt.
Pour pouvoir utiliser la console des VM Proxmox: https://www.jamescoyle.net/how-to/1736-reverse-proxy-proxmox-vnc-with-nginx
Salut,
Merci, c’est ajouté dans l’article 🙂