Tutoriel Nginx Proxy Manager
Dans ce tutoriel, nous allons nous intéresser à l'installation et à la configuration d'un reverse Proxy que j'ai nommé Nginx Proxy Manager.
Nginx Proxy Manager est un reverse-proxy simplifié capable de fournir aux usagers ne souhaitant pas forcément s'attarder sur le configuration de Nginx une configuration et une administration simple. Basé sur OpenResty, l'outil apporte une gestion simple centralisée depuis une interface Web capable de rendre accessible, depuis l'extérieur, différents services comme des serveurs Web, de jeu ou de mail par exemple.

Pour rappel, un serveur reverse-proxy est un serveur que l'on va placer devant un ou plusieurs serveurs d'applications. Son rôle principal est de fournir une passerelle d'accès entre le réseau Internet et le réseau de serveur accessible en DMZ (réseau contenant des machines accessibles depuis Internet) où sont hébergées les serveurs de ressources comme un serveur de messagerie, de jeu par exemple.
L'avantage de disposer d'un serveur Reverse-Proxy est de permettre avec une seule adresse IP publique de "dispatcher" les différents serveurs de ressources en un serveur de gestion ouvert en front sur Internet.

Dans le schéma de représentation, un utilisateur lambda souhaite accéder au site Web www.vemotech.fr, qui est un serveur Web interne. Il va dans un premier temps envoyer une requête à destination du reverse proxy, représenté en vert entre la requête client et le firewall, puis la DMZ, qui se chargera d'associer le sous domaine www vers le serveur interne configuré dans le reverse proxy.
Entre deux, un firewall effectue un contrôle d'accès aux ressources nécessaires au serveur reverse proxy (services HTTPS & HTTPS) afin de gérer au mieux le niveau de sécurité du réseau DMZ. Enfin, en retour, l'utilisateur obtient en retour le site internet demandé. Le serveur reverse proxy ouvert sur Internet, avec redirection des ports HTTP (80) & HTTPS (443).
Il est donc à noter que seul ce serveur sera accessible depuis Internet depuis les service HTTP & HTTPS et qu'un aucun cas l'internaute n'aura accès directement au serveur d'application hébergé dans la DMZ.
Dans la préparation de l'environnement, nous allons mettre en place deux serveurs et un pare-feu, joignable depuis l'extérieur uniquement par le biais du serveur Nginx Proxy Manager.

