Nginx : configuration en tant reverse proxy

Dans ce tutoriel dédié à Nginx, je vais vous expliquer comment le configurer afin d’avoir un reverse proxy.

Avant de rentrer dans le vif du sujet, je vais vous présenter rapidement Nginx et ce qu’un reverse proxy.

Pour ce tutoriel, j’ai utilisé une machine Ubuntu 20.04.

Présentation de Nginx

Nginx est un serveur Web comme Apache2 ou IIS qui a pour « philosophie » d’être léger et rapide. Il est disponible sur plusieurs système d’exploitation (Windows, Linux …).

Aujourd’hui, il existe deux versions :

  • Une version communautaire qui est libre et gratuite disponible ici : nginx.org
  • Une version commerciale qui inclut des fonctionnalités avancées de configuration, sécurité et d’administration disponible sur nginx.com.

Nginx permet « nativement » de mettre en place une solution de reverse proxy, à ses débuts Nginx était principalement utilisé pour ça.

Un reverse proxy c’est quoi ? et pourquoi en utiliser un ?

Un reverse proxy fonctionne de la même manière qu’un proxy en interne pour aller sur Internet, mais dans le sens inverse, c’est-à-dire qu’il capture la requête HTTP à destination du serveur Web internet et la traite lui-même.

L’utilisation d’un reverse proxy à plusieurs interets :

  • Économiser des adresses IP publiques : sur une même adresse IP publiques il est possible de publier plusieurs sites Internet hébergés sur un ou plusieurs serveurs en DMZ par exemple.
  • Optimiser les performances et réduire la charge des serveurs Web, le serveur proxy peut faire office de cache pour le nombre de requêtes au serveur qui héberge le site, pour des sites à fort trafic, on peut aussi l’utiliser en décharge SSL.
  • Faciliter la gestion des certificats SSL, en utilisant la décharge SSL et en gérant les certificats depuis le reverse proxy, il y a un seul serveur à gérer, ce qui permet de gagner du temps et éviter des oublies lors d’un renouvellement d’un certificat, surtout quand on utilise des wildcart (*.xxxxxxx.yy).
  • Sécurité, qui est aussi l’un des principaux avantages, car il permet de modifier l’entête HTTP en masquant le serveur derrière, coupler à l’utilisation de fail2ban ou crowsec, on peut protège l’ensemble des serveurs publiés. Il est aussi possible par les directives locations, de restreindre l’accès de certaines zones (/wp-admin pour WordPress, l’accès PowerShell pour Exchange …).
  • La répartition de charge, Nginx permet de faire du load-balancing.

Installation de Nginx

Pour d’avoir la version la plus récente de Nginx, il est possible de configurer dépôt nginx.org

Dans ce tutoriel, je vais utiliser le dépôt Ubuntu afin d’avoir le paquet nginx-extras, qui installe différents modules complémentaires que nous allons voir dans ce tutoriel.

Dans le dossier /etc/apt/sources.list.d/ créer un fichier nginx.list.

sudo touch /etc/apt/sources.list.d/nginx.list

Ensuite, éditer le fichier à l’aide de nano (ou autre).

sudo nano /etc/apt/sources.list.d/nginx.list

Ajouter les lignes ci-dessous dedans :

deb [arch=amd64] http://nginx.org/packages/mainline/ubuntu/ focal nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ focal nginx
Add nginx repo

Maintenant, exécuter les 2 lignes ci-après pour installer la signature du dépôt :

wget http://nginx.org/keys/nginx_signing.key 
sudo apt-key add nginx_signing.key

Mettre à jour la ligne des paquets :

sudo apt update
update repository

Sur la capture ci-dessus, on voit que les dépôts Nginx ont été interrogés.

On peut maintenant passer à l’installer de Nginx.

Entrer la commande ci-dessous pour installer Nginx

sudo apt install nginx nginx-extras
Install nginx and extra for reverse proxy

L’installation terminée, vérifier le bon fonctionnement de Nginx :

sudo systemctl status nginx

Il est aussi possible depuis un navigateur d’aller sur l’adresse : http://server-ip. La page Welcome Nginx doit s’affichée.

En complément, il est aussi possible d’installer certbot pour Nginx pour générer des certificats Let’s Encrypt.

sudo apt install python3-certbot-nginx

Notre serveur est maintenant prêt, on va pouvoir passer à la configuration de nos différents virtualhost en reverse proxy.

Configuration de Nginx en reverse proxy

Comme vous l’avez certainement déjà compris, le but ici, n’est pas d’utiliser les fonctionnalités de reverse proxy de Nginx pour servir des sites qui seraient hébergés sur le serveur lui-même à l’aide de conteneur où d’un autre serveur Web (Apache, Tomcat …) mais de servir des sites (applications) qui sont hébergés sur d’autre serveur.

Dans certain cas, on peut avoir une problématique d’enregistrement DNS, notamment quand le serveur qui se trouve après le proxy utilisent des virtualhosts et qu’un enregistrement existe et qu’il va pointer par la suite sur le reverse proxy, on retrouve cette configuration principalement quand le reverse proxy doit résoudre l’url et que celle-ci pointe dessus.

Pour résoudre ce problème, nous allons mettre en dur sur le serveur proxy dans le fichier /etc/hosts la bonne résolution, afin d’arriver à ce résultat :

Pour ajouter un enregistrement ouvrir le fichier avec nano (ou autre).

sudo nano /etc/hosts

Ensuite ajouter l’enregistrement sous le format :

ip_adr dns_record

Maintenant que cette problématique est traitée, nous allons voir comment mettre en place notre reverse proxy avec Nginx.

Reverse proxy Nginx : configuration « standard »

