URL: https://linuxfr.org/news/gerer-plusieurs-services-de-facon-transparente
Title: Gérer plusieurs services de façon transparente
Authors: Denis Dordoigne
Florent Zara, Benoît Sibaud et Bruno Michel
Date: 2013年11月15日T08:08:51+01:00
License: CC By-SA
Tags: gerer_plusieurs_services_de_façon_transparente, administration_système, howto, hébergement et haute_disponibilité
Score: 54
Vous avez commencé à héberger de plus en plus de services internet pour votre famille ou votre association et, les besoins évoluant, vous commencez à avoir plusieurs services qui utilisent le même protocole (vous avez par exemple un serveur web, un serveur d'application et un serveur d'API qui communiquent tous en HTTP) ou alors vous avez voulu cloisonner dans différentes machines virtuelles les services selon leurs utilisateurs et vous vous retrouvez avec plusieurs serveurs web, ftp, mail, dns... malheureusement vous n'avez qu'une seule adresse IP publique pour accéder à tout cela, alors comment permettre à chacun d'accéder au bon service ?

Des logiciels dits de [[proxy inverse]] permettent de répondre à ce besoin, cet article va vous présenter comment fonctionnent certains d'entre eux.
----
----
# Les services HTTP #
## Logiciels ##
À peu près tous les logiciels de proxy HTTP peuvent remplir cette fonctionnalité, le plus à la mode actuellement pour faire cela est [[nginx]] mais si vous êtes plus habitué à [[Squid]] ou [[Apache HTTP Server]] ceux-ci feront bien l'affaire...
## Problématique ##
Pour notre exemple, on va considérer que nous avons deux serveurs HTTP à gérer, le premier héberge un wiki et un blog, le second qui écoute sur le port 8080 héberge une api et un webmail.
## Configuration d'Apache HTTP Server ##
Il faut d'abord charger le module proxy, et le configurer pour agir comme un proxy inverse :
```ruby
# chargement des modules
LoadModule proxy_module mod_proxy.so
LoadModule proxy_http_module mod_proxy_http.so
# on ne veut pas servir de proxy sortant
ProxyRequests Off
# le proxy ne fera que transférer les requêtes HTTP
ProxyPreserveHost On
```
Ensuite, il faut configurer chacun des serveurs que l'on veut servir :
```xml
NameVirtualHost *:80
ServerName serveur1.local
ServerAlias wiki.example.com
ServerAlias blog.example.com
ProxyPass / http://serveur1.local/
ServerName serveur2.local
ServerAlias api.example.com
ServerAlias webmail.example.com
ProxyPass / http://serveur2.local:8080/
```
Bien entendu, si on est amené à gérer beaucoup de sites et que ceux-ci évoluent, on préférera automatiser la génération de cette configuration.
## Bonus : faire du HTTPS grâce au proxy ##
On peut profiter du proxy pour chiffrer la communication avec internet, il suffit d'activer le proxy SSL :
```xml
ServerName serveur2.local
ServerAlias api.example.com
ServerAlias webmail.example.com
SSLEngine On
SSLProxyEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
ProxyPass / http://serveur2.local:8080/
```
Ici il faudrait que le certificat gère à la fois les noms de domaine api.example.com et webmail.example.com pour que celui-ci soit valide. Si jamais on veut gérer plusieurs certificats, il est nécessaire de s'assurer de la compatibilité du serveur et des navigateurs web des visiteurs avec la fonctionnalité [[Server Name Indication]].
# Les services FTP #
## Logiciels ##
De nombreux logiciels de proxy FTP existent, d'ailleurs certains des logiciels faisant office de proxy HTTP ont aussi une fonction FTP. Cependant, ces logiciels ont pour la plupart une des limitations suivantes :
* le choix du serveur cible n'est pas transparent (il faut par exemple utiliser le login avec le compte georgette@serveur2.local pour accéder au serveur2 avec le compte georgette)
* un seul serveur cible est géré
* seule la récupération de fichiers est gérée et pas le dépôt
Il existe cependant deux logiciels qui permettent de répondre à notre besoin de proxy inverse transparent : [ftp.proxy](http://www.ftpproxy.org) et [frox](http://frox.sourceforge.net) ; nginx, encore lui, devrait également répondre à ce besoin dans ses dernières versions
## Problématique ##
Pour notre exemple on considérera qu'il y a un serveur ftp principal (serveur1) et que les utilisateurs georgette et mauricette ont chacun un serveur ftp dédié (serveur2 et serveur3)
## Configuration de ftp.proxy ##
ftp.proxy ne dispose pas de fichier de configuration. Il est lancé à partir de [[xinetd]] avec les arguments qui font office de configuration. Voici à quoi doit ressembler /etc/xinetd.d/ftp :
```bash
service ftp
{
socket_type = stream
wait = no
user = root
server = /usr/local/sbin/ftp.proxy
server_args = -e -m -b -x /usr/local/bin/routage_ftp.pl
}
```
Le routage des accès vers les différents serveurs est faite grâce au script passé en argument (ici /usr/local/bin/routage_ftp.pl), si on veut rediriger les accès selon le compte utilisé pour le login, il suffit de tester la valeur de la variable d'environnement PROXY_SERVERLOGIN :
```perl
#!/usr/bin/perl
# on recupere l'utilisateur ftp
my $login = $ENV{'PROXY_SERVERLOGIN'};
# par defaut le serveur ftp est serveur1
my $serveur = 'serveur1.local';
# georgette et mauricette sont sur d'autres serveurs
if ($login eq 'georgette')
{
$serveur = 'serveur2.local';
}
elsif ($login eq 'mauricette')
{
$serveur = 'serveur3.local';
}
# on envoie la reponse au proxy ftp
print "LOGIN $login\nSERVER $serveur\n";
```
Bien entendu, chacun utilisera son langage préféré pour faire son script, et s'il y a de nombreux comptes on fera un script un peu plus évolué (qui interroge la base de données de chaque serveur FTP par exemple).
# Les services DNS #
## Logiciels ##
La solution la plus élégante et qui est gérée par tous les logiciels de serveurs DNS est de faire un [[transfert de zone DNS]] depuis chacun de vos serveurs DNS vers celui qui sera relié à internet. Cependant, la plupart des serveurs DNS ont aussi une fonctionnalité de proxy inverse et peuvent se contenter de renvoyer les requêtes au bon serveur.
## Problématique ##
Pour notre exemple, on considérera que 192.168.0.33 gère toutes les zones, sauf la zone georgette.example.com qui est gérée par 192.168.0.44 et la zone mauricette.example.com qui est gérée par 192.168.0.55.
## Configuration de bind9 ##
```perl
# configuration du serveur par défaut
options {
forwarders {192.168.0.33;};
};
# configuration des cas particuliers
zone "georgette.example.com" {
type forward;
forwarders {192.168.10.44;};
};
zone "mauricette.example.com" {
type forward;
forwarders {192.168.10.55;};
};
```
# Les services SMTP #
## Logiciels ##
Les logiciels de serveur mail les plus populaires, dont [[sendmail]], [[postfix]] et [[exim]], permettent tous de relayer des messages à plusieurs serveurs internes
## Problématique ##
Pour notre exemple, on va considérer que les adresses paulette@example.com et claudette@example.com sont gérées par serveur1, et que les adresses contact@georgette.example.com et georgette@example.com sont gérées par serveur2. Chaque serveur mail écoute sur le port 587.
## Configuration de postfix ##
On met d'abord en place une configuration pour n'accepter que les mails à destination de boîtes hébergées par la plateforme :
```bash
smtpd_recipient_restrictions = reject_unauth_destination, reject_unlisted_recipient
```
Ensuite on met en place la configuration du relayage par adresse dans main.cf :
```bash
# liste des nom de domaines gérés
relay_domains = /etc/postfix/domaines_relayes
# liste des adresses gérées
relay_recipient_maps = hash:/etc/postfix/adresses_relayees
# serveur de destination de chaque adresse gérée
transport_maps = hash:/etc/postfix/adresses_transport
```
Fichier domaines_relayes :
```bash
example.com
georgette.example.com
```
Fichier adresses_relayees :
```bash
paulette@example.com OK
claudette@example.com OK
georgette@example.com OK
contact@georgette.example.com OK
```
Fichier adresses_transport :
```bash
paulette@example.com smtp:[serveur1.local]:587
claudette@example.com smtp:[serveur1.local]:587
georgette@example.com smtp:[serveur2.local]:587
contact@georgette.example.com smtp:[serveur2.local]:587
```
Bien entendu la gestion par des fichiers gérés manuellement n'est destinée qu'à une petite architecture évoluant peu, il est possible de demander à postfix d'aller directement interroger des bases de données pour récupérer les différentes adresses et noms de domaines gérés.
## Bonus : et la communication en interne ? ##
Si votre serveur proxy inverse SMTP connaît bien toutes les adresses, ce n'est pas forcément le cas de chacun de vos serveurs mails. Dans notre exemple, si vous souhaitez écrire à paulette@example.com depuis serveur2, le message risque d'être refusé par le serveur mail local parce que l'adresse lui est inconnue... il existe trois solutions pour contourner ce problème :
* soit mettre en place la configuration de relayage sur tous vos serveurs mails (donc serveur1 aura la configuration pour relayer vers serveur2 les mails gérés par serveur2, et inversement), ce qui peut se révéler lourd à gérer si vous commencez à multiplier les services mails
* soit, si votre serveur mail le permet, ne pas rejeter les messages aux destinataires inconnus mais plutôt les transférer au serveur proxy (NDLA : je ne connais pas de serveur mail permettant cela)
* soit configurer deux instances de serveur mail sur chaque serveur, l'une destinée à la réception de mails (que l'on fait écouter sur le port 587 par exemple), et l'autre destinée à l'envoi de mails (qui se contentera de tout envoyer au proxy, charge à celui-ci de redistribuer les mails au bon endroit par la suite) ; en ce qui concerne postfix la lecture de http://www.postfix.org/MULTI_INSTANCE_README.html est un bon début pour mettre cela en place
# Les services POP/IMAP #
## Logiciels ##
De nombreux projets existent pour offrir un service de proxy inverse en [[IMAP]], mais seuls deux sont pleinement stables et opérationnels : [[nginx]], toujours lui, et [[perdition]] qui gère également les protocoles [[POP]] et [[SIEVE]].
## Configuration de perdition ##
Perdition fournit une configuration par défaut qui gère directement les protocoles pop et imap, sans avoir besoin de la modifier. Il nécessite seulement un fichier popmap (qui doit être compilé avec la commande _make_ depuis le répertoire /etc/perdition/) qui contient la liste des adresses gérées :
```
paulette@example.com:serveur1
claudette@example.com:serveur1
georgette@example.com:serveur2
contact@georgette.example.com:serveur2
```
Perdition peut également interroger une base de données ou un serveur [[LDAP]] pour récupérer ces informations.
## Bonus : faire du POPS et de l'IMAPS grâce au proxy ##
Il est possible de profiter de ce proxy pour chiffrer les communications passant par internet. Pour cela, il suffit d'activer les services IMAPS et POPS, en leur indiquant qu'ils doivent communiquer avec un port non crypté en face. Cela est géré dans le fichier /etc/default/perdition ou /etc/sysconfig/perdition selon les distributions :
```bash
# Run an instance of perdition in POP3S mode
# Set to "yes" to run this instance of perdition
# Set to any other value to not run this instance of perdition
POP3S=yes
#Command line parameters to pass to perdition when run in POP3S mode
POP3S_FLAGS="--ssl_mode ssl_listen -p 110"
# Run an instance of perdition in IMAP4S mode
# Set to "yes" to run this instance of perdition
# Set to any other value to not run this instance of perdition
IMAP4S=yes
#Command line parameters to pass to perdition when run in IMAP4S mode
IMAP4S_FLAGS="--ssl_mode ssl_listen -p 143"
```
Le certificat doit être déclaré dans /etc/perdition/perdition.conf :
```bash
# chemin des informations de certificat
ssl_ca_file /etc/perdition/perdition.ca.pem
ssl_cert_file /etc/perdition/perdition.crt.pem
ssl_key_file /etc/perdition/perdition.key.pem
# facultatif : autoriser un certificat auto-signé
ssl_ca_accept_self_signed
ssl_cert_accept_self_signed
```
# Dernières considérations pratiques #
## Visibilité de l'adresse IP publique ##
Une fois que les connexions passent par le proxy, vos serveurs n'auront plus la visibilité de l'adresse IP publique d'origine, ce qui nécessitera probablement quelques adaptations au niveau de votre plateforme :
* si vous loguez pour des raisons légales vos accès, que vous avez des outils de statistiques qui utilisent les adresses IP source, ou encore que vous avez des mécanismes de sécurité comme [[fail2ban]], il faudra dorénavant utiliser les logs du proxy et non plus ceux de vos serveurs
* si vous avez des antispams sur vos serveurs mails, il sera probablement plus pertinent de les installer sur le proxy pour bénéficier de tous les fonctionnalités
* si vous utilisez des vues sur vos serveurs DNS, il faudra bien veiller à ce que le proxy accède à la vue "internet"
* dans le cadre du HTTP, les proxys ajoutent un entête **X-Forwarded-For** aux entêtes, vous pouvez configurer vos serveurs web pour qu'ils considèrent cet entête comme adresse IP source (dans apache HTTPD server, cela peut être fait avec le [mod_rpaf](http://www.stderr.net/apache/rpaf/)).
## Choisir le bon logiciel ##
Vous trouverez une multitude de logiciels prétendant pouvoir répondre au besoin de proxy inverse, mais presque tous ont un défaut en commun : un manque flagrant de documentation pour ce cas précis d'usage. Ici ont été présentés des exemples de configuration pour une sélection de logiciels, mais si vous savez configurer d'autres logiciels pour répondre au même besoin, n'hésitez pas à l'indiquer en commentaire (en conservant de préférence la licence CC-BY-SA afin que l'ensemble puisse être diffusé et réutilisé).