Je prépare deux serveurs sous Debian dont un pour installer Nginx Proxy Manager et un autre pour faire office de serveur Web. Un domaine public nommé cosmotech.cf fera office de domaine principal et qui sera associé à une adresse IP publique qui portera le serveur Reverse Proxy derrière. Dans ce cas de figure, un pare-feu Stormshield agira en tant que gestionnaire d'accès entre le serveur Nginx Proxy Manager et les ressources internes à la DMZ.
Nginx Proxy Manager se base sur Docker, donc il est nécessaire d'avoir installer Docker au préalable (un tutoriel consacré à l'installation de Docker est disponible juste ici et un autre lié à l'installation de DockerFile juste là
). Un pare feu Stormshield va gérer les accès au serveur Web par une règle Reverse NAT. Ce pare-feu Sur le serveur Web Debian, j'ai décidé d'installer un serveur Apache afin de faire office de serveur Web interne.
Le fait d'avoir un pare-feu entre les deux n'est pas obligatoire mais il est fortement recommandé afin d'avoir au minimum un réseau bien géré et sécurisé
Quelques prérequis afin de de suivre ce tutoriel :
Afin d'installer Nginx Proxy Manager, il est nécessaire d'avoir installé Docker et Docker Compose (des tutoriels sont consacrés à ce sujet : Installer Docker et Docker Compose).
Dans un premier temps, nous allons créer un répertoire qui contiendra l'ensemble des fichiers de Nginx Proxy Manager :
mkdir nginxproxymanager
cd nginxproxymanager
Ensuite, nous allons créer un fichier YML que l'on nommera docker-compose.yml dans lequel nous allons inscrire la configuration à avoir pour l'image de Nginx Proxy Manager.
nano docker-compose.yml
Dans ce fichier, nous allons écrire la configuration suivante, les instructions nécessaire à la construction de l'image :
version: "3"
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Port HTTP public
- '443:443' # Port HTTPS public
- '81:81' # Port d'administration Web (ne doit pas être accessible de l'extérieur)
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
DB_MYSQL_HOST: "db" # Nom d'hôte du serveur SQL
DB_MYSQL_PORT: 3306 # Port d'écoute par défaut de MySQL / MariaDB
DB_MYSQL_USER: "npm" # Utilisateur de la base SQL de Nginx Proxy Manager
DB_MYSQL_PASSWORD: "Passw0rd1!" # Mot de passe de l'utilisateur npm (à modifier !)
DB_MYSQL_NAME: "npm" # Nom de la base de données de Nginx Proxy Manager
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'Sup€r@R00TPasswd0rd2' # Mot de passe SQL compte Root (à modifier !)
MYSQL_DATABASE: 'npm' # Nom de la base de données de Nginx Proxy Manager
MYSQL_USER: 'npm' # Utilisateur de la base SQL de Nginx Proxy Manager
MYSQL_PASSWORD: 'Passw0rd1!' # Mot de passe de l'utilisateur npm (à modifier !)
volumes:
- ./data/mysql:/var/lib/mysql
Dans la configuration, assurez-vous de spécifier des informations de connexions différentes (nom d'utilisateur & mot de passe). Utilisez les mêmes informations de connexions de la partie "DB_" comme pour la partie "MYSQL_".
De plus, au niveau de l'ouverture de vos ports depuis l'extérieur, nous vous recommandons de ne pas ouvrir le port 81 TCP, nécessaire à la gestion du serveur Nginx Proxy Manager. L'usage de l'interface d'administration n'est nécessaire qu'en interne (sauf si vous utilisez un serveur distant, dans ce cas utilisez un VPN).

Une fois le fichier modifié et enregistré, il ne vous reste plus qu'à lancer votre image dans le répertoire créé (dans notre cas le dossier nginxproxymanager) avec Docker Compose !
sudo docker-compose up -d

docker-compose.ymlOn s'assure que le container est bien en cours d'exécution :
sudo docker-compose ps

Nous avons bien nos deux services lancés en tâche de font : notre service Nginx Proxy Manager et notre serveur MariaSQL. Nous pouvons constater que le répertoire ~/nginxproxymanager contient maintenant les fichiers nécessaires à l'image :

Vous pouvez arrêter ou relancer à nouveau l'image. Cette procédure gardera en mémoire les fichiers de configurations modifiés :
cd ~/nginxproxymanager
sudo docker-compose up -d
sudo docker-compose down

En allant directement sur l'adresse IP du serveur sur le port 80, vous pouvez constater qu'une page par défaut est affichée :

En allant également sur le port d'administration 81, vous pouvez visualiser l'espace d'authentification de Nginx Proxy Manager :

La page en HTTPS est disponible car le certificat autosigné est présenté, mais n'est pour le moment pas opérationnelle (code ERR_EMPTY_RESPONSE sur Chromium).
Une fois que notre installation est opérationnelle, il est maintenant temps de faire le tour du propriétaire ! Connectez-vous dans un premier temps sur l'adresse IP de votre serveur suivit du port 81 (exemple : http://<ip_or_fqdn>:81).
Renseignez ensuite les informations de connexions par défaut :

Lors de la connexion, si vous obtenez une erreur "Bad Gateway", laissez un peu de temps afin que le système se mette en place en interne (j'ai eu ce problème et j'ai patienté un peu et ça a fonctionné pour moi !).
Une fois la connexion effectuée, un assistant s'ouvre afin d'éditer les informations du compte administrateur de Nginx Proxy Manager :

Choisissez ensuite un mot de passe robuste que vous n'utilisez pas ailleurs (Qu'attendez-vous d'ailleurs pour utiliser un gestionnaire de mot de passe tels que Keepass ou Bitwarden ?!
) :

Vous voici dès à présent sur le Dashboard de Nginx Proxy Manager ! Sur cette page, vous obtenez un récapitulatif des proxies et des différentes règles Nginx créées. Sur l'ensemble des pages, vous disposez d'une barre de gestion des hôtes, des listes d'accès, des certificats SSL, des utilisateurs sur Nginx proxy Manager, d'une visualisation des journaux d'audits et ainsi que les paramètres des pages de Nginx présentes par défaut, encadré en vert.
Encadré en orange, vous pouvez modifier les différentes informations du compte connecté tels que l'adresse Email, le nom ou son mot de passe. Vous pouvez modifier l'avatar si le mail choisi est enregistré chez Gravatar.

