Un truc que j’ai fait un jour, c’est un système de reverse proxy pour apache. Si vous avez pas ce que c’est un reverse proxy, c’est sans doute que vous n’en avez pas besoin, mais je vais y aller d’une explication rapide;

Un proxy, pour commencer

Ça ce traduit en “mandataire” et c’est en général un serveur entre une machine sur un réseau interne (un poste de travail dans une entreprise, par exemple) et l’internet. On peut faire proxy pour des tas de choses, mais généralement c’est pour le protocole HTTP et ses amis HTTPS, FTP qui lui ressemble très vaguement, bref les trucs de l’internet. Mandataire, c’est bien l’idée, il reçoit les requêtes, les envoie à votre place au serveur, et vous envoie la réponse quand il l’a.

Jusque là, il n’y a pas d’intérêt si ce n’est que ça résoud le problème du routage réseau. Bon, sans rentrer dans les détails, sur un réseau privé, l’adresse de l’ordinateur n’est pas connue sur le réseau public, l’internet. Donc, impossible de s’y rendre sans un mandataire qui va nous prêter son adresse IP. Il y a d’autres solutions techniquement, mais le proxy peut faire des choses en plus, et notamment ces trois choses :

  1. d’abord, il peut cacher. C’est-à-dire, si vous demander une image, il la demande au vrai serveur, la stocke, puis ensuite, si vous en avez encore besoin, il vous la refile, en vérifiant de temps en temps sur le serveur original qu’elle n’a pas changé... Ca fait des économies de bande passante, et on y gagne en vitesse...
  2. ensuite, il peut filtrer de manière à ce que des yeux innocents ne voient pas des choses qui pourraient les choquer. Par exemple, des textes très violents qui explique ce que c’est vraiment que l’état, qu’on trouve sur des sites pleins d’anarchistes très méchants. C’est qu’un exemple.
  3. enfin, il peut vous demander de vous authentifier. Pour tout ou seulement pour certains sites.

Inutile de dire que ça, c’est la théorie. Dans la pratique, c’est plus ou moins bien fait et à la sortie, c’est parfois un cauchemar. Mais bref.

Et maintenant, le reverse proxy

Le reverse proxy, c’est la même chose, mais la différence, c’est que les serveurs sont dans un réseau interne, et que l’on “cache”, si l’on veut, le fait qu’il y a douze serveurs derrière une seule adresse publique. C’est toujours le principe du mandat, mais cette fois-ci, les requêtes viennent de l’extérieur et vont vers l’intérieur.

Les trois choses sont toujours présentes, mais à l’envers !

  1. Le cache : ce coup-ci, il peut renvoyer vers l’extérieur des images venant d’un serveur interne, c’est autant de moins à faire pour un serveur qui est peut-être assez occupé sans encore passer son temps à servir des images.
  2. Le filtre : et hop si un méchant pirate de l’internet envoie un virus ! (Le pirate un peu benêt qui croit qu’un serveur web peut tourner sur MS-WINDOS :))) et hop ! filtré !
  3. L’authentification. Là, un seul proxy peut authentifier tout le monde avant de faire suivre les demandes. C’est bien pratique, parce que la sécurité est centralisée et les serveurs de derrière n’ont plus qu’à faire confiance au proxy....

J’ai expliqué, la différence entre la pratique et la théorie, tout-à-l’heure, non ? Ben là, pareil.

Un exemple

  • Vous avez un serveur de domaine windows avec exchange, ou active directory, ou un honnête serveur ldap, qui tourne sur serveur-ldap,
  • Vous avez des applis intranet appli1 et appli2 qui tournent sur les serveurs interne-1 et interne-2,
  • Et vous voulez que l’on se connecte sur le reverse proxy, qui est accessible sur internet par l’adresse intranet.cheunous.com, et qu’en plus, en tapant http://intranet.cheunous.com/appli1/ on arrive sur le serveur interne-1 et pareil pour appli2 ?
  • Comme c’est pas la journée portes ouvertes, vous voulez aussi authentifier les gens sur le LDAP ?

Apache+mod_perl est votre ami !

AVERTISSEMENT : Je ne m’engage à rien, d’ailleurs, en informatique, je m’engage jamais sans être payé et encore. Your mileage may vary, comme dirait l’autre. Il faudrait adapter à apache 2.0 etc... En plus, j’ai pas de LDAP sous la main pour tester.

Config d'apache pour mod_perl

Il vous faudra des lignes dans ce genre :

LoadModule perl_module /usr/lib/apache/1.3/mod_perl.so
...
<IfModule mod_perl.c>
  Alias /perl/ /var/www/perl/
  <Location /perl>
    SetHandler perl-script
    PerlHandler Apache::Registry
    Options +ExecCGI
  </Location>
</IfModule>

Pour un endroit à protéger, il faudra donc quelque chose du genre

<Directory /var/www/secret>
       AuthType basic
       AuthName "Endroit secret"
       PerlAuthenHandler Apache::AuthSystem
       require valid-user
       Order allow,deny
       Allow from all
