Ecrivez moi !
english french

SME : Utiliser le serveur Apache comme Reverse Proxy

Type How To
Version 0.1.1
Tested on SME 6.0 et 6.0.1

Objet
Explication du fonctionnement
Réalisation
Et après ?
Change Log

Objet

Il est parfois souhaitable qu'une requête WEB reçue par le serveur SME soit transmise silencieusement vers un autre serveur WEB. Plusieurs raisons à cela :

Information importante :

Avant d'aller plus loin, il est important de noter que cette configuration peut compromettre gravement la sécurité de votre réseau. En effet, SME est une distribution orientée sécurité, et, dans la plupart des cas, utiliser SME comme passerelle vers Internet vous permet d'envisager un niveau de sécurité raisonnable. Le fait de relayer une partie de trafic à l'intérieur de votre réseau compromet cette installation. Il convient donc d'être totalement sur de la configuration du serveur cible, ainsi éventuellement des éléments annexes avant d'entreprendre toute réalisation.
Vous aurez été prévenus...

Explication du fonctionnement

Le serveur WEB Apache dispose d'un module qui permet de faire du 'reverse Proxy'. Ceci veut dire qu'il peut recevoir des connexions HTTP et/ou HTTPS et relayer la requête vers un autre serveur, en effectuant éventuellement des modifications dans la requêtes.
De même, il renverra la réponse du serveur au client initial, en effectuant si nécessaire les modifications inverses, afin de présenter les réponses comme si elles émanaient effectivement du serveur Apache.

A titre documentaire, je mentionne ici les deux instructions (de type global) qui doivent être présentes dans le fichier httpd.conf afin d'activer la fonction reverse proxy :
LoadModule proxy_module modules/libproxy.so
AddModule mod_proxy.c

Il n'est pas nécessaire sous SME de s'en préoccuper, elles sont déjà activées, puisque ces fonctions sont utilisées notamment pour 'atteindre' le server-manager.

Type de relayage

Il existe trois types de relayage :

Relayage d'un nom de site

Notez que ceci ne demande PAS d'adresses IP supplémentaires.

Votre serveur Apache est hébergé sur une machine SME et répond au nom de www.bar.foo.

