ExaProxy est un nouveau proxy HTTP s'ajoutant à une longue liste de logiciels libres (SQUID, haproxy, varnish, tinyproxy…). Il se place dans le secteur de niche des proxy filtrants principalement desservis commercialement par des entreprises comme BlueCoat ou Fortinet.
Dans ce domaine, SQUID est la plus connue des solutions libre grâce à une interface simple permettant l’écriture rapide de modules de filtrage qui reçoivent l'IP de hôte connecté avec la requête faite. SQUID supporte aussi ICAP/eCAP pour ceux qui veulent modifier la requête et la réponse du serveur.
Cependant, afin d'avoir un filtrage différent par IP d'origine, il est impossible d'utiliser SQUID avec un load balancer de niveau 7, comme haproxy, qui change l'IP d'origine. Seules les solutions de haute disponibilités ré-écrivant l'adresse MAC de destination (comme ipvsadmin) sont adaptées. De plus, SQUID ne présente pas les requêtes de type CONNECT.
ExaProxy est donc un forward proxy permettant de filtrer ou router le trafic transitant dans un cluster de manière très souple, et permet l'utilisation du header X-Forwaded-For quand l'IP de l’hôte est masquée. Une autre utilisation peut être comme passerelle entre machines IPv4 et IPv6.
Le fonctionnement du serveur peut-être observé via une interface web sur le port local 8080.
Ce proxy, bien qu’écrit en Python, a été conçu pour remplacer SQUID dans un cluster de serveurs sous forte charge. Afin d’être performant, l'application utilise un arsenal de techniques de programmation :
- un réacteur asynchrone (epoll ou select) ;
- une gestion par événements de la machine d'état (state-machine) ;
- l'utilisation de co-routines (plus légères que des threads) pour la gestions des connections TCP ;
- une résolution DNS UDP/TCP interne intégrée dans le coeur (
gethostbyname
est une fonction bloquante) ; - une communication entre threads et le coeur par messages ;
- une gestion automatique du nombre de threads nécessaire pour une bonne montée en charge.
Beaucoup de scripts (certains compatibles avec le format SQUID) sont présents avec le code comme :
- comment éditer un cookie pour par exemple, toujours avoir des résultats YouTube filtrés ;
- comment présenter https://www.wolframalpha.com/ quand https://www.google.com/ a été demandé, sans que le butineur n'affiche de problème de certificat SSL ;
- comment servir des fichiers locaux à la place de la page demandée ;
- comment servir un contenu généré depuis le script lui-même.
Le proxy est considéré assez stable pour être utilisé en production par quelques beta-testeurs, une version 1.0.0 devrait voir le jour début mars. Les auteurs recherchent donc activement des retours d’expérience autre que la leur.
Aller plus loin
- ExaProxy (768 clics)
- Interface SQUID (333 clics)
- ICAP (126 clics)
- Forward Proxy (164 clics)
# c'est pas un peu compliqué tout ca
Posté par fredezic . Évalué à 3.
je sais pour vous, mais sincèrement à la 1ere lecture j'ai pas compris grand chose
je ne pense pas que tous les lecteurs de linuxfr soit des experts en proxy, c'est dommage le domaine m’intéresse mais pour moi cette news est trop complexe
[^] # Re: c'est pas un peu compliqué tout ca
Posté par MrLapinot (site web personnel) . Évalué à 3.
C'est surtout très verbeux. Par exemple :
se résume tout bêtement à :
Pas besoin de rentrer dans les détails, ceux qui savent ce qu'est du code à événement infèrent les détails à partir de la simple information « style à événements », et ceux qui ne savent pas ont au moins une vague idée de ce que ça implique.
(Et en plus, la dépêche induit le doute avec tous ces détails ; par exemple, même si c'est ma spécialité, je ne suis pas sûr de comprendre le lien entre les événements, coroutines et threads mentionnés dans cette énumération.)
[^] # Re: c'est pas un peu compliqué tout ca
Posté par Thomas Mangin (site web personnel) . Évalué à 2.
Les threads sont necessaires pour gerer les programmes forkes qui contiennent la logique de filtrage. Sans elles, le code serait bloquant quand le programme de filtrage est lent. Ces threads communiquent via messages a la thread principale afin de ne pas avoir besoin de lock dans le code. Les coroutines sont gere par le reacteur et s'occupent des connections TCP.
trop verbeux mais pas assez pour etre clair :)
[^] # Re: c'est pas un peu compliqué tout ca
Posté par MrLapinot (site web personnel) . Évalué à 2.
Je n’avais pas vu que c’était un Python, je comprends mieux la notion de coroutines du coup.
J’apprécie aussi les scripts fournis pour faire un service runsv.
# redirection HTTPS
Posté par jame_s . Évalué à 2.
Je suis curieux : comment fait on pour remplacer un site https par un autre sans alerte de certificat SSL ?
[^] # Re: redirection HTTPS
Posté par Thomas Mangin (site web personnel) . Évalué à 3.
Google propose https://nosslsearch.google.com/ avec un certificat google valide, qui redirige vers son site http://www.google.com/ . En redirigant la premiere requete vers ce site, la second requete peut alors etre redirige / repondu par le proxy.
Alternativement si le browser utilise le proxy directement et demande un tunneling pour HTTPS, il est possible de retourner un 302 redirect comme reponse au CONNECT et rediriger le browser autre part.
[^] # Re: redirection HTTPS
Posté par steph1978 . Évalué à 3.
c'est justement à ce moment que le navigateur va gueuler, car le proxy va lui présenter un certificat qui ne correspond pas à "nosslsearch.google.com", non ?
je ne vois pas où le proxy s'insère dans la séquence suivante:
[^] # Re: redirection HTTPS
Posté par Thomas Mangin (site web personnel) . Évalué à 3.
Non, il ne va pas geuler, car google presente un star certificate (CN=*.google.com) qui marche pour tous les sous domaines google.com. Pour verifier verifier :
changer ses proxies HTTP/HTTPS pour 127.0.0.1, entrer l'url https://www.google.com/ regarder le contenu de la page.
[^] # Re: redirection HTTPS
Posté par steph1978 . Évalué à 2.
Je vois un
dans mon navigateur
Et un
dans les logs du proxy.
[^] # Re: redirection HTTPS
Posté par Thomas Mangin (site web personnel) . Évalué à 2.
La version doit etre superieure ou egale a 533 (version de Vendredi).
Si ce n'est pas le cas, re-essayer apres un :
Si c'est le cas, peux-tu m'envoyer par email les logs complets (car je n'ai pas ce probleme).
# X-Forwarded-For
Posté par PLuG . Évalué à 2.
A priori un proxy filtrant c'est fait pour ne pas être contourné, alors attention aux headers X-Forwarded-For qui sont très simples à générer.
Imaginons un proxy qui laisse passer certaines requetes web selon la station cliente en se basant sur le champ X-Forwarded-For. Il suffit que la machine cliente injecte un header X-Forwarded-For pour se faire passer pour une autre …
Il faut donc absolument
- être sur un réseau sur lequel on maitrise les IP
- que le proxy filtrant valide que l'adresse IP de laquelle vient la requete est bien un "trusted proxy". Si on autorise les cascades de proxys, il faut valider toute la chaine des proxy qui ont été traversés. Cette chaine doit être présente dans le (ou les) header(s) X-Forwarded-For.
Car il y a 2 méthodes possibles dans la RFC: chainer les adresses IP dans le même header (séparées par des virgules), ou ajouter un header a chaque fois que l'on traverse un proxy. Du coup les produits (apache, jboss, haproxy, …) implementent rarement les deux solutions et ne sont pas forcement compatibles entre eux :-(
Bref le X-Forwarded-For pour gérer de la sécurité c'est vraiment quand on n'a pas trouvé mieux !
[^] # Re: X-Forwarded-For
Posté par Thomas Mangin (site web personnel) . Évalué à 1. Dernière modification le 02 mars 2012 à 01:01.
Ce n'est pas faux, il faut bien faire attention a ce header. ExaProxy utilise la dernière valeur du header comme le demande haproxy dans sa documentation (http://haproxy.1wt.eu/download/1.3/doc/configuration.txt
"option forwardfor")
Comme haproxy donne le choix d'un autre nom pour ce leader, j'ajouterai demain une option pour changer ce nom et aussi enlever ce header de la requête quand elle passe a travers le proxy.
J'espère que cette sécurité par l'obscurité satisfera les utilisateurs les plus exigeants.
[^] # Re: X-Forwarded-For
Posté par Joris Dedieu (site web personnel) . Évalué à 2. Dernière modification le 02 mars 2012 à 08:44.
Willy a proposé une solution élégante (je trouve) au problème. Il s'agit d'un protocole de communication entre les diverses couches de proxy décrit ici : http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
Le problème originel consiste à passer l'information sur l'ip réelle du client depuis stunnel vers haproxy. Mais cela peut avoir d'autres applications bien sympas, comme remplacer le X-Forwarded-For par exemple.
Pour l'heure c'est implémenté (que je sache) dans stunnel, haproxy et stud. Mais je pense que c'est un mécanisme qui gagnerai à être déployé largement
[^] # Re: X-Forwarded-For
Posté par Thomas Mangin (site web personnel) . Évalué à 2.
Cool, merci beaucoup pour cette information. Ce n'est pas dur a ajouter et c'est en effet bien pratique.
[^] # Re: X-Forwarded-For
Posté par Olivier Jeannet . Évalué à 2.
Les proxys ça ne devrait pas exister, enfin, les PALC :
« Pour la fin des P.A.L.C. (Proxys à la con) » http://blog.ronez.net/?p=708
« Le proxy à la con (PALC) » http://padawan.info/fr/2007/09/le-proxy-a-la-con.html
[^] # Re: X-Forwarded-For
Posté par Thomas Mangin (site web personnel) . Évalué à 2.
LOL !
Regardons le trafic de ma societe (un FAI pour entreprise) vers Facebook (la partie qui ne va pas chez Akamai). Le trafic correspond bien aux heures de
travaildetente d'entreprise.Le proxy a la *** est une consequence des actions des employees. Il y a d'autres facteurs comme des certifications ISO toutes aussi stupides.
Maintenant mon proxy a ete concu pour les ecoles ou le filtrage est obligatoire, c'est pas ma faute si on vit dans des pays liberticides.
# Commentaire supprimé
Posté par Anonyme . Évalué à 4.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: EPool ?
Posté par MrLapinot (site web personnel) . Évalué à 2.
Ils codent en python, alors forcément, il y a des majuscules partout ;-)
http://code.google.com/p/exaproxy/source/browse/lib/exaproxy/network/async/epoll.py
[^] # Re: EPool ?
Posté par netsurfeur . Évalué à 2.
Je ne crois pas que la remarque portait sur la majuscule mais plutôt sur la confusion entre poll et pool. Les deux mots sont utilisés en informatique et sont souvent confondus.
[^] # Re: EPool ?
Posté par claudex . Évalué à 4.
C'est corrigé, merci.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # libevent ?
Posté par Fabien . Évalué à 1.
Pourquoi ne pas utiliser libevent au lieu d'attaquer directement epoll ?
[^] # Re: libevent ?
Posté par Thomas Mangin (site web personnel) . Évalué à 2.
ExaProxy doit être facile à installer sur un serveur, même embarqué, nous ne voulons donc pas avoir de dépendances autre que python lui-meme.
libevent sous python est une librarie (http://code.google.com/p/pyevent/) qui nécessite d'être compilée et installée ou un paquet pour la distribution, alors qu'epoll est disponible dans la librairie standard (from select import epoll).
[^] # Re: libevent ?
Posté par Joris Dedieu (site web personnel) . Évalué à 2.
libevent n'est pas qu'une abstraction pour epoll. Il gère la portabilité (kqueue, /dev/poll…). Du coup sous *BSD ou Solaris ton proxy utilise select ce qui est … lent
[^] # Re: libevent ?
Posté par Thomas Mangin (site web personnel) . Évalué à 1.
kqueue est disponible pour les versions BSD et MAC de python, ecrire un reacteur kqueue est donc possible. Nous ne l'avons pas fait car ce n'est pas une priorite pour nous et je veux pouvoir utiliser le logiciel en production sous peu.
select est clairement plus lent que kqueue mais ce n'est pas non plus la fin du monde …
Si quelqu'un veut ecrire le patch pour ajouter kqueue, je suis prenneur ou si des utilisateurs me font savoir que kqueue est important pour eux, nous l'ajouterons.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.