Proxy HTTP
Qu’est-ce qu’un proxy HTTP. Bien souvent lorsque l’on surfe sur Internet, le navigateur Web ne va pas directement demander les pages/images que l’on regarde au serveur Web du site que l’on regarde. Le navigateur va demander les fichiers à une autre machine (toujours la même). C’est cette machine qui va chercher les pages sur le serveur Web que l’on veut consulter. Une fois que cette machine intermédiaire a récupéré la page/image elle fait suivre au navigateur Web. Pour que cela fonctionne, la machine intermédiaire fait tourner un programme que l’on appelle un proxy web ou proxy http.
Vous savez maintenant ce qu’est un proxy http mais à quoi cela peut-il servir ? En réalité, cela peut avoir de nombreuses utilités. En voici quelques unes :
– Généralement le proxy sert de cache web. Ce qui veut dire qu’il va demander les fichiers que l’on souhaite et il les place sur un de ses disques. Si une autre personne fait la demande de la même page au proxy, il se contentera d’interroger le serveur web pour savoir si la page a été mise à jour. Si ce n’est pas le cas, il retournera le fichier qu’il a en local et évitera un transfert sur le réseau.
– Une autre utilité qui va souvent de pair avec la précédente c’est le filtrage. En effet, quand vous demandez vos pages à ce serveur proxy, il suffit de lui dire ce que l’on n’a pas le droit de voir ou ce que l’on a le droit de voir et il ne retournera que les pages qui sont autorisées à être vues.
– Une autre application bien utile c’est la possibilité de permettre à des machines qui ne sont pas sur Internet de consulter des sites Web. En effet, Internet est basé sur le protocole IP. Chaque machine a une adresse IP. Grâce à cette adresse, les machines sont capables d’échanger avec d’autres machines grâce à des routeurs qui, en fonction de l’adresse trouvent le bon chemin à prendre. Seulement, il existe des plages d’adresses réservées pour les réseaux privés. Dans ce cas, ces adresses ne sont pas routées sur Internet car il peut y avoir de nombreux réseaux privés qui utilisent ces plages d’adresses. Il n’y a donc pas de problèmes à utiliser ces adresses car elles ne sont à personne (ou plutôt à tout le monde). Maintenant, si on place une machine qui est reliée à notre réseau privé et aussi à Internet, cette machine peut dialoguer à la fois avec toutes les machines sur Internet grâce à sa carte, son modem… relié à Internet et aussi avec toutes les machines qui sont sur notre réseau privé. Mais les machines du réseau privé ne peuvent pas dialoguer avec une machine sur Internet car leur adresse réseau n’est pas connue sur Internet, la machine avec laquelle on veut dialoguer ne saura donc pas où renvoyer le résultat. Il suffit pour résoudre ce problème de placer un proxy http sur la machine qui est reliée à Internet et de l’utiliser pour toutes les autres machines du réseau privé. Du coup, la machine qui fait les demandes au serveur web est la machine qui a une adresse Internet valide et qui peut donc dialoguer avec le serveur Web.
– Une dernière application c’est la possibilité de passer à travers un système de filtrage réseau. C’est rarement une utilisation que l’on met en avant mais elle existe bien. Par exemple, si je suis sur une machine avec une adresse Internet valide mais qu’entre ma machine est la machine destination il y a une autre machine qui fait suivre mes paquets réseaux mais qui avant de les faire suivre vérifie certaines régles et ne laisse passer qu’une partie de mes paquets qui sont autorisés. Pas les autres. Ce type de machine s’appelle un firewall. Dans le cas du web, le protocole utilisé pour échanger les fichiers (les pages web sont composées de plusieurs fichiers) et le protocole HTTP. Ce protocole est généralement utilisé au dessus du protocole TCP lui même basé sur le protocole IP. Un protocole est une convention à respecter pour que les machines se comprennent. Notre firewall comprend généralement le protocole TCP mais pas HTTP. Dans le protocole TCP, un numéro appelé numéro de port permet au protocole TCP de savoir à quelle application qui tourne sur un ordinateur il faut donner le paquet. La plupart des serveurs web (programmes qui comprennent le protocole HTTP et renvoient les fichiers demandés) se trouve derrière le port 80. Maintenant, il suffit d’interdire dans le firewall les paquets TCP avec le port 80 comme destination pour interdire aux gens de surfer sur le web. Si on veut seulement controler ce qu’ils font sur le web, on place un proxy http, on configure leur navigateur pour qu’ils l’utilisent et on interdit l’accès direct (sans passer par le proxy) pour aller sur le web. Seul le proxy est alors autorisé à aller sur le web. Seulement, il est très fréquent que le firewall autorise des paquets TCP avec d’autres ports que le port 80 à passer sur Internet. En effet, il existe des applicatifs qui ont besoin d’un accès direct ou qui n’ont pas de proxy. Ces paquets peuvent donc passer à travers le firewall. Maintenant, si l’on dispose d’une machine sur Internet sans firewall. Il suffit de placer sur cette machine un proxy web et configurer notre machine locale (celle qui est limitée par le firewall) pour utiliser ce proxy web. Seulement, si on veut que cela fonctionne (le firewall laisse passer), il suffit de faire démarrer le proxy http sur un port TCP qui est autorisé par le firewall. Bref de faire croire au firewall qu’il s’agit d’un serveur pour un autre type d’application qui est autorisée. Comme applications autorisées, on trouve souvent :
— POP3, qui sert à consulter ses emails. POP3 est sur le port TCP 110 ou UDP (un autre protocole) 110.
— FTP, qui sert aux échanges de fichiers (un peu comme HTTP). On le trouve sur le port TCP 21 (et aussi 20 dans l’autre sens).
— SMTP, qui permet le transfert de mail entre serveur de mail. On le trouve sur le port TCP 25.
— et bien d’autres protocoles…
Maintenant que vous savez ce qu’est un proxy http et à quoi cela sert, je vous présente le code perl d’un petit proxy http qui ne fait pas de cache, ni de filtrage, qui ne supporte que la commande GET du protocole HTTP et qui peut démarrer sur n’importe quel port TCP. Voici le code :
#!/usr/bin/perl
use strict;
use Socket;
use Carp;
my $EOL = "\015\012";
sub spawn; # forward declaration
my $port = shift || 2345;
my $proto = getprotobyname('tcp');
$port = $1 if $port =~ /(\d+)/; # untaint port number
socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR,pack("l", 1)) || die "setsockopt: $!";
bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
listen(Server,SOMAXCONN) || die "listen: $!";
my $waitedpid = 0;
my $paddr;
sub REAPER {
$waitedpid = wait;
$SIG{CHLD} = \&REAPER; # loathe sysV
}
$SIG{CHLD} = \&REAPER;
for ( $waitedpid = 0;
($paddr = accept(Client,Server)) || $waitedpid;
$waitedpid = 0, close Client)
{
next if $waitedpid and not $paddr;
my($port,$iaddr) = sockaddr_in($paddr);
my $name = gethostbyaddr($iaddr,AF_INET);
spawn sub {
# start
my $cmd = "";
my $line;
while ((defined($line = <Client>)) && (($cmd .= $line) !~ /\n[\t\s]*\n/s)) {
}
my ($remote,$port, $iaddr, $paddr, $proto, $line);
($remote) = ($cmd =~ /http:\/\/(.*?)\//s);
if ($remote =~ /^(.*):(.*?)$/) {
$remote = $1;
$port = $2;
} else {
$port = 80;
}
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
die "No port" unless $port;
$iaddr = inet_aton($remote) || die "no host: $remote";
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect(SOCK, $paddr) || die "connect: $!";
send(SOCK,"$cmd\n",0);
while (defined($line = <SOCK>)) {
send(Client,$line,0);
}
close (SOCK) || die "close: $!";
# end
};
}
sub spawn {
my $coderef = shift;
unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
confess "usage: spawn CODEREF";
}
my $pid;
if (!defined($pid = fork)) {
print "cannot fork: $!";
return;
} elsif ($pid) {
return; # I'm the parent
}
# else I'm the child -- go spawn
exit &$coderef();
}
Si vous ne voulez pas faire de copier coller, ci-joint le fichier : proxy-http
Son utilisation est simple. Il suffit d’avoir un interpréteur perl installé sur sa machine d’y placer le fichier et de l’exécuter. Ce script n’a été testé que sous Linux avec perl version 5.6.0. Il prend au paramêtre le numéro de port sur lequel il attend les requêtes http.
Voici un exemple d’installation :
# chmod +x proxy.pl
# proxy.pl 6666
Il ne rend pas la main. Vous pouvez alors l’utiliser. Pour l’arrêter, il suffit de faire Ctrl-c.
Voici un exemple d’utilisation sans navigateur web (ouvrir un autre terminal que celui de la commande proxy.pl 6666 pour taper ces commandes) :
# telnet localhost 6666
Trying 127.0.0.1...
Connected to daniel.
Escape character is '^]'.
GET http://www.linux.com/ HTTP/1.0
HTTP/1.1 200 OK
Date: Sat, 23 Jun 2001 14:05:40 GMT
Server: Apache-AdvancedExtranetServer/1.3.19 (Linux-Mandrake/3mdk) mod_ssl/2.8.2
OpenSSL/0.9.6
Connection: close
Content-Type: text/html
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
... contenu de la page ...
</body>
</html>
Connection closed by foreign host.
La commande que je tape est GET http://www.linux.com/ HTTP/1.0 suivit de 2 retours à la ligne (touche Entrée). C’est une partie du protocole HTTP.
Si vous démarrez le proxy sur un port TCP inférieur à 1024, il faut être l’utilisateur root sur la machine Linux.
Si la programmation réseau perl vous interresse, sachez que ce proxy est fait à partir des exemples d’applications réseaux en perl que l’on peut consulter en tapant man perlipc.
Encore une chose, mon code est libre de droit et je ne suis en rien responsable de ce qu’il peut vous arriver en l’utilisant. N’en faites pas mauvais usage.