Nginx Proxy Manager dispose de plusieurs menu et sous-menus afin de gérer les différents Virtual Hosts et divers évènements :
Un hôte proxy est le point d'arrivée d'un service Web que vous souhaitez transférer. Il fournit une terminaison SSL optionnelle pour votre service qui pourrait ne pas avoir de support SSL intégré. Les hôtes proxy sont l'utilisation la plus courante du gestionnaire de mandataires Nginx. Commençons à ajouter un hôte proxy en allant dans Hosts > Proxy Hosts > Add Proxy Host.

Lors de ce nouvel enregistrement, spécifiez le nom complet du domaine incluant ainsi le sous domaine de votre choix. Lors de la saisie, appuyez sur la touche "Entrer" dans la propriété "Domain Names" afin de valider l'ajout du domaine.

Renseignez dans un premier le nom de domaine complet. Choisissez ensuite dans "Scheme", soit HTTP ou HTTPS, qui sera la méthode d'appel au serveur d'origine. Dans la partie "Forward Hostname / IP", spécifiez l'adresse IP ou le nom DNS du serveur réel et ainsi que son port de redirection dans "Forward Port", si jamais votre application tourne sur un port différent de 80 ou 443.
L'option "Block Common Exploits" est une fonctionnalité à activer et qui bloque les attaques de base qui pourrait atteindre le site proxifié tels que le Spam, les UserAgent malveillants, les injections SQL, les exploits...
Enfin, la notion de liste d'accès sera définit par défaut, c'est à dire que tous le monde aura accès au site proxifié sans authentification HTTP. Plus tard dans le tutoriel, nous auront la possibilité de restreindre l'accès avec une authentification HTTP gérée par Nginx Proxy Manager applicable à un Proxy.
Dans "Custom Location", vous pouvez décider de rendre accessible le contenu d'un dossier sur le serveur d'origine. Par exemple, si vous avez un répertoire public destiné au serveur Web avec plusieurs sous dossier contenant des sites différents, définissez alors le chemin du dossier à rendre accessible au proxy et même les paramètres d'accès HTTP. Une roue crantée offre la possibilité d'insérer sa propre configuration Nginx pour ce proxy.

Actuellement, nous pouvons remarquer que le site dispose d'une connexion HTTPS avec un certificat TLS. En effet, ce certificat est géré par Cloudflare. Mais qu'advient-il si je n'utilise pas Cloudflare et que je souhaite disposer d'une connexion HTTPS ?
Dans l'onglet SSL, sélectionnez votre propre certificat que vous avez importé ou créé dans l'onglet "SSL Certificate" ou générez-en un automatiquement avec Let's Encrypt & Certbot.

Plusieurs options de gestion TLS/SSL sont disponibles :

Activez l'option "Force SSL" afin de chiffrer en permanence le trafic. Activez également le support HTTP/2 qui accélère la vitesse de chargement des pages par la compression des en-tête HTTP par une seule connexion TCP entre le client et le serveur.
Activez ou non l'option HSTS qui consiste à bloquer complètement l'accès au site si il y a un problème de conformité avec le certificat TLS (soit il auto-signé, révoqué, a expiré...). Donc si dans votre navigateur vous recevez une erreur indiquant un problème de certificat, impossible de cliquer sur "Continuer vers..." afin d'ajouter une exception de sécurité.
Dans le menu "Advanced", vous pouvez écrire des instructions à affecter à la configuration de Nginx comme l'ajout d'en-tête supplémentaire par exemple :
more_set_headers "MyHeader: value";

Une fois l'enregistrement créé, il sera listé sur la page des hôtes proxy. En essayant d'accéder au sous domaine créé, il est inaccessible... En effet, nous n'avons pas encore créé notre enregistrement DNS !

Accédez au panneau de configuration de votre domaine et ajoutez un enregistrement de type CNAME afin de faire pointer le sous domaine sur le domaine racine. L'enregistrement peut être instantané comme peu prendre un certain temps avant d'être propagé.

En tentant d'accéder maintenant au sous domaine web.cosmotech.cf, nous visualisons notre superbe site internet !

Notre site est désormais en ligne ! 
Dans le cas où une application ne dispose pas d'un système d'authentification utilisateur intégré ou que vous souhaitez restreindre une application en plus de l'authentification afin d'éviter le référencement de celle-ci par exemple, Nginx Proxy Manager propose une solution permettant de gérer les listes d'accès par des comptes utilisateurs ou par restrictions d'adresse IP.

