Title: Configurer un reverse proxy Apache
subtitle: (HTTP/HTTPS)
Date: 2012-10-16 20:06
Modified: 2012-10-16 20:06
Category: Système
Tags: reverse proxy, apache, debian, linux, nom de domaine
keywords: reverse proxy, apache, debian, linux, nom de domaine
Slug: configurer-reverse-proxy-apache
Authors: Victor
Status: published

[TOC]

## Ou : routage entre serveurs par nom de domaine

<p>Et oui, c'est ce dont on va parler ici. Comme ce n'est peut être pas très clair pour tout le monde, je vais me permettre une toute petite digression pour expliquer ce qu'est le routage, et plus précisément ce que j'appelle le routage par noms de domaine.</p>

## Merci pour cette digression.

<p>Mais de rien.</p>

<p>Qu'est ce que le <a href="http://fr.wikipedia.org/wiki/Routage">routage</a> ? Ca consiste à se servir d'une unique machine (comunément appelée "le routeur") pour diriger des flux réseau vers différents autres matériels.</p>

<p>Ca sert le plus simplement du monde sur Internet, pour router les différents sous réseaux. Vous voulez joindre truc.truc.truc.truc, mais vous avez comme IP machin.machin.machin.machin, alors un routeur va pouvoir vous dire :</p>

<p>"Pour aller vers truc, c'est à gauche, mais si c'est pour aller vers bidule, c'est à droite. Quand à toi machin, tu es au milieu".</p>

<p>Ok, c'est résumé très vite pour les puristes, mais l'idée est là&nbsp;:-)</p>

<p>Il existe différents autres types de routage. On utilise ce terme parce que l'idée de donner des routes (ou des chemins) pour diriger des flux reste la même.</p>

<p>Une machine (routeur, PC, serveur, ...) reçoit un flux, et à partir de différents critères choisit de rediriger ce flux vers un autre matériel du réseau, l'objectif final étant bien sûr que ce flux arrive à destination de manière sûre.</p>

## Ca suffit oui ?

<p>On y arrive.&nbsp;;-)</p>

<p><strong>EDIT décembre 2015 : </strong>j'ai écris un <a href="/2015/12/configurer-reverse-proxy-haproxy.html">nouvel article</a> pour utiliser haproxy en tant que reverse-proxy, logiciel plus léger et plus adapté qu'apache à cet usage.</p>

<p>Or donc, si vous avez plusieurs serveurs web mais une seule connexion Internet, alors vous avez sans doute déjà eu cette problématique.</p>

<p><em>Comment joindre plusieurs sites web sur différents serveurs depuis les Internet ?</em></p>

<p>La solution qui s'impose directement, c'est du routage de port.</p>

<p>Ce routage particulier consiste à router différents flux reçus depuis Internet vers des machines à l'intérieur de votre réseau local en se basant sur les ports réseaux utilisés. Ce n'est pas le lieu pour décrire un port réseau. Voyez ça comme une porte. Vous rentrez dans la même maison, mais selon que vous utilisiez la porte d'entrée ou la véranda, vous êtes "redirigés" vers une pièce différente de la maison.</p>

<p>&nbsp;</p>

<p>Ce type de routage présente un inconvénient certain : chacun de vos utilisateurs doit spécifier la porte qu'il veut utiliser pour joindre le bon serveur.</p>

<p>En général, ça consiste à taper <em>nomdedomaine.tld:port </em>dans votre navigateur, ce qui n'est pas très pratique, et difficile à expliquer à vos clients. (Et oubliez de suite expliquer ça à Google and co)</p>

<p>C'est là qu'intervient ce super outil, le <a href="http://fr.wikipedia.org/wiki/Reverse_proxy">reverse proxy, ou mandataire inverse</a>. Nous allons voir ici comment l'utiliser avec <a href="http://www.apache.org/">Apache</a>, un serveur web populaire. Il est sans doute possible de le faire également avec NGinX ou lightHTTPD, mais ce n'est pas le sujet&nbsp;:-D</p>

<p>Le mandataire inverse va regarder le site que vous voulez joindre, et vous rediriger vers le bon serveur directement. Il servira ensuite d'intermédiaire sur le réseau entre vous et le serveur.</p>

## On veut du concret !

<p>Voila voila !</p>

### Pré-requis matériel

<p>Pour commencer, il va falloir définir un serveur mandataire. C'est sur ce serveur que nous allons configurer le mandataire inverse.</p>

<p>Il peut héberger lui-même des sites Internet, ou vous pouvez l'utiliser uniquement comme mandataire, ça n'a pas d'importance. Si vous utilisez cette solution à des vues industrielles, mieux vaut prévoir un serveur robuste, puisqu'il supportera toutes les requêtes vers tous vos sites web.</p>