Votre DNS (et le DNS public, le cas échéant) est configuré pour résoudre www.bar.foo. Il est également configuré pour résoudre www2.bar.foo à la même adresse que www.bar.foo (Idéalement, www2.bar.foo est un alias dans le DNS de www.bar.foo, mais malheureusement la conf du DNS de SME ne permet pas de créer d'aliases)

Vous souhaitez en fait que tout le trafic envoyé à www2.bar.foo soit traité par le serveur intranet.bar.foo

Ceci est possible, car dans l'en-tête d'une requête HTTP, il est précisé le nom du host que l'on souhaite atteindre. Le serveur Apache va exploiter cette information pour effectuer son travail d'aiguillage.

Si vous m'avez suivi, et si ceci correspond à votre besoin, allez voir dans réalisation, la partie Relayage d'un nom de site

Relayage en fonction d'une adresse IP

En supposant que votre fournisseur Internet vous propose plusieurs adresses IP différentes il est possible de demander à Apache d'effectuer son tri en fonction de l'adresse IP.
Comme je n'ai pas (pu) tester cette combinaison, je ne m'étendrais pas dessus, mais sachez qu'elle est très proche de la précédente.

Relayage en fonction d'un dossier au sein du site.

Votre page principale est hébergée sur votre serveur SME, à l'adresse www.bar.foo. Mais vous disposez d'une application de prise de commande qui se trouve sur sales.bar.inside.

Vous souhaitez que tout le trafic entrant avec le préfixe suivant : www.bar.foo/commandes soit relayé sur sales.bar.inside.

La solution se trouve dans réalisation, partie Relayage en fonction d'un dossier au sein du site

Variations

Notez que de nombreuses variations sont possibles :

En fait, la combinaison qui ne va pas (à ma connaissance), c'est de relayer vers un serveur HTTPS. En effet, il faudrait que le serveur Apache contienne un client HTTPS, ce qui poserait de toutes façons des problèmes de certificats. En tout cas, je ne sais pas faire.

Réalisation

On m'a signalé qu'un rpm pour SME existe, voir plus bas. Je laisse cependant les explications pours les plus bricoleurs...

Relayage d'un nom de site

Il faut créer un fichier nommé /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/99reverseproxysite :

mkdir -p /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/
cd /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/
vi 99reverseproxysite
(J'ai mentionné vi comme éditeur, mais vous traduirez pico, mc ou autre en fonction de vos habitudes)

En restant dans notre exemple, vous souhaitez qu'une requête adressée au serveur SME et au site web www2.bar.foo soit en fait redirigée vers intranet.bar.foo.
Il faut évidemment que intranet.bar.foo soit dans le dns du serveur SME !

Mettez dans votre fichier 99reverseproxysite les lignes suivantes :

<VirtualHost 0.0.0.0:80>
    ServerName www2.bar.foo
    ServerAlias www2

    ProxyPass / http://intranet.bar.foo/
    ProxyPassReverse / http://intranet.bar.foo/

</VirtualHost>

<VirtualHost 0.0.0.0:443>
    ServerName www2.bar.foo
    ServerAlias www2

    ProxyPass / http://intranet.bar.foo/
    ProxyPassReverse / http://intranet.bar.foo/

</VirtualHost>

Dans ce cas, les connexions HTTP et HTTPS sont relayées en HTTP vers le serveur intranet.bar.foo.
Si vous ne souhaitez qu'un des deux modes, vous mettez la section adéquate.
Eventuellement, vous pouvez peaufiner avec une instruction RevriteRule qui permettra de renvoyer vers le mode adéquat (de 80 vers 443 ou vice-versa).

Le champ ServerAlias permet de donner plusieurs noms au site. Dans ce cas, je l'utilise pour qu'il soit possible d'accéder au site sans donner le nom complet avec le domaine.

Vous pouvez également rediriger vers un sous répertoire du site intranet. Il ne faut pas oublier le / final. Par exemple :

<VirtualHost 0.0.0.0:80>
    ServerName www2.bar.foo
    ServerAlias www2

    ProxyPass / http://intranet.bar.foo/sub/directory/
    ProxyPassReverse / http://intranet.bar.foo/sub/directory/

</VirtualHost>

Une fois ces modifications réalisées, il vous reste à les mettre en application :

server-# /sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
server-# service httpd graceful
/usr/sbin/apachectl graceful: httpd gracefully restarted

Relayage en fonction d'un dossier au sein du site

Il faut créer un fichier nommé /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/VirtualHosts/26reverseproxydir :

mkdir -p /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/VirtualHosts/
cd /etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/VirtualHosts/
vi 26reverseproxydir
(J'ai mentionné vi comme éditeur, mais vous traduirez pico, mc ou autre en fonction de vos habitudes)

En suivant notre exemple, vous souhaitez que les requêtes envoyées à votre serveur SME et commençant par www.bar.foo/commandes soit relayé sur sales.bar.inside.
Il faut évidemment que sales.bar.inside soit dans le dns du serveur SME !

Mettez dans le fichier 26reverseproxydir les lignes suivantes :

Si vous souhaitez qu'il soit accessible en HTTP et en HTTPS :

{
    if ( $virtualHost eq "bar.foo" ) {
        $OUT .= "    # theses dirs are reverse proxyed to an internal server\n" ;
        $OUT .= "    ProxyPass /commandes http://sales.bar.inside/\n" ;
        $OUT .= "    ProxyPassReverse /commandes http://sales.bar.inside/\n" ;
        $OUT .= "\n" ;
        }
}

Si vous souhaitez que le site ne soit accessible qu'en HTTPS (remplacez 443 par 80 pour du HTTP) :

{
    if ( $virtualHost eq "bar.foo" && $port eq "443" ) {
        $OUT .= "    # theses dirs are reverse proxyed to an internal server\n" ;
        $OUT .= "    ProxyPass /commandes http://sales.bar.inside/\n" ;
        $OUT .= "    ProxyPassReverse /commandes http://sales.bar.inside/\n" ;
        $OUT .= "\n" ;
        }
}

Là encore, vous pouvez rediriger vers un sous répertoire du site interne, en ajoutant derrière le nom de machine un sous répertoire, sans oublier le / juste avant le \n. Ce qui donne par exemple :

{
    if ( $virtualHost eq "bar.foo" ) {
        $OUT .= "    # theses dirs are reverse proxyed to an internal server\n" ;
        $OUT .= "    ProxyPass /commandes http://sales.bar.inside/my/wonderful/sales/application/\n" ;
        $OUT .= "    ProxyPassReverse /commandes http://sales.bar.inside/my/wonderful/sales/application/\n" ;
        $OUT .= "\n" ;
        }
}

Une fois ces modifications réalisées, il vous reste à les mettre en application :

server-# /sbin/e-smith/expand-template /etc/httpd/conf/httpd.conf
server-# service httpd graceful
/usr/sbin/apachectl graceful: httpd gracefully restarted

Bien évidement, ces configuration sont compatibles et peuvent être présentes simultanément. D'autres combinaisons peuvent être imaginées.

Utilisation du package "proxypass" de Darell May et Abe Loveless

Il m'a été signalé qu'un package existe pour gérer les fonctions de reverse proxy depuis le server-manager
Ce package (en anglais uniquement) se trouve ici : proxypass.

Ce package fait sensiblement la mêm chose que ce qui est expliqué dans ce how-to :

Après tests, cette contrib, bien que n'étant indiquée opérationnelle que jusqu'à la version 5.6, fonctionne très bien sur la version 6.0

Après, à vous de choisir la solution qui vous va le mieux ;-)

Et après ?

Après ? Votre reverse Proxy est opérationnel et vous me vouez une reconnaissance jusqu'à la douzième génération ;-)

Plus sérieusement, si la demande est suffisante, je peux transformer ce How To en RPM dans le server-manager. C'est à vous de voir...

Change Log

18 mars 2004 Version Initiale
19 mars 2004 Ajout du lien vers le package proxypass sur le site de Abe Loveless