</Directory>

Le code Perl pour authentifier

Ce n’est qu’un vague exemple, mais c’est l’idée (à fourrer dans un fichier AuthSystem.pm et à mettre là où apache le cherchera).

package Apache::AuthSystem;
 
use Apache::Constants ':common';
use Net::LDAP;
 
sub handler {
	my $r = shift;
 
	my($res, $sent_pwd) = $r->get_basic_auth_pw;
	return $res if $res != OK;
 
	my $user = $r->connection->user;
	my $reason = "";
 
	my $tmp;
	my $base_dn;
	my $serveur;
	my $filter;
	my $port;
	my $cn;
	my $domaine;
	my @tmp;
	my $binddn;
	my $bindpwd;
 
	# decoupage du user en DOMAINE\USER (vous savez, windos...)
	if (index($user, "\\") > 0)
	{
			$user = substr($user, rindex($user, "\\")+1);
	}
	$serveur = "serveur-ldap";
	$filter="attributDuLdap=".$user; # ce qui dépend de chez vous
	$port=389;
	$binddn="CN=connecteur anonyme,CN=users,DC=cheunous,DC=com";
	$bindpwd="anonyme";
	$base_dn="DC=cheunous,DC=com";
 
	# on se debarrase des mots de passe vide
	if ($sent_pwd eq "") {
		$r->note_basic_auth_failure;
		$r->log_reason("user $filter : no password supplied",$r->uri);
		return AUTH_REQUIRED;
	}
 
	# procedure ldap pour verifier le mot de passe
	my $ldap = new Net::LDAP($serveur, port => $port);
 
	# d'abord une connexion semi-anonyme
	my $mesg = $ldap->bind($binddn, password=>$bindpwd);
 
	# on verifie que la connexion est ok
	if (my $error = $mesg->code())
	{
		   $r->note_basic_auth_failure;
		   $r->log_reason("user $filter : LDAP Connection Failed: $error ($filter)",$r->uri);
		   return AUTH_REQUIRED;
	}
 
	# ensuite on cherche le gars
	my $attrs = mail;
	$mesg = $ldap->search(
			 base => "",
			 filter => "($filter*)",
			 attrs => $attrs
			 );
	if (my $error = $mesg->code())
	{
		# oops il existe pas
		$r->note_basic_auth_failure;
		$r->log_reason("user $filter : LDAP Search Failed: $error ($filter)",$r->uri);
		return AUTH_REQUIRED;
	}
 
	my $entry = $mesg->shift_entry;
	my $user_dn = $entry->dn();
	$r->log_reason("user $user_dn : LDAP Search OK ($user_dn)",$r->uri);
 
	# on prend son dn
	my $login = $user_dn;
	# et on essaye de se logguer avec le password qu'il nous a envoyé
	$mesg = $ldap->bind($login,password=>$sent_pwd);
 
	if (my $error = $mesg->code())
	{
		$r->note_basic_auth_failure;
		$r->log_reason("user $login : failed bind: $mesg->error ",$r->uri);
		# essaye encore
		return AUTH_REQUIRED;
	}
 
	my $error = $mesg->code();
	$r->log_reason("AUTHDEBUG user $user_dn bind: $error",$r->uri);
	# user authentifié
	return OK;
 
}
 
1;

Un reverse proxy

Il vous faudra les modules de proxy qui vont bien...

LoadModule proxy_module /usr/lib/apache/1.3/libproxy.so
...

ProxyRequests On
...
<Directory proxy:http://serveur-interne-1/*>
	AuthType basic
	AuthName "intranet"
	require valid-user
	PerlAuthenHandler Apache::AuthSystem
	Order deny,allow
	Allow from all
</Directory>
	
ProxyPass /appli1/ http://serveur-interne-1/appli1/
ProxyPassReverse /appli1/ http://serveur-interne-1/appli1/
...
# idem pour le serveur-interne-2 et appli2	

Autre piste de recherche

Le mod_revrite. A woodoo thing, comme ils disent.

LoadModule rewrite_module /usr/lib/apache/1.3/mod_rewrite.so
....
RewriteEngine On
RewriteLogLevel 0
RewriteLog "/var/log/apache/rewrite_log"

RewriteRule ^/appli1(.*) http://serveur-interne-1/appli1$1 [P]
RewriteRule ^/serveur-interne-1/appli1/(.*)$ http://intranet.cheunous.com/$1 [R]

Mais là, c’est sans garantie de tomber en marche.

En conclusion

Vos remarques et tests complémentaires sont les bienvenus. Je collerai les solutions aux problèmes que je trouve quand j’aurais le temps. Faire marcher l’ensemble du biniou est laissé comme un exercice pour le lecteur.

 
config_pour_apache_et_ses_amis.txt · Dernière modification: 2007/05/03 00:45 par joe
 
Recent changes RSS feed Ouvaton, l'hebergement cooperatif Powered by PHP Driven by DokuWiki