Apache httpd : Configuration en mode Reverse Proxy
Table des matières
Sur mes serveurs, lorsque j'ai besoin d'un serveur web, j'utilise apache httpd.
Ce serveur web sait également faire du reverse proxy, et il le fait très bien.
Bien qu'il existe d'autres solutions de Reverse Proxy (Nginx, Caddy, Traefik, ...) cet article décrit la mise en place d'un reverse proxy avec Apache.
Il faudra dans un premier temps s'assurer que les modules proxy sont actifs sur le système.
Sous RHEL (et dérivés) ou Fedora, les modules sont automatiquement chargés.
On peut le vérifier dans le fichier /etc/httpd/conf.modules.d/00-proxy.conf :
Il n'y a donc rien à faire.
Sous Debian ou Ubuntu, il faut activer le module avec la commande suivante (qui activera le module proxy aussi) :
Recharger la config apache.
Sous Gentoo, on positionnera les USE suivants dans /etc/portage/package.use/apache par exemple :
Et dans /etc/conf.d/apache, on rajoute -D PROXY :
Recharger la config apache.
Voici une config "simple" de Reverse Proxy en HTTP :
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
Define PROXY_URL : Vu qu'on utilise 2 fois la valeur, je la mets dans une variable
ProxyPass : Redirection des requêtes vers le backend spécifié (limite de 1000 connexions simultanées)
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Si on veut que le Reverse Proxy soit en HTTPS uniquement, et rediriger une requête HTTP en HTTPS, le VirtualHost sera une simple redirection vers HTTPS classique :
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
RewriteEngine : Activation du mode Rewrite
RewriteCond : On reste en HTTP dans le cas d'une requête Lets Encrypt
RewriteRule : On redirige tout vers HTTPS
Dans le cas d'un certificat Let's encrypt, on aura besoin de :
DocumentRoot : Racine du site nécessaire pour un échange avec Let's Encrypt (si certificats interne, pas besoin)
Bloc Directory : Pour autoriser l'accès à ce dossier pour consulter l'échange Let's encrypt
Il faudra configurer un Virtualhost en HTTPS sur ce même serveur, qui portera la fonction de Reverse Proxy (voir juste en dessous)
Voici une config "simple" de Reverse Proxy en HTTPS :
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
SSLProxyEngine : Activation du SSL
SSLCertificateFile et SSLCertificateKeyFile : Certificat et clé SSL/TLS
Define PROXY_URL : Vu qu'on utilise 2 fois la valeur, je la mets dans une variable
SSLProxyCheckPeerCN : (Facultatif) Désactive la vérification du CN sur le certificat du backend. Utile si on laisse un autosigné.
SSLProxyCheckPeerName : (Facultatif) Désactive la vérification du nom d'hôte sur le certificat du backend. Utile si on laisse un autosigné.
SSLProxyCheckPeerExpire : (Facultatif) Désactive la vérification de la date d'expiration sur le certificat du backend. Utile si on laisse un autosigné.
ProxyRequests : Désactive la fonction de proxy ouvert (sécurité)
ProxyPreserveHost : Préserve l'entête Host de la requête d'origine.
RequestHeader set X-Forwarded-For : Ajoute l'en-tête X-Forwarded-For à la requête envoyée au serveur backend. (Garde l'IP du client d'origine)
RequestHeader set X-Forwarded-Proto : Ajoute l'en-tête X-Forwarded-Proto à la requête envoyée au serveur backend. (Garde le protocole du client d'origine)
ProxyPass : Redirection des requêtes vers le backend spécifié (limite de 1000 connexions simultanées)
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Voici une config de Reverse Proxy en HTTPS avec du LoadBalancing sur 2 noeuds :
On est donc sur un bloc VirtualHost traditionnel avec les mêmes éléments que ci dessus avec en plus :
Header add Set-Cookie : Ajout d'un cookie pour les sessions persistantes (rester sur le même noeud)
<Proxy balancer://pilinuxtricks> : Section dédiée au Load Balancing, appelé pilinuxtricks
BalancerMember : Membres du pool du load balancer (route=XXX où XXX est un identifiant différent pour les sessions persistantes)
ProxySet lbmethod=bybusyness timeout=1 : Load Balancing par occupation du serveur, considérer HS si timeout de plus d'1 seconde
ProxySet stickysession=ROUTEID : Session persistante suivant le cookie nommé ROUTEID défini précédemment
ProxyPass : Redirection des requêtes vers le pool spécifié
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Quand on utilise du loadbalancing, on peut avoir des stats avec l'outil balancer-manager.
Pour cela, dans le VirtualHost, on ajoutera ceci :
On est donc sur un bloc VirtualHost traditionnel avec les mêmes éléments que ci dessus avec en plus :
ProxyPass /lbstats ! : On ne redirige pas cette URI vers le pool si elle est demandée (c'est le Reverse Proxy qui porte les stats)
<Location "/lbstats"> : Directive associée à cette URI
SetHandler balancer-manager : On affiche le gestionnaire du load balancer
Require ip 192.168.21.0/24 : On filtre sur un réseau sûr
Le gestionnaire affiche ceci et permet de gérer les noeuds (les mettre hors ligne par exemple) :
Pour mettre proxmox derrière un Reverse Proxy, vu qu'il y a du Websocket, je vous renvoie vers cet article : https://www.linuxtricks.fr/wiki/wiki.php?title=proxmox-derriere-le-reverse-proxy-apache-httpd
Introduction
Sur mes serveurs, lorsque j'ai besoin d'un serveur web, j'utilise apache httpd.
Ce serveur web sait également faire du reverse proxy, et il le fait très bien.
Bien qu'il existe d'autres solutions de Reverse Proxy (Nginx, Caddy, Traefik, ...) cet article décrit la mise en place d'un reverse proxy avec Apache.
Prérequis
Il faudra dans un premier temps s'assurer que les modules proxy sont actifs sur le système.
Fedora, RHEL et dérivés
Sous RHEL (et dérivés) ou Fedora, les modules sont automatiquement chargés.
On peut le vérifier dans le fichier /etc/httpd/conf.modules.d/00-proxy.conf :
Code TEXT :
LoadModule proxy_module modules/mod_proxy.so LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_express_module modules/mod_proxy_express.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so LoadModule proxy_scgi_module modules/mod_proxy_scgi.so LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
Il n'y a donc rien à faire.
Debian, Ubuntu et dérivés
Sous Debian ou Ubuntu, il faut activer le module avec la commande suivante (qui activera le module proxy aussi) :
Code BASH :
a2enmod proxy_http
Recharger la config apache.
Gentoo
Sous Gentoo, on positionnera les USE suivants dans /etc/portage/package.use/apache par exemple :
Code TEXT :
www-servers/apache apache2_modules_proxy apache2_modules_proxy_connect apache2_modules_proxy_http apache2_modules_proxy_http2 apache2_modules_proxy_wstunnel apache2_modules_remoteip apache2_modules_proxy_balancer apache2_modules_lbmethod_bybusyness apache2_modules_slotmem_shm apache2_modules_lbmethod_byrequests apache2_modules_lbmethod_bytraffic apache2_modules_lbmethod_heartbeat apache2_modules_session session_cookie
Et dans /etc/conf.d/apache, on rajoute -D PROXY :
Code BASH :
APACHE2_OPTS="-D DEFAULT_VHOST -D INFO -D SSL -D SSL_DEFAULT_VHOST -D LANGUAGE -D PHP -D PROXY"
Recharger la config apache.
Reverse Proxy HTTP
Simple reverse proxy HTTP
Voici une config "simple" de Reverse Proxy en HTTP :
Code TEXT :
<VirtualHost *:80> ServerName pi.linuxtricks.fr ErrorLog /var/log/apache2/pi.linuxtricks.fr-error_log TransferLog /var/log/apache2/pi.linuxtricks.fr-access_log ServerSignature Off Define PROXY_URL 192.168.21.244 ProxyRequests off ProxyPreserveHost on RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s RequestHeader set X-Forwarded-Proto %{HTTPS}s ProxyPass / http://${PROXY_URL}/ max=1000 ProxyPassReverse / http://${PROXY_URL}/ </VirtualHost>
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
Define PROXY_URL : Vu qu'on utilise 2 fois la valeur, je la mets dans une variable
ProxyPass : Redirection des requêtes vers le backend spécifié (limite de 1000 connexions simultanées)
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Redirection vers HTTPS
Si on veut que le Reverse Proxy soit en HTTPS uniquement, et rediriger une requête HTTP en HTTPS, le VirtualHost sera une simple redirection vers HTTPS classique :
Code TEXT :
<VirtualHost *:80> ServerName pi.linuxtricks.fr DocumentRoot /var/www/localhost/htdocs/pi ErrorLog /var/log/apache2/pi.linuxtricks.fr-error_log TransferLog /var/log/apache2/pi.linuxtricks.fr-access_log ServerSignature Off RewriteEngine on RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/ RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] <Directory /var/www/localhost/htdocs/pi> Require all granted </Directory> </VirtualHost>
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
RewriteEngine : Activation du mode Rewrite
RewriteCond : On reste en HTTP dans le cas d'une requête Lets Encrypt
RewriteRule : On redirige tout vers HTTPS
Dans le cas d'un certificat Let's encrypt, on aura besoin de :
DocumentRoot : Racine du site nécessaire pour un échange avec Let's Encrypt (si certificats interne, pas besoin)
Bloc Directory : Pour autoriser l'accès à ce dossier pour consulter l'échange Let's encrypt
Il faudra configurer un Virtualhost en HTTPS sur ce même serveur, qui portera la fonction de Reverse Proxy (voir juste en dessous)
Reverse Proxy HTTPS
Simple reverse proxy HTTPS
Voici une config "simple" de Reverse Proxy en HTTPS :
Code TEXT :
<VirtualHost *:443> ServerName pi.linuxtricks.fr ErrorLog /var/log/apache2/pi.linuxtricks.fr-error_log TransferLog /var/log/apache2/pi.linuxtricks.fr-access_log ServerSignature Off SSLProxyEngine on SSLCertificateFile /etc/letsencrypt/live/pi.linuxtricks.fr/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/pi.linuxtricks.fr/privkey.pem Define PROXY_URL 192.168.21.244 SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off ProxyRequests off ProxyPreserveHost on RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s RequestHeader set X-Forwarded-Proto %{HTTPS}s ProxyPass / https://${PROXY_URL}/ max=1000 ProxyPassReverse / https://${PROXY_URL}/ </VirtualHost>
On est donc sur un bloc VirtualHost traditionnel avec :
ServerName : Le nom de domaine qui répond à la requête
ErrorLog : Fichier de logs des erreurs (au cas où)
TransferLog : Fichier de logs des accès
ServerSignature : Déactivation de la signature du serveur
SSLProxyEngine : Activation du SSL
SSLCertificateFile et SSLCertificateKeyFile : Certificat et clé SSL/TLS
Define PROXY_URL : Vu qu'on utilise 2 fois la valeur, je la mets dans une variable
SSLProxyCheckPeerCN : (Facultatif) Désactive la vérification du CN sur le certificat du backend. Utile si on laisse un autosigné.
SSLProxyCheckPeerName : (Facultatif) Désactive la vérification du nom d'hôte sur le certificat du backend. Utile si on laisse un autosigné.
SSLProxyCheckPeerExpire : (Facultatif) Désactive la vérification de la date d'expiration sur le certificat du backend. Utile si on laisse un autosigné.
ProxyRequests : Désactive la fonction de proxy ouvert (sécurité)
ProxyPreserveHost : Préserve l'entête Host de la requête d'origine.
RequestHeader set X-Forwarded-For : Ajoute l'en-tête X-Forwarded-For à la requête envoyée au serveur backend. (Garde l'IP du client d'origine)
RequestHeader set X-Forwarded-Proto : Ajoute l'en-tête X-Forwarded-Proto à la requête envoyée au serveur backend. (Garde le protocole du client d'origine)
ProxyPass : Redirection des requêtes vers le backend spécifié (limite de 1000 connexions simultanées)
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Reverse proxy HTTPS avec load balancing
Voici une config de Reverse Proxy en HTTPS avec du LoadBalancing sur 2 noeuds :
Code TEXT :
<VirtualHost *:443> ServerName pi.linuxtricks.fr ErrorLog /var/log/apache2/pi.linuxtricks.fr-error_log TransferLog /var/log/apache2/pi.linuxtricks.fr-access_log ServerSignature Off SSLProxyEngine on SSLCertificateFile /etc/letsencrypt/live/pi.linuxtricks.fr/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/pi.linuxtricks.fr/privkey.pem SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off ProxyRequests off ProxyPreserveHost on RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s RequestHeader set X-Forwarded-Proto %{HTTPS}s Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED <Proxy balancer://pilinuxtricks> BalancerMember https://192.168.221.51 route=backend1 BalancerMember https://192.168.221.52 route=backend2 ProxySet lbmethod=bybusyness timeout=1 ProxySet stickysession=ROUTEID </Proxy> ProxyPass / balancer://pilinuxtricks/ ProxyPassReverse / balancer://pilinuxtricks/ </VirtualHost>
On est donc sur un bloc VirtualHost traditionnel avec les mêmes éléments que ci dessus avec en plus :
Header add Set-Cookie : Ajout d'un cookie pour les sessions persistantes (rester sur le même noeud)
<Proxy balancer://pilinuxtricks> : Section dédiée au Load Balancing, appelé pilinuxtricks
BalancerMember : Membres du pool du load balancer (route=XXX où XXX est un identifiant différent pour les sessions persistantes)
ProxySet lbmethod=bybusyness timeout=1 : Load Balancing par occupation du serveur, considérer HS si timeout de plus d'1 seconde
ProxySet stickysession=ROUTEID : Session persistante suivant le cookie nommé ROUTEID défini précédemment
ProxyPass : Redirection des requêtes vers le pool spécifié
ProxyPassReverse : Ajuste les entêtes HTTP dans les réponses pour qu'ils correspondent au VirtualHost
Gestionnaire Load Balancing
Quand on utilise du loadbalancing, on peut avoir des stats avec l'outil balancer-manager.
Pour cela, dans le VirtualHost, on ajoutera ceci :
Code :
<VirtualHost *:443>
ServerName pi.linuxtricks.fr
ErrorLog /var/log/apache2/pi.linuxtricks.fr-error_log
TransferLog /var/log/apache2/pi.linuxtricks.fr-access_log
ServerSignature Off
SSLProxyEngine on
SSLCertificateFile /etc/letsencrypt/live/pi.linuxtricks.fr/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/pi.linuxtricks.fr/privkey.pem
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyRequests off
ProxyPreserveHost on
RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
RequestHeader set X-Forwarded-Proto %{HTTPS}s
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://pilinuxtricks>
BalancerMember https://192.168.221.51 route=backend1
BalancerMember https://192.168.221.52 route=backend2
ProxySet lbmethod=bybusyness timeout=1
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass /lbstats !
<Location "/lbstats">
SetHandler balancer-manager
Require ip 192.168.21.0/24
</Location>
ProxyPass / balancer://pilinuxtricks/
ProxyPassReverse / balancer://pilinuxtricks/
</VirtualHost>
On est donc sur un bloc VirtualHost traditionnel avec les mêmes éléments que ci dessus avec en plus :
ProxyPass /lbstats ! : On ne redirige pas cette URI vers le pool si elle est demandée (c'est le Reverse Proxy qui porte les stats)
<Location "/lbstats"> : Directive associée à cette URI
SetHandler balancer-manager : On affiche le gestionnaire du load balancer
Require ip 192.168.21.0/24 : On filtre sur un réseau sûr
Le gestionnaire affiche ceci et permet de gérer les noeuds (les mettre hors ligne par exemple) :
Proxmox derrière le reverse Proxy avec WebSocket
Pour mettre proxmox derrière un Reverse Proxy, vu qu'il y a du Websocket, je vous renvoie vers cet article : https://www.linuxtricks.fr/wiki/wiki.php?title=proxmox-derriere-le-reverse-proxy-apache-httpd