Aujourd’hui nous allons voir comment utiliser Nginx comme un reverse proxy pour fonctionner avec Apache2. Nous allons commencer par une explication de ce qu’est un reverse proxy
Un proxy inverse (reverse proxy) ou serveur mandataire inverse est un type de serveur, habituellement placé en frontal de serveurs web. Contrairement au serveur proxy qui permet à un utilisateur d’accéder au réseau Internet, le proxy inverse permet à un utilisateur d’Internet d’accéder à des serveurs internes. Une des applications courantes du proxy inverse est la répartition de charge (load-balancing).
Wikipedia
En image, ça donne ça :
Quand vous appelez une ressource, Nginx répond et envoie la requête à Apache pour qu’elle soit traitée.
Pour quoi faire me direz vous ? L’idée c’est de faire en sorte que Nginx se charge des ressources statiques, images, JavaScript, polices etc. et qu’Apache se charge d’interpréter le PHP. Car il se trouve que si Apache et Nginx sont plus ou moins à égalité pour l’interprétation du PHP, Nginx est beaucoup plus efficace pour les ressources statiques. Il y a tout un tas d’explications à ce sujet que nous n’allons pas voir ici. Même si vous avez un petit site, l’utilisation de Nginx en reverse proxy vous aidera à gagner en performances.
Installation de PHP 8.2
On va commencer par ajouter le repo afin de pouvoir installer PHP comme dans un précédent article
Note : Sur Debian 12 le package PHP est déjà à la version 8.2, vous pouvez donc passer à l’installation directement
sudo apt install apt-transport-https lsb-release ca-certificates curl wget -y sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' sudo apt update
On installe PHP
sudo apt install php8.2-{mysql,cli,common,imap,ldap,xml,fpm,curl,mbstring,zip}
On peut maintenant passer à Apache
Installation du serveur Apache2
On installe Apache2 et on active php-fpm comme dans l’article pour l’installation de LAMP
sudo apt install apache2-bin libapache2-mod-php8.2 sudo a2dismod php8.2 sudo a2enconf php8.2-fpm sudo a2enmod proxy_fcgi sudo systemctl restart apache2
Nous allons vérifier que PHP est bien interprété
sudo nano /var/www/html/info.php
Collez le code suivant dans le fichier et enregistrez
<?php phpinfo(); ?>
Dans votre navigateur, rendez vous sur
http://votre_ip/info.php
Vous devriez voir cette page :
Maintenant que tout est bon pour PHP, nous allons configurer Apache2
Configuration d’Apache2
Nous commençons par changer le port d’écoute d’Apache. Pour ce faire, nous devons éditer le fichier ports.conf
sudo nano /etc/apache2/ports.conf
Supprimez les autres lignes pour que votre fichier ressemble à celui-ci
# If you just change the port or add more ports here, you will likely also # have to change the VirtualHost statement in # /etc/apache2/sites-enabled/000-default.conf Listen 8080 # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
sudo systemctl restart apache2
On vérifie que Apache écoute bien le port 8080 et non pas le 80, qui sera utilisé par Nginx
sudo netstat -tulpn | grep apache
Remarque, vous pouvez utiliser ss à la place de netstat
Nous voyons qu’Apache écoute bien sur le port 8080.
On finit en activant le mod_remoteip qui nous servira plus tard à récupérer l’adresse IP qui appelle notre serveur. Sans ce mod, l’adresse IP affichée sera 127.0.0.1
sudo a2enmod remoteip sudo systemctl restart apache2
Installation et configuration de mod_rpaf
Dans cette étape, nous allons installer un module Apache appelé mod_rpaf qui réécrit les valeurs de REMOTE_ADDR, HTTPS et HTTP_PORT en fonction des valeurs fournies par le reverse proxy. Sans ce module, certaines applications PHP nécessiteraient des modifications de code pour fonctionner de manière transparente derrière un proxy. Ce module est présent dans libapache2-mod-rpaf mais il est obsolète et ne supporte pas certaines directives de configuration. Nous allons donc l’installer à partir des sources.
Installez les paquets nécessaires pour construire le module :
sudo apt install unzip build-essential apache2-dev
On télécharge la dernière version depuis Github
wget https://github.com/gnif/mod_rpaf/archive/stable.zip
On extrait les données
unzip stable.zip
On va dans le dossier, on compile et on installe
cd mod_rpaf-stable make sudo make install
On va maintenant créer un fichier dans mods-available
pour charger le module rpaf
sudo nano /etc/apache2/mods-available/rpaf.load
On ajoute ce code pour charger le module
LoadModule rpaf_module /usr/lib/apache2/modules/mod_rpaf.so
On sauvegarde puis on crée un autre fichier, qui contiendra la configuration pour mod_rpaf
sudo nano /etc/apache2/mods-available/rpaf.conf
On ajoute maintenant la configuration
<IfModule mod_rpaf.c> RPAF_Enable On RPAF_Header X-Real-Ip RPAF_ProxyIPs votre_serveur_ip RPAF_SetHostName On RPAF_SetHTTPS On RPAF_SetPort On </IfModule>
On active le module puis on vérifie que la configuration est bonne
sudo a2enmod rpaf sudo apachectl -t
Si tout est bon, on redémarre Apache
sudo systemctl restart apache2
Installation du serveur Nginx
Comme vu dans l’article sur l’installation de Nginx il y a plusieurs versions disponibles. Toutes les versions mis à part la version light prennent en charge la fonction proxy. Choisissez la version que vous voulez, puis installez-la
sudo apt install nginx
On peut vérifier si les ports 80 et 8080 sont bien écoutés respectivement par Nginx et Apache
sudo netstat -tulpn | grep 80
C’est tout bon pour l’installation !
Configuration du virtualhost Nginx
Maintenant que notre Nginx est installé, nous allons créer un virtualhost
sudo nano /etc/nginx/sites-available/vhost-test
Collez le code suivant
server { listen 80; server_name votre_ip; location / { proxy_pass http://127.0.0.1:8080; 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; } }
sudo ln -s /etc/nginx/sites-available/vhost-test /etc/nginx/sites-enabled/vhost-test sudo systemctl restart nginx
Avec cette configuration, location est configurée sur / ce qui indique à Nginx, que vous transmettez toute la requête à Apache.
L’élément important dans ce code est proxy_pass http://127.0.0.1:8080 c’est ce paramètre qui indique à Nginx qu’il doit rediriger la requête ailleurs.
Configuration du virtualhost d’Apache
Nous allons maintenant faire la même chose avec Apache, à la différence que Apache va recevoir et traiter la requête.
sudo a2dissite 000-default.conf sudo nano /etc/apache2/sites-available/vhost-test-apache.apache.conf
Ajoutez le code suivant
<VirtualHost *:8080> ServerName localhost DocumentRoot /var/www/html <Directory /var/www/html> AllowOverride All </Directory> </VirtualHost>
sudo a2ensite vhost-test-apache.apache.conf sudo systemctl restart apache2
Vous remarquerez que le port d’écoute est défini sur 8080. L’instruction AllowOverride All permet à Apache de prendre en compte le fichier .htaccess.
Test de notre configuration de Nginx en reverse_proxy pour Apache
Comme plus tôt dans ce tutoriel, nous allons aller sur notre navigateur et appeler le fichier info.php
http://votre_ip/info.php
Une requête HTTP se fait sur le port 80, c’est donc Nginx qui va y répondre. Nous allons vérifier que c’est bien Apache qui va traiter le PHP. Si vous avez bien suivis le tuto, vous devriez voir que oui !
Félicitations vous avez mis en place votre reverse proxy !
NB : vous pouvez voir à la ligne $_SERVER[‘REMOTE_ADDR’] que l’adresse IP indiquée est 127.0.0.1 car c’est l’adresse qui a envoyé la requête à Apache. Si vous souhaitez voir la vraie IP qui appelle les ressources, ajoutez ces 2 lignes après avoir activé le mode :
a2enmod remoteip
RemoteIPHeader X-Real-IP RemoteIPInternalProxy 127.0.0.1
Ce qui nous donne
<VirtualHost *:8080> ServerName localhost DocumentRoot /var/www/html RemoteIPHeader X-Real-IP RemoteIPInternalProxy 127.0.0.1 <Directory /var/www/html> AllowOverride All </Directory> </VirtualHost>
Faire servir les fichiers statiques par Nginx et le PHP par Apache
Actuellement notre serveur Nginx retransmet toutes les données qu’il reçoit à Apache. L’idée maintenant c’est de faire en sorte qu’il serve le contenu statique, images, JS, CSS etc. et que le PHP passe par Apache. Pour ce faire, nous allons éditer le virtualhost de Nginx
sudo nano /etc/nginx/sites-available/vhost-test
On va modifier notre fichier pour qu’il ressemble à ça :
server { listen 80; server_name votre_ip; root /var/www/html; index index.html index.php index.htm; location / { try_files $uri $uri/ =404; } location ~ \.php$ { proxy_pass http://127.0.0.1:8080; 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; } location ~ /\.ht { deny all; } }
sudo systemctl restart nginx
Nous venons d’indiquer plusieurs choses à Nginx :
root - Indique l’emplacement du dossier racine du site. Là où Nginx pourra récupérer les fichiers de notre site.
index - Le fichier a lire en priorité (index.html, index.php etc)
Vous avez remarqué de location a changé dans cette version de notre virtualhost. En fait, nous indiquons que tous les fichiers finissant par .php doivent être traités dans ce block. En l’occurrence pour l’envoyer à Apache.
La directive location ~ /.ht est très importante, elle empêche Nginx de servir le contenu des fichiers de configuration d’Apache comme .htaccess et .htpasswd qui contiennent des informations sensibles.
Le reverse_proxy en quelques mots
Nous avons vu qu’utiliser Nginx comme reverse_proxy comporte de nombreux avantages pour les gros sites comme pour les petits. L’inconvénient principal étant qu’il faut multiplier les virtualhost lorsque l’on ajoute de nouveaux sites. Dans ce tuto nous nous sommes limités au reverse proxy avec les fichiers PHP en localhost, mais Nginx offre de nombreuses possibilités, comme être un load balancer ou un serveur de cache.
N’hésitez pas à réagir en commentaire, je reviens bientôt avec de nouveau tuto !