Dans l'onglet "Access list", vous pouvez créer un profil de restriction qui pourra être affecté à un site. En cliquant sur "Add Access List", deux niveaux d'authentifications sont possibles :

Dans le menu "Details", vous pouvez renseigner un nom explicit à la règle afin de mieux l'identifier (exemple : Checkpoint_Auth_SrvWeb). Deux options suivantes sont proposées :
Dans le menu "Authorisation", vous pouvez ajouter à votre guise les comptes utilisateurs d'accès :

Dans l’onglet "Autorisation", vous pouvez entrer des noms d’utilisateur et des mots de passe pour authentifier les utilisateurs auprès de votre application ou service.
La connexion sera gérée par Nginx Proxy Manager et le formulaire sera semblable à celui-ci :

Dans le menu "Access", ajoutez une adresse IP ou un bloc d'adresse IP est renseignez si il doit être Whitelisté ou Blacklisté du reverse proxy :

Vous pouvez sélectionner ce menu si vous souhaitez autoriser ou bloquer des adresses IP spécifiques. Les règles sont appliquées dans l’ordre d'ajout, de sorte que lorsqu’il y a une correspondance, toutes les autres règles ci-dessous sont ignorées. Il est important de mentionner que vous ne pouvez pas seulement entrer une seule adresse IP, mais aussi des réseaux. Donc, dans cet exemple, j’ai autorisé le réseau 10.28.0.0/24 à accéder au proxy. Cela signifie que toutes les adresses IP de 10.28.0.1 à 10.28.0.254 sont autorisées à se connecter via cette liste d’accès. En revanche, les adresses IP comprises entre 114.21.95.1 et 114.21.95.254 ne sont pas autorisées et sont donc bloquées.
Sur la version dernièrement publié, un bug graphique est présenté lorsque l'on a déjà renseigné plusieurs informations dans la liste des comptes et des adresses IP. Si on clique sur le bouton "Add" afin d'ajouter de nouveaux champs, cette action efface la liste. En attendant, cliquez plusieurs fois sur le bouton "Add" même si vous ne remplissez pas tout et ça devrait aller
Une fois notre liste d'accès créée, elle apparait dans la partie "Access Lists". C'est à cet endroit que vous allez pouvoir gérer les règles créées.

Il ne reste maintenant plus qu'à activer notre "protection" à un hôte Proxy afin de lui affecter la liste d'accès créée précédemment. Rendez-vous dans Hosts > Proxy Hosts. Éditer la configuration d'un hôte où vous souhaitez ajouter la liste d'accès. Par défaut, l'accès est considéré comme "Public" :

En bas de la fenêtre, dans la partie "Access List", sélectionnez la configuration que vous avez ajoutée :

Valider les changements effectués, et en tentant d'accéder à l'URL et en renseignant les logins spécifiés :

On remarque alors que le site internet s'affiche convenablement ! 

Afin de rendre ce qui précède encore plus simple dans Nginx Proxy Manager, nous pouvons créer ce que l’on appelle un certificat générique. L'objectif est d'effectuer une demande DNS automatiquement pour créer un certificat Wildcard pour chaque domaines et sous domaines. Les avantages sont qu'au lieu d’en créer un pour chaque sous-domaine comme ci-dessus, il est plus intéressant d'en créer qu'un seul pour tous le monde et que toujours il y aura un certificat de proposé si le certificat du sous-domaine n'est pas encore installé et configuré.
Dans notre exemple, nous allons utiliser Cloudflare afin de "relier" Nginx Proxy Manager via l’API proposée. En fonction du fournisseur de domaine, l'opération est similaire à celle proposée. Consulter ainsi les documentations associées aux différents fournisseurs répandus comme OVH, Infomaniak, Ionos, DigitalOcean, GoDaddy...
Cela vous permettra d’utiliser essentiellement le même certificat (*.cosmotech.cf). Dans un premier temps, allez sur le panneau d'administration de Cloudflare et cliquez sur le nom de domaine associé. Il vous amènera à la page principale avec quelques graphiques et "Actions rapides" en haut à droite.
En bas à droite, au niveau de la section "API", vous verrez l’ID de zone API et l’ID de compte. En dessous, vous devez cliquer sur Obtenir votre jeton d'API (ou directement accessible via https://dash.cloudflare.com/profile/api-tokens).

