Cet article détaille la configuration d’Apache en tant que reverse proxy pour une application web interne sécurisée. Ce processus implique plusieurs étapes pour garantir une communication fluide et sécurisée entre les clients et le serveur backend.
Table of Contents
Contexte
L’application web interne est hébergée sur un serveur backend avec une adresse IP interne. L’objectif est de configurer Apache pour servir de reverse proxy, permettant aux utilisateurs d’accéder à l’application via une URL publique sécurisée.
Qu’est-ce qu’un Reverse Proxy ?
Un reverse proxy agit comme un intermédiaire entre les clients (utilisateurs) et les serveurs backend. Il reçoit les requêtes des clients et les transmet aux serveurs appropriés. Le reverse proxy permet de masquer les adresses IP des serveurs backend et, éventuellement, de répartir la charge de trafic, et d’appliquer des politiques de sécurité. C’est un élément standard pour la sécurisation d’une application, on peut, par ailleurs, imaginer implémenter un WAF (comme mod_security) pour sécuriser le plus possible les requêtes afin d’éviter toute compromission du serveur finale.
Schéma Explicatif
[ Utilisateur ] <--> [ Reverse Proxy (Apache) - https://monapp.mondomaine.com (192.168.1.10:443) ] <--> [ Serveur Backend (https://192.168.1.20:8443) ]
Configuration Détailée du Reverse Proxy
192.168.1.10 est l’adresse IP interne du reverse proxy.
Configuration du VirtualHost
<VirtualHost 192.168.1.10:443>
ServerName monapp.mondomaine.com
## Racine du vhost
DocumentRoot "/var/www/html"
## Répertoires
<Directory "/var/www/html">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
## Journaux
ErrorLog "/var/log/httpd/monapp_error_ssl.log"
ServerSignature Off
CustomLog "/var/log/httpd/monapp_access_ssl.log" combined
## Règles d'en-têtes de requêtes
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
RequestHeader set X-Forwarded-Proto "https"
## Directives de proxy SSL
SSLProxyEngine On # Active le moteur de proxy SSL pour gérer les connexions HTTPS
SSLProxyVerify none # Désactive la vérification des certificats SSL du serveur en amont
SSLProxyCheckPeerCN off # Désactive la vérification du nom commun (CN) du certificat SSL
SSLProxyCheckPeerName off # Désactive la vérification du nom du certificat SSL
## Règles de proxy
ProxyRequests Off
ProxyPreserveHost Off
## Détecter les requêtes XHR et définir une variable d'environnement
SetEnvIf X-Requested-With "XMLHttpRequest" xhr_request
## Définir l'en-tête Host vers le serveur upstream uniquement pour les requêtes XHR
RequestHeader set Host 192.168.1.20 env=xhr_request
## Directives Proxy Pass
ProxyPass / https://192.168.1.20:8443/
ProxyPassReverse / https://192.168.1.20:8443/
## Directives SSL
SSLEngine on # Active le moteur SSL pour ce virtual host
SSLCertificateFile "/etc/ssl/mescertificats/mondomaine.com.crt" # Chemin vers le fichier du certificat SSL
SSLCertificateKeyFile "/etc/ssl/mescertificats/mondomaine.com.key" # Chemin vers la clé privée SSL
SSLCertificateChainFile "/etc/ssl/mescertificats/mondomaine.com.crt" # Chemin vers le fichier de la chaîne de certificats SSL
## Activer le moteur de réécriture
RewriteEngine on
# Support WebSocket
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) wss://192.168.1.20:8443/$1 [P,L]
# Appliquer un filtre de substitution pour divers types MIME
<Location />
SubstituteMaxLineLength 10M
AddOutputFilterByType SUBSTITUTE text/html text/css text/javascript application/javascript application/json
Substitute "s|https://192.168.1.20:8443|https://monapp.mondomaine.com|ni"
# Autoriser toutes les méthodes HTTP
<Limit GET POST PUT DELETE PATCH OPTIONS>
Require all granted
</Limit>
</Location>
# Paramètres de proxy inverse
ProxyPassReverseCookieDomain 192.168.1.20 monapp.mondomaine.com
ProxyPassReverseCookiePath / /
</VirtualHost>
Explications des Directives
- ProxyRequests Off : Désactive la fonctionnalité de proxy ouvert, assurant qu’Apache n’est pas utilisé comme un proxy direct par des clients externes.
- ProxyPreserveHost Off : Désactive la préservation de l’en-tête
Host
d’origine, permettant au serveur backend de traiter correctement les requêtes authentifiées. - RequestHeader set Host 192.168.1.20 env=xhr_request : Modifie l’en-tête
Host
uniquement pour les requêtes XHR, ce qui permet de « duper » l’application finale en lui faisant croire que les requêtes proviennent directement de l’IP interne 192.168.1.20. - SSLProxyEngine On et SSLProxyVerify none : Activent le proxy SSL et désactivent la vérification des certificats, étant donné que le certificat du serveur final est autosigné, pour les connexions HTTPS.
- ProxyPass / https://192.168.1.20:8443/ et ProxyPassReverse / https://192.168.1.20:8443/ : Configurent le routage des requêtes vers le serveur backend.
- RewriteCond et RewriteRule : Gèrent les connexions WebSocket.
- Substitute : Réécrit les URLs dans les réponses pour assurer que les liens et les ressources utilisent l’URL publique.
- ProxyPassReverseCookieDomain et ProxyPassReverseCookiePath : Réécrivent les cookies pour qu’ils soient corrects du point de vue des clients.
Tester la Configuration
Pour tester la configuration, utilisez curl
pour simuler des requêtes et vérifier les réponses :
curl -k -v -X PUT "https://monapp.mondomaine.com/api/test" \
-H "Accept: application/json, text/plain, */*" \
-H "Content-Type: application/json" \
-H "Cookie: JSESSIONID=example_cookie; XSRF-TOKEN=example_token" \
-H "X-Requested-With: XMLHttpRequest" \
-d '{"key":"value"}'
Résultats
Après l’application de cette configuration finale et le redémarrage d’Apache, les requêtes étaient correctement routées via le reverse proxy, et les réponses du serveur backend étaient manipulées comme prévu.
Conclusion
La configuration d’Apache en tant que reverse proxy pour une application web sécurisée nécessite une attention particulière aux en-têtes HTTP, à la gestion des cookies, et aux règles de réécriture. Ce processus implique souvent plusieurs essais et ajustements afin d’obtenir une configuration stable et fonctionnelle, surtout quand l’application n’a pas été prévue pour ce type d’usage.