<p>Ensuite, il vous faut configurer votre routeur/machinbox© pour rediriger tout le flux web (port 80) vers le serveur mandataire. Ceci se fait grâce à un routage de port classique. Toutes les requêtes web arriveront maintenant sur ce serveur, qui va décider quoi en faire.</p>

<p>En théorie on devrait pouvoir faire la même chose pour l'HTTPS, mais vu qu'il y a quand même des contraintes de certificats et que je n'ai pas testé, je préfère ne pas dire de bêtises ici.</p>

### Prérequis logiciel

<p>Là, c'est simple. Il vous faut un serveur Apache installé et fonctionnel sur votre serveur mandataire. C'est tout. Un système de pare-feu ne serait également pas de trop (ce serveur est l'unique point d'entrée d'Internet, rappelons le :-) )</p>

<p>Il vous faut également (bien evidemment ?) une connexion ssh vers votre serveur, ou à défaut un écran-clavier-souris.</p>

## Plongeons dans le cambouis

### Activation du module proxy Apache

<p>Connectez vous sur votre serveur (mandataire), puis tapez :</p>

<pre>
$ sudo a2enmod proxy

$ sudo a2enmod proxy_http</pre>

<p>&nbsp;</p>

<p>Redémarrez ensuite Apache un petit coup</p>

<pre>
$sudo /etc/init.d/apache restart</pre>

<p>&nbsp;</p>

<p>Voila, c'est fait !</p>

### Configuration du routage

<p>Ici, tout va se faire grâce au système d'hôte virtuel Apache.</p>

<p>Editez un fichier dans /etc/apache2/site-available/</p>

<pre>
$ sudo nano /etc/apache2/sites-available/monsite</pre>

<p>&nbsp;</p>

<p>Puis configurez votre hôte comme suit :</p>

<pre>
&lt;VirtualHost *:80&gt;
#
ServerName nomdedomaine.tld #
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://IPSERVEURWEBINTERNE/
ProxyPassReverse / http://IPSERVEURWEBINTERNE/
#
&lt;/VirtualHost&gt;</pre>

<p>&nbsp;</p>

<p>Cela va permettre de rediriger toutes les requêtes sur nomdedomaine.tld en http vers le serveur IPSERVEURWEBINTERNE</p>

<p>&nbsp;</p>

<p>C'est simple et efficace. Vous pouvez créer toutes vos autres redirections dans ce fichier, ou créer un fichier par redirection (plus propre mais plus contraignant). A vous de voir.</p>

<p>Une fois ces fichier créés, il vous faut activer les hôtes virtuels.</p>

<p>Faites</p>

<pre>
$ sudo a2ensite monsite
</pre>

<p>pour chaque fichier que vous avez créé.</p>

<p>&nbsp;</p>

<p>Ensuite, rechargez la configuration Apache (pas besoin de redémarrer)</p>

<pre>
$ sudo /etc/init.d/apache2 reload</pre>

<p>&nbsp;</p>

## Tadam !

<p>Il ne vous reste plus qu'à tester. De l'exterieur, essayez de joindre nomdedomaine.tld, tout doit fonctionner :-)</p>

<p>Et voila, vous avez économisé plein d'adresses IP publiques ! Mais pourquoi utiliser plusieurs serveurs Web derrière une seule IP petits coquinous ? Ça, ça vous regarde...</p>

<p>Si jamais j'ai la problématique un jour, je configurerai ça pour de l'HTTPS (mais honnêtement j'espère jamais&nbsp;:-D )</p>

<p>&nbsp;</p>

<p><s>Et dans ce cas je rajouterai ça sur le blog, promis !&nbsp;</s> Voir juste au dessous !</p>

## Edit : Comme promis, la version https

<p>Et oui, car finalement j'ai du m'y mettre :)</p>

<p>Tout d'abord, les limitations. Je n'ai réussit jusqu'alors qu'à configurer une connexion HTTPS entre le client et le reverse proxy.</p>

<p>Je n'ai pas réussit à avoir ensuite de l'HTTPS entre le reverse proxy et le vrai serveur web, ce qui veut dire que, au moins sur le réseau local, les données transitent en clair.</p>

<p>De mon point de vue ce n'est qu'un problème conceptuel, étant donné que le "réseau local" est en fait une liaison directe entre machines virtuelles sur le même hyperviseur, donc bon. Mais quand même, ce n'est pas très propre. Si jamais quelqu'un a une suggestion à ce sujet, qu'il me fasse signe :)</p>

<p>&nbsp;</p>

<p>L'idée donc du reverse proxy en HTTPS, c'est que c'est le proxy qui va contenir les certificats https. Celui-ci va alors répondre à la place du serveur web, avec la bonne URL puique c'est un proxy, et transmettre ensuite les requêtes vers le serveur.</p>

<p>On a donc un schéma dans cette idée :</p>

<p>&lt;Client&gt; ====https====&lt;Proxy&gt;----http----&lt;serveur web&gt;</p>

