Apache : reverse proxy
Un reverse proxy transmet les requêtes des visiteurs à une application qui écoute sur un port local. Il gère aussi HTTPS et la sécurité. Les exemples utilisent une application fictive sur 127.0.0.1:3000.
Activer les modules
Section intitulée « Activer les modules »sudo a2enmod proxy proxy_http headerssudo systemctl restart apache2| Module | Rôle |
|---|---|
proxy |
Cœur du proxy |
proxy_http |
Proxy HTTP et HTTPS |
proxy_wstunnel |
WebSockets |
proxy_balancer, lbmethod_byrequests |
Répartition de charge |
headers |
Modification des en-têtes |
remoteip |
Adresse réelle du client derrière un autre proxy |
Proxy simple
Section intitulée « Proxy simple »<VirtualHost *:80> ServerName app.exemple.com
ProxyRequests Off ProxyPreserveHost On ProxyPass / http://127.0.0.1:3000/ ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "http"</VirtualHost>| Directive | Rôle |
|---|---|
ProxyRequests Off |
Désactive le proxy direct (mandataire ouvert) : toujours à Off pour un reverse proxy |
ProxyPreserveHost On |
Transmet le Host demandé par le visiteur à l’application |
ProxyPass |
Transmet les requêtes du chemin vers l’application |
ProxyPassReverse |
Réécrit les redirections (Location) renvoyées par l’application |
RequestHeader set X-Forwarded-Proto |
Indique le protocole d’origine (https derrière TLS) |
Apache ajoute automatiquement X-Forwarded-For (adresse du visiteur), X-Forwarded-Host et X-Forwarded-Server.
Derrière HTTPS, remplacer l’en-tête par :
RequestHeader set X-Forwarded-Proto "https"La barre oblique finale
Section intitulée « La barre oblique finale »| Écriture | Requête /api/utilisateurs transmise comme |
|---|---|
ProxyPass /api/ http://127.0.0.1:4000/ |
/utilisateurs (le préfixe /api/ est retiré) |
ProxyPass /api/ http://127.0.0.1:4000/api/ |
/api/utilisateurs (chemin conservé) |
ProxyPass /api/ http://127.0.0.1:4000/ProxyPassReverse /api/ http://127.0.0.1:4000/Garder la même forme (avec ou sans / final) des deux côtés de ProxyPass.
Proxy d’un sous-chemin seulement
Section intitulée « Proxy d’un sous-chemin seulement »DocumentRoot /var/www/exemple.com
ProxyPass /api/ http://127.0.0.1:4000/ProxyPassReverse /api/ http://127.0.0.1:4000/ProxyPass /statique ! # exclu du proxy : servi par ApacheLes règles ProxyPass sont évaluées dans l’ordre d’écriture : placer les exceptions (!) avant les règles générales.
WebSockets
Section intitulée « WebSockets »sudo a2enmod proxy_wstunnel rewriteRewriteEngine OnRewriteCond %{HTTP:Upgrade} websocket [NC]RewriteCond %{HTTP:Connection} upgrade [NC]RewriteRule ^/ws/(.*)$ ws://127.0.0.1:3000/ws/$1 [P,L]
ProxyPass /ws/ http://127.0.0.1:3000/ws/ProxyPassReverse /ws/ http://127.0.0.1:3000/ws/Pour un chemin entièrement WebSocket, la forme courte suffit : ProxyPass "/ws/" "ws://127.0.0.1:3000/ws/".
Événements serveur (SSE) et flux
Section intitulée « Événements serveur (SSE) et flux »ProxyPass /evenements http://127.0.0.1:3000/evenements flushpackets=onflushpackets=on transmet les données dès leur réception, sans mise en mémoire tampon.
ProxyTimeout 60 # délai global d'attente de l'applicationProxyPass / http://127.0.0.1:3000/ timeout=120 connectiontimeout=5 retry=0LimitRequestBody 20971520 # taille maximale du corps de requête : 20 MoRépartition de charge
Section intitulée « Répartition de charge »sudo a2enmod proxy_balancer lbmethod_byrequests<Proxy "balancer://application"> BalancerMember http://127.0.0.1:3000 retry=30 BalancerMember http://127.0.0.1:3001 retry=30 BalancerMember http://127.0.0.1:3002 status=+H # de secours (« hot standby ») ProxySet lbmethod=byrequests</Proxy>
ProxyPass / balancer://application/ProxyPassReverse / balancer://application/Méthode (lbmethod) |
Comportement |
|---|---|
byrequests |
Répartition selon le nombre de requêtes (défaut) |
bytraffic |
Répartition selon le volume transféré (module lbmethod_bytraffic) |
bybusyness |
Vers le membre le moins occupé (module lbmethod_bybusyness) |
Un membre en échec est retiré pendant retry secondes.
Adresse réelle du visiteur derrière un autre proxy
Section intitulée « Adresse réelle du visiteur derrière un autre proxy »Si Apache est lui-même derrière un répartiteur de charge ou un CDN :
sudo a2enmod remoteipRemoteIPHeader X-Forwarded-ForRemoteIPInternalProxy 10.0.0.0/8Apache remplace alors l’adresse du client dans les journaux et les règles Require ip.
Transmettre une adresse HTTPS interne
Section intitulée « Transmettre une adresse HTTPS interne »SSLProxyEngine On # nécessite le module sslProxyPass / https://127.0.0.1:8443/ProxyPassReverse / https://127.0.0.1:8443/Éviter SSLProxyVerify none en production : il désactive la vérification du certificat de l’application.
curl -I http://app.exemple.com/curl -H "Host: app.exemple.com" http://127.0.0.1/sudo apache2ctl -Ssudo tail -f /var/log/apache2/error.logDépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
Invalid command 'ProxyPass' |
sudo a2enmod proxy proxy_http puis redémarrer |
503 Service Unavailable |
L’application est arrêtée ou injoignable : curl http://127.0.0.1:3000. Apache met le membre en erreur pendant retry secondes |
502 Bad Gateway |
L’application ferme la connexion ou répond de façon invalide |
504 Gateway Timeout |
Application trop lente : augmenter ProxyTimeout ou timeout= |
AH01114: HTTP: failed to make connection to backend |
Mauvais port ou application arrêtée |
Redirections vers http://127.0.0.1:3000/… |
ProxyPassReverse manquant ou différent de ProxyPass |
Liens générés en http:// |
Transmettre X-Forwarded-Proto et configurer l’application |
| WebSocket qui se coupe | proxy_wstunnel activé, règles RewriteRule … [P] et ProxyTimeout assez long |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Les directives de proxy sont identiques sur Apache 2.4.58 (24.04) et 2.4.66 (26.04).
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Documentation : Reverse Proxy Guide et
mod_proxy - Suite : HTTPS et certificats