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.
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
Sous Debian et Ubuntu, il faut activer le module avec la commande suivante (qui activera le module proxy aussi) :
Sous Gentoo, on positionnera les USE suivants :
Et dans /etc/conf.d/apache, on rajoute -D PROXY :
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
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.
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
Sous Debian et Ubuntu, il faut activer le module avec la commande suivante (qui activera le module proxy aussi) :
Code BASH :
a2enmod proxy_http
Sous Gentoo, on positionnera les USE suivants :
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
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"
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
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