<p>Et en plus, c'est assez simple en fait.</p>

<p><strong>On considérera ici que vous avez déja généré des certificats propres pour votre site (éventuellement auto-signés).</strong></p>

<p>Il vous faudra activer le SSL sur votre reverse proxy :&nbsp;</p>

<pre>
$ sudo a2enmod ssl
$ sudo /etc/init.d/apache2 restart
</pre>

<p>Ensuite, placez vos certificats (clef publique, clef privée) dans le dossier /etc/apache2/ssl/.</p>

<pre>
$ sudo cp moncertificat.* /etc/apache2/ssl/
</pre>

<p>Créez l'hôte virtuel qui servira pour votre redirection :</p>

<pre>
sudo nano /etc/apache2/site-available/monproxySSL
</pre>

<p>Et remplissez le avec ceci :</p>

<pre>
	&lt;VirtualHost *:443&gt;

	# Décommentez cette ligne et indiquez-y l'adresse courriel de l'administrateur du site
	#ServerAdmin webmaster@my-domain.com

	# Classique, votre nom de domaine
	ServerName monsite.tld

	# Si jamais vous avez d'autres domaines renvoyant sur ce site, utilisez la dircetive ServerAlias
	# Vous pouvez utiliser le joker * pour prendre en compte tout les sous-domaines
	#ServerAlias www2.my-domain.com www.my-other-domain.com *.yet-another-domain.com

	# L'emplacement des logs.
	ErrorLog /var/log/apache2/monsite.tld-error.log
	LogLevel warn
	CustomLog /var/log/apache2/monsite.tld-access.log combined

	# SSL magic
	#
	# Il est nécessaire d'activer SSL, sinon c'est http qui sera utilisé
	SSLEngine On

	# On autorise uniquement les clefs de cryptage longue (high) et moyenne (medium)
	# SSLCipherSuite HIGH:MEDIUM

	# On autorise SSLV3 et TLSv1, on rejette le vieux SSLv2
	# SSLProtocol all -SSLv2

	# La clef publique du serveur :
	SSLCertificateFile /etc/apache2/ssl/moncertificat-cert.pem

	# La clef privée du serveur:
	# SSLCertificateKeyFile /etc/apache2/ssl/moncertificat-key.pem

	# Theses lines only apply of the rewrite module is enabled.
	# This is a security enhancement recommanded by the nessus tool.
	&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine on
	RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
	RewriteRule .* - [F]
	&lt;/IfModule&gt;
	&lt;IfModule mod_rewrite.c&gt;
	&lt;IfModule mod_proxy.c&gt;

	#Ne commentez jamais cette ligne, elle évite que votre serveur soit utilisé comme proxy par des gens mal-intentionnés.
	ProxyRequests Off

	# Cetet option passe les nom d'hôte au serveur, ce qui vous permet d'utiliser également des hôtes virtuels sur le serveur principal.
	ProxyPreserveHost On

	# Les lignes classiques de proxy. Comme dit au dessus, on passe le flux en http.
	ProxyPassReverse / http://IPSERVEURWEB/
	RewriteRule ^/(.*) http://IPSERVERUWEB/$1 [P,L]

	&lt;/IfModule&gt;
	&lt;/IfModule&gt;

	# Autoriser l'accès au contenu à travers le proxy.
	#Ne l'enlevez pas si vous voulez que le site fonctionne !
	&lt;Location /&gt;
	Order deny,allow
	Allow from all
	&lt;/Location&gt;

	&lt;/VirtualHost&gt;


	&lt;VirtualHost *:80&gt;
	# Cette partie va permettre de rediriger d'éventuelles requêtes en HTTP vers l'HTTPS
	# Vous pouvez également configurer le proxy à la place de la règle de réécriture si vous voulez autoriser l'accès en HTTP
	ServerName monsite.tld

	#ServerAlias www2.my-domain.com www.my-other-domain.com *.yet-another-domain.com

	# Theses lines only apply of the rewrite module is enabled.
	# This is a security enhancement recommanded by the nessus tool.
	&lt;IfModule mod_rewrite.c&gt;
	RewriteEngine on
	RewriteCond %{REQUEST_METHOD} ^{TRACE|TRACK}
	RewriteRule .* - [F]
	&lt;/IfModule&gt;

	# On renvoit toutes les requêtes HTTP vers l'HTTPS.
	Redirect permanent / https://monsite.tld/

	&lt;/VirtualHost&gt;
</pre>

<p>N'oubliez pas bien sûr d'activer votre nouvel hôte virtuel :</p>

<pre>
$ sudo a2ensite monproxyssl
$ sudo /etc/init.d/apache2 reload
</pre>

<p>Et voila, votre reverse proxy doit fonctionner en HTTPS :)</p>

<p>&nbsp;</p>