Pour illustrer ce premier tutoriel, on va envoyer le trafic vers un serveur IIS simple, on va utiliser le nom DNS rproxy.rdr-it.io

Créer un fichier configuration pour le virtualhost

sudo touch /etc/nginx/sites-available/rproxy-rdr-it-io

Ouvrir le fichier que l’on vient de créer :

sudo nano /etc/nginx/sites-available/rproxy-rdr-it-io

Coller la configuration ci-dessous (chaque ligne est commenté) :

Il faut maintenant ajouter un lien symbolique pour rendre notre configuration active :

sudo ln -s /etc/nginx/sites-available/rproxy-rdr-it-io /etc/nginx/sites-enabled

Tester la configuration de Nginx :

sudo nginx -t

Si tout est OK, recharger la configuration :

sudo systemctl reload nginx

C’est le moment de tester, avant il faut s’assurer que votre enregistrement dns (url) pointe bien sur le reverse proxy. 😉

Depuis un navigateur, j’ai bien la page IIS de mon serveur qui s’affiche :

On peut aussi voir le trafic dans les logs (access.log) Nginx.

Avant de passer à l’étape suivante, je vous propose une petite amélioration de notre virtualhost, on va séparer les logs access dans un fichier à part en ajoutant le code suivant :

access_log /var/log/nginx/rproxy-rdr-it-io_access.log;

Ce qui donne dans le fichier de virtualhost :

Recharger ensuite la configuration Nginx.

Le fichier de log est présent sur le serveur, effectuer une requête pour si tout fonctionne.

Vous savez maintenant comment mettre en place virtualhost en mode reverse proxy avec Nginx.

Reverse proxy Nginx : configuration réécriture / substitution

On va maintenant passer à une configuration où nous allons réécrire le code HTML qui est retourné au navigateur.

Cette modification est possible avec le module : Module HTTP Subs Filter.

Ce type de configuration est utilisé régulièrement quand on publie des applications en interne et en externe (sur Internet) et que l’application est configurée avec une URL interne et donc inaccessible depuis Internet. On utilise aussi ce module pour changer le port de publication d’une application, par exemple certaine application (Tomcat) utilise le port 8080, la réécriture permet de publier le service sur un port standard 80/443.

Pour vérifier si le module est présent, afficher le contenu du dossier /etc/nginx/modules-enabled/ et vérifier que le lien symbolique 50-mod-http-subs-filter.conf est présent.

Je ne vais pas reprendre la création du virtualhost, celle-ci a été abordée avant.

Dans cette partie, je vais vous montrer deux exemples :

  • Un simple sur du code HTML
  • Le second sur WordPress

Exemple 1

Pour ce premier exemple, on va tester avec une réécriture (substitution) simple dans un fichier HTML (index.html).

Comme on peut le voir sur la capture ci-dessous, on va travailler sur le domaine rdr-it.lan qui est disponible seulement depuis un réseau privé et on souhaite maintenant le publié sur Internet en rdr-it.fr.

Voici le fichier index.html :

On peut voir que l’url rdr-it.lan est écrite en dur deux fois.

Ci-dessous, les fichiers (index.html et image) :

Voici le résultat depuis un accès en interne.

Je vais maintenant, vous montrer la configuration qui va permettre de modifier rdr-it.lan en rdr-it.fr afin de pouvoir publier le site sur Internet.

Voici le fichier de configuration du virtualhost :

Une fois la configuration ajoutée, créer le lien symbolique, vérifier la configuration et recharger la configuration de Nginx.

Depuis un navigateur, aller sur l’url accessible depuis Internet, normalement tout doit s’afficher correctement.

On peut voir ci-dessous, que le code a bien été réécrit avec la bonne url.

Exemple 2

Dans ce second exemple pour la réécriture de contenu HTML, je vais le faire avec un site WordPress, comme on va le voir après, la configuration du virtualhost est un peu plus compliquée et on utilise du RegEx pour modifier le contenu.

Sur les captures ci-dessous, un aperçu du site WordPress :

Créer le fichier du virtualhost et copier la configuration ci-dessous en adaptant à votre configuration.

Voici quelques captures :

  • Administration WordPres où l’on peut voir que l’url (config) est changé dynamiquement
  • Configuration dans la base de donnée avec l’url orginal : wp.rdr-it.lan
  • Capture de la requete HTTP où l’on peut voir que l’on passe par Nginx et non LiteSpeed
  • Un aperçu des logs

Reverse proxy avec répartition de charge

Pour finir ce tutoriel, je vais vous présenter une configuration de reverse proxy Nginx avec du load balancing..

Dans la déclaration des serveurs dans le block upstream, il est possible d’indiquer un point (préférence) ,

upstream ServersWebPool{
    # Declare each server
    server srv-web-01 weight=3;
    server srv-web-02;
}

Dans l’exemple ci-dessus, pour 4 requêtes HTTP, 3 requêtes vont aller sur srv-web-01 et une requête sur srv-web-02.

Dernier élément que l’on peut configurer est la disponibilité du service :

upstream ServersWebPool{
    # Declare each server
    server srv-web-01 max_fails=3 fail_timeout=60s;
    server srv-web-02;
}

Dans l’exemple ci-dessus, après 3 échecs sur le serveur srv-web-01, celui-ci sera considéré comme indisponible pendant 60 secondes

Par défaut la valeur max_fails est égale à 1 et fail_timeout à 10 sec.


Vous savez maintenant comment configurer Nginx en tant que reverse proxy et réécrire (substituer) le contenu HTML pour le faire correspondre à l’URL de requête dans le cas où le code HTML n’utilise pas des liens absolus.



Start the discussion at community.rdr-it.io