Utiliser NGinx comme Reverse Proxy
Tout comme son homologue Apache, Nginx est un serveur Web qui peut être utilisé comme Reverse Proxy. Un Reverse Proxy est utilisé comme intermédiaire entre les clients et un ou plusieurs serveurs pour améliorer la sécurité des services exposés sur Internet, améliorer les performances par un usage de mémoire cache et de l'équilibrage de charge.
Imaginez que vous ayez un service qui tourne sur un serveur en écoute du port 9000. Vous ne voulez pas que ce service soit directement exposé sur internet avec tous les problèmes de sécurité existants. Utiliser Nginx comme reverse proxy va lui permettre de récupérer les requêtes provenant des utilisateurs, de les transférer au service en écoute sur le port 9000 quelque part sur un serveur protégé et de renvoyer la réponse du servier web au client qui a initié la requête.
Si vous disposez déjà de Nginx fonctionnel vous pouvez sauter cette étape sinon plusieurs solutions sont possibles :
On partira du postulat que Ubuntu version Serveur a été installé sur une machine neuve. Sur cet Ubuntu, nous
allons installer nginx par sudo apt install nginx
. Par défaut, le firewall
UFW (Uncomplicated FireWall) est installé mais inactif sur Ubuntu. Puisque nous sommes (normalement) en train d'utiliser
SSH pour gérer le serveur à distance, il ne faut pas que nous fermions nos accès. Faites un sudo ufw allow 22/tcp
afin d'autoriser le flux SSH à travers le firewall. Vérifiez le status pour être sûr que c'est bien le cas. Nous pouvons maintenant
activer UFW avec sudo ufw enable
. Le status obtenu par sudo ufw status
nous indique que le firewall logiciel est maintenant activé et nous affiche également les règles en cours. Un petit tour sur le status
de nginx nous affiche alors
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
Prenez votre navigateur préféré et pointez vers l'adresse http://<ip-du-serveur-nginx>. Vous devriez obtenir l'affichage de la page
par défaut de Nginx.
Puisque nous parlons de serveur web, il nous faut autoriser les ports 80 et 443 à destination de notre serveur nginx par
sudo ufw allow http
sudo ufw allow https
Lorsque Nginx s'installe il créé un utilisateur www-data avec lequel seront réalisées les opérations d'authentification sur les différents services Nginx. C'est cet utilisateur qui est référencé sur la première ligne du fichier /etc/nginx/nginx.conf. Dans ce fichier, nous retrouvons également la notion de worker_processes qui indique le nombre de connexions simultanées supportées par Nginx. La valeur "auto" essaie de détecter le nombre de CPU disponibles pour paramétrer au mieux le comportement de Nginx. Globalement le nombre de connexions simultanées est worker_processes * nombre_de_cpu.
Pour les services courants, il est aujourd'hui intéressant de passer par les containers Docker pour une mise en place simplifiée. Si vous avez une machine Docker vous pouvez faire simplement :
docker pull nginx
Cela va tirer l'image depuis le Docker Hub et la télécharger sur la machine Docker locale.
Pour exécuter Docker, faire simplement :
docker run -d -p 8080:80 --name nginx_rp nginx
Cette commande se décompose comme suit :
docker stop nginx_rp
Pour configurer Nginx en tant que Reverse Proxy, voici un exemple de fichier de configuration :
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://@ip-service-web:9000;
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_set_header X-Forwarded-Proto $scheme;
}
}
Les éléments du fichier de configuration sont les suivants :
Maintenant que la configuration existe, il faut la fournir à Nginx qui, je vous le rappelle, est un container Docker donc une zone sur laquelle nous n'avons que peu de moyens d'action. Pour cela on va ajouter un champ à la ligne d'appel de lancement du container Docker :
docker run -d -p 8080:80 --name nginx_rp -v /path/to/local/nginx.conf:/etc/nginx/nginx.conf:ro nginx
Remplacez le chemin /path/to/local/nginx.conf par le chemin dans lequel vous avez mis en place le fichier de configuration localement.
Il sera mappé sur le fichier situé après les ':' à savoir /etc/nginx/nginx.conf.
Pour connaître le chemin, interroge celui qui en vient.
Proverbe Chinois
Un des avantages certains des containers sur les VMs est que le container va démarrer beaucoup plus vite qu'une VM. Par exemple, pour installer docker simplement il suffirait (exemple tiré de Nginx Proxy Manager):
curl -sSL https://get.docker.com/ | sh
pour récupérer
le script d'installation de docker et de procéder à son installation automatiquementmkdir -p ~/docker/npm
)
puis faire un cd ~/docker/npm
. Créer ensuite un fichier docker-compose.ymlversion: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
# These ports are in format <host-port>:<container-port>
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '81:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
# Uncomment the next line if you uncomment anything in the section
# environment:
# Uncomment this if you want to change the location of
# the SQLite DB file within the container
# DB_SQLITE_FILE: "/data/database.sqlite"
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
docker compose up -d
qui va lire le fichier docker-compose.yml
précédemment créé.Maintenant il reste à routeur sur le firewall les ports 80 et 443 pour permettre l'accès depuis l'extérieur et permettre la mise en place de certificats Let's encrypt.. Sur pfSense, le port forwarding consiste en les règles suivantes :
Interface | Protocol | Source Address | Source Ports | Dest. Address | Dest. Ports | NAT IP | NAT Ports | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
WAN | TCP | * | * | WAN address | 80 (HTTP) | 192.168.x.y | 80 | nginx proxy manager | WAN | TCP | * | * | WAN address | 443 (HTTPS) | 192.168.x.y | 80 | nginx proxy manager |
Se connecter à nginx sur le port 81 et saisir le mot de passe par défaut changeme. Changez-le à la première connexion pour quelque chose de plus solide.
Pour exposer des services le plus simple est de créer une nouvelle entrée dans le DNS du domaine pour le service que vous souhaitez exposer. Un enregistrement A seul ou A + CNAME font l'affaire. Si plusieurs services sont à exposer, utiliser la même IP publique (A) pour toutes les déclarations de services.
Aller sur l'interface principale de nginx proxy manager et cliquer sur Proxy Hosts pour ajouter un nouveau service.
Sur l'onglet SSL, sélectionner Force SSL et I agree... et faire Save. Le certificat sera automatiquement généré tous les 90 jours depuis le site de Let's Encrypt et affecté au service exposé. Ainsi nous pouvons avoir un certificat légitime pour notre interface Proxmox sans trop de difficultés si nous définissons l'accès à la WebGUI de Proxmox depuis NGinx Proxy Manager...
Par défaut pfSense est capable de gérer des certificats mais si l'on souhaite utiliser nginx pour accéder à la webgui, il suffit :
Dans le langage Nginx, un stream peut être considéré comme une redirection de ports. Par exemple, si NPM est derrière un firewall et que tous les ports sont redirigés vers NPM, alors le reverse proxy peut se charger de rediriger n'importe lequel des ports vers le serveur mentionné. A la fois TCP et UDP sont pris en charge et ce type de fonctionnement peut permettre de sécuriser des accès comme les FTP par exemple.
Par défaut lorsqu'une connexion est établie avec la page d'accueil du proxy (son ip), celle-ci consiste en une page de félicitations. Il est important de remplacer cette page par autre chose. C'est le rôle de la page par défaut disponible dans Settings > Default Site. En faisant Edit nous allons pouvoir définir une page 404 ou une page sans réponse, voire une page custom (intéressant pour faire la pub de nos services par exemple).