Dans le menu de gestion des API de Cloudflare, vous y retrouvez les jetons créés pour tous les domaines enregistrés sur votre compte Cloudflare. En haut de la page, cliquer sur "Créer un jeton" :

En bas de la page, créez un jeton API personnalisé afin de configurer manuellement les autorisations que nous souhaitons :

Choisissez un nom explicit au jeton (le token) API (par exemple : DNSEdit_CosmoTech_NginxProxyManager => module + action + site + service). Dans les autorisations, sélectionnez dans le premier menu "Zone", puis "DNS" et comme action d'édition. Au niveau des ressources de la zone, choisissiez d'inclure une zone spécifique ayant comme valeur votre site (ex : cosmotech.cf).

Vous devriez visualiser ensuite un récapitulatif du Token qui sera créé et valider la création.

Enfin, vous obtenez le Token avec les droits affectés sur Cloudflare :

Sur notre machine Linux, vous pouvez tester l'appel de l'API avec Curl afin de vérifier son bon fonctionnement :
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer {YOUR_API_KEY}" \
-H "Content-Type:application/json"

On remarque le Token est bien valide. Copiez le Token du premier encadré, car nous en aurons besoin sur Nginx Proxy Manager. 
Dans notre interface de gestion de Nginx Proxy Manager, dans la partie "SSL Certificates", ajoutez un nouveau certificat SSL Let's Encrypt. Saisissez le domaine Wildcard pour le certificat (*.cosmotech.cf) et activez l'option "Use DNS Challenge". Une section particulière apparait et sélectionnez dans le menu déroulant "DNS Provider" votre fournisseur de domaine. Dans notre cas, en sélectionnant Cloudflare, automatiquement une récupération est effectuée dans le champ "Credentials File Content" afin de ne plus qu'à spécifier la clé API que vous avons créée :
# Cloudflare API token
dns_cloudflare_api_token = {YOU_API_KEY}

Remplacez dans le champ bleu par votre clé API, acceptez les conditions générales des services de Let's Encrypt et enregistrez la configuration.
Si vous utilisez un domaine gratuit comme dans mon cas, Cloudflare restreint parfois son API aux domaines .cf, .ga, .gq, .ml, ou .tk afin d'éviter les abus... Si le domaine gratuit a été récemment créé, attendez sa propagation et attendez avant de spécifier directement les serveurs DNS de Cloudflare Pour les autres domaines payants, l'opération doit normalement fonctionner.
Votre certificat est ensuite créé et vous n'avez plus qu'à le spécifier à domaine souhaité ! 
Si pour des raisons techniques ou que vous ne voulez pas toujours accéder à votre gestionnaire DNS de votre fournisseur de nom de domaine, vous pouvez rajouter un enregistrement soit A ou CNAME avec une valeur Wildcard (*) suivit soit de l'adresse IP ou du domaine afin de faire correspondre chaque domaine qui sera ajouté sur Nginx Proxy Manager, qui symbolise tous les sous domaines.

De ce fait, en saisissant n'importe quel sous domaine, vous tomberais automatiquement sur la page par défaut du reverse-proxy. En revanche, si un nom de domaine a déjà été configuré, alors le sous domaine pointera vers la configuration existante.
Dans notre exemple, nous avons configuré le sous domaine web.cosmotech.cf :

Si je saisie maintenant un domaine totalement aléatoire :

Nous remarquons que nous sommes redirigé sur la page de Bienvenue par défaut définie depuis Nginx Proxy Manager.
Vous pouvez également personnaliser la page Web par défaut du serveur Nginx Proxy Manager. Cliquez sur le menu Settings > Default site et sélectionnez Edit. Vous pouvez choisir soit d'afficher une erreur 404, de rediriger vers une nouvelle adresse ou de créer une page personnalisée :

Par exemple, voici le rendu d'une page personnalisée visible pour les enregistrements DNS créés mais pas configurés sur Nginx Proxy Manager :

Et voilà, maintenant vous savez (presque) tout sur Nginx Proxy Manager. Ce serveur reverse proxy est principalement connu pour sa simplicité et son interface moderne et surtout qu'il est tellement plus simple d'utiliser Nginx maintenant ! N'hésitez-pas à nous solliciter pour toute question particulières dans le forum 