Proxy HTTP(s) gatejs

Posté par  . Édité par Xavier Teyssier, Benoît Sibaud, Pierre Jarillon et rootix. Modéré par ZeroHeure.
20
20
juin
2014
JavaScript

gatejs est un nouveau mandataire/proxy HTTP(s) (forward & reverse) qui a pour vocation de remplacer squid, nginx, varnish ou encore apache, dans leurs fonctions de proxy (forward & reverse). Il est publié sous licence GPLv3.

Il est développé en JavaScript (2/3) et en C++ (1/3). Il est prévu que la proportion de C++ se réduise au fil du temps. Ce proxy utilise le moteur Javascript V8 et nodejs.

Il a été initialement conçu pour offrir plus de flexibilité sur l'interception et le traitement d'informations en HTTP.

Pour ceux qui ne sont pas pro-JavaScript, il est important de préciser que les performances de gatejs sont proches, voire dans certains cas, supérieures à nginx.

De plus, l'utilisation de Javascript permet d'augmenter la lisibilité des codes, de les factoriser et de renforcer la sécurité, surtout pour des opérations complexes.

Les configurations sont écrites au moyen de la notation d'objets Javascript (JSON).

Ci-dessous une liste de fonctionnalités déjà implémentées :

  • gestion de HTTP 0.9, 1.0, 1.1, Websocket, quic, spdy ;
  • gestion de SSL forward & reverse + SNI ;
  • reverse proxy, stream primary & secondary, pondération, détection de panne, load-sharing iphash / round-robin ;
  • le forward proxy peut transmettre les requêtes en utilisant le champ Host HTTP, mais peut aussi utiliser l'adresse de destination directement ;
  • implémentation généralisée de TPROXY qui permet de spoofer les adresses IP (source ou destination) pour une utilisation totalement transparente ;
  • système de cache ACN (Associative Cache Network) qui permet de mettre en cache les données HTTP forward et/ou reverse et de les partager entre différents serveurs via du multicast ;
  • gestionnaire de greffons très simple mais scalable à souhait ;
  • traitement des requêtes HTTP par un système de pipeline et d'opcodes ;
  • gestion de l'exécution parallèle de plusieurs workers autonomes ;
  • gestion de l'utilisation simultanée des options forward et reverse proxy.

Les sources de gatejs étaient fermées pendant plusieurs années, mais différentes raisons ont amené ses créateurs à rendre ouvert ce travail.

Aujourd'hui, gatejs est utilisable en production, les codes initiaux ont déjà vécu et vivent encore en production depuis plusieurs années.

Nous aimerions maintenant pousser gatejs plus loin avec une communauté de développeurs et utilisateurs fidèles.

Aller plus loin

  • # Enfin un choix raisonnable

    Posté par  . Évalué à 10.

    De plus, l'utilisation de Javascript permet d'augmenter la lisibilité des codes

    La preuve en s'amusant sans fin

  • # Mmrffff

    Posté par  . Évalué à 4.

    Publier ça un vendredi… c'est ballot.

    • [^] # Re: Mmrffff

      Posté par  . Évalué à 0.

      Faudra le repost …. je ne suis pas un expert de la comm.. :]

  • # Références

    Posté par  (site web personnel) . Évalué à 10.

    Pour ceux qui ne sont pas pro-JavaScript, il est important de préciser que les performances de gatejs sont proches, voire dans certains cas, supérieures à nginx.

    Dans quels cas?

    Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html

    • [^] # Re: Références

      Posté par  . Évalué à 7.

      Bonne question, nous faisons des tests permanent mais non structurés. Cependant le premier test à réaliser serait de prendre une image caché par nginx & gatejs puis de mesurer le nombre requêtes par secondes. À ce test et avec un nombre de 100 connexions concurrentes nginx est plus performant (~2,5x) cependant la donne change quand on monte en nombre de connexions concurrentes nginx dérouille rapidement (à partir de 10 000) ce qui n'est le cas de gatejs.
      Gatejs est clairement plus asynchrone que nginx ce qui pourrait expliquer cela.
      Nous avons une production qui utilise gatejs et qui handle 250 000 connexions actives.
      Aussi l'écart de traitement des requêtes via gatejs est largement plus stable qu'avec nginx.
      Autant ne pas parler de Squid qui est complètement hors course.

      Des tests plus poussés doivent être réalisés mais il nous manque de ressources actuellement pour pouvoir le faire dans les règles de l'art.

      • [^] # Re: Références

        Posté par  . Évalué à 6.

        Nous avons une production qui utilise gatejs et qui handle 250 000 connexions actives.

        C'est bête de pas pouvoir indiquer un site de test à faire tomber, c'est probablement la meilleure pub pour vous!

        ⚓ À g'Auch TOUTE! http://afdgauch.online.fr

      • [^] # Re: Références

        Posté par  (site web personnel) . Évalué à 5.

        […] il nous manque de ressources actuellement […]

        Je rejoins zezinho, un bon moyen de démontrer que votre outils poutre des mamans plantigrades, c'est de poster cet article avec un lien vers l'un de vos accès utilisant gatejs, sur slashdot, reddit et ici-même.

        Si ça ne crashe pas, vous pourrez ensuite montrer à tout le monde des jolis graphiques avec watt-mille connexions "handlées" par javascript.

        Et si ça plante, et bien vous aurez fait un test extrême de charge qui pourra sûrement vous aider à "handler" à terme la totalité de l'espace d'adresse IPV6 qui se connecterait au même moment à votre service.

      • [^] # Re: Références

        Posté par  (site web personnel) . Évalué à 1.

        Autant ne pas parler de Squid qui est complètement hors course.

        A quel point ? En testant avec les workers ?
        Avez vous aussi fait une comparaison en forward avec une utilisation Internet classique sortante et des centaines/milliers d'utilisateurs (et du coup un cache conséquent) ?

    • [^] # Re: Références

      Posté par  . Évalué à 2.

      et en C++ (1/3)

  • # Quelques questions

    Posté par  (site web personnel) . Évalué à 10.

    Gatejs pourrait être intéressant mais j'ai du mal à comprendre ce qu'il fait précisément et pourquoi il serait mieux que les autres solutions citées (ou haproxy dont la version 1.5 vient juste de sortir).

    Il a été initialement conçu pour offrir plus de flexibilité sur l'interception et le traitement d'informations en HTTP.

    Ce serait possible d'avoir un cas d'usage ? J'ai un peu regardé les exemples sur le wiki mais j'ai l'impression que je pourrais faire tout aussi bien avec les autres outils.

    Les configurations sont écrites au moyen de la notation d'objets Javascript (JSON).

    Dans le wiki, ce sont des modules nodejs avec une fonction qui renvoie un objet JavaScript. J'ai du mal à voir l'intérêt de cette approche. Ça va fait plus de bruit que juste un bout de JSON, mais sans permettre d'aller chercher des bouts de cette configuration dans un fichier, une base de données, une API Rest (il faudrait de l'asynchrone pour ça).

    support SSL forward & reverse + SNI

    Pour la prise en charge de SSL, est-ce que cela inclut les trucs sympas comme le Forward Secrecy ou l'OCSP stapling ? Quelle est la bibliothèque SSL utilisée ? OpenSSL ? GnuTLS ?

    traitement des requêtes HTTP par un système de pipeline et d'opcodes

    C'est-à-dire ? À quoi ressemble un opcode ?

    support de l'exécution parallèle de plusieurs workers autonomes

    Sur la même machine ? Comment se répartissent-ils le boulot ?

    • [^] # Re: Quelques questions

      Posté par  . Évalué à 6. Dernière modification le 20 juin 2014 à 18:37.

      Gatejs pourrait être intéressant mais j'ai du mal à comprendre ce qu'il fait précisément et pourquoi il serait mieux que les autres solutions citées (ou haproxy dont la version 1.5 vient juste de sortir).

      gatejs est un bundle complet de proxy(ing) HTTP, en ce sens il regroupe des fonctionnalités de plusieurs soft tel que nginx ou squid.
      Je ne me suis pas posé la question par rapport à haproxy, mais je pense qu’au-delà des performances la flexibilité ira au bénéfice de gatejs.

      Ce serait possible d'avoir un cas d'usage ? J'ai un peu regardé les exemples sur le wiki mais j'ai l'impression que je pourrais faire tout aussi bien avec les autres outils.

      Les cas sont multiple mais globalement avoir des requêtes HTTP modifiables qui passent par du Javascript facilite énormément les taches de debug ou d'audit
      Pour exemple, pour optimiser le cache il est essentiel de pouvoir regrouper les urls entre elles. Pour être encore plus précis, Grooveshark par exemple délivre les musiques via un système de post HTTP qui empêche pratiquement n'importe quel proxy de cacher cette données (la musique).
      gatejs embarque un opcode store qui et comparable au vieux store_url de squid (qui n'est plus disponible maintenant) et qui été fort utile pour regrouper les URLs, cependant même lui ne permet pas de faire cette opération.
      Va voir ça http://pastebin.com/3J7jaVmB cet exemple est pour moi le plus parlant en matière de flexibilité. J'estime qu'il est pas possible de faire plus simple pour le moment tout en aillant des performances et sans risque sécurité.

      Dans le wiki, ce sont des modules nodejs avec une fonction qui renvoie un objet JavaScript. J'ai du mal à voir l'intérêt de cette approche. Ça va fait plus de bruit que juste un bout de JSON, mais sans permettre d'aller chercher des bouts de cette configuration dans un fichier, une base de données, une API Rest (il faudrait de l'asynchrone pour ça).

      je ne comprend pas ce que tu dis :( Nous utilisons nodejs comme preloader à v8. Nos modules sont développés pour v8 et chargés par nodejs.

      Pour la prise en charge de SSL, est-ce que cela inclut les trucs sympas comme le Forward Secrecy ou l'OCSP stapling ? Quelle est la bibliothèque SSL utilisée ? OpenSSL ? GnuTLS ?

      Oui le PFS est supporté, il faut simplement lui demander d’honorer l'ordre d'utilisation des cyphers et de spécifier ECDHE. OpenSSL, mais on a rien senti de heartbleed car il est embarqué en static dans nodejs.

      C'est-à-dire ? À quoi ressemble un opcode ?

      À ca : https://github.com/binarysec/gate/blob/master/src/lib/http/js/pipeForward/headers.js
      Et tu l'utilises comme ça dans un pipeline : https://github.com/binarysec/gate/wiki/OpcodeHeaders

      Sur la même machine ? Comment se répartissent-ils le boulot ?

      Oui, j'aime dire que chaque processes est atomique à lui même, il n'y a aucun lock ni threads. Les processes communiques entre eux via un système IPC (qui s'étend au réseau via NPC). Tien tu veux voir le système IPC ? https://github.com/binarysec/gate/blob/master/src/lib/core/js/ipc.js il est intéressant d'aller voir celui de nginx ou apache…

    • [^] # Re: Quelques questions

      Posté par  . Évalué à 5.

      Ce serait possible d'avoir un cas d'usage ? J'ai un peu regardé les exemples sur le wiki mais j'ai l'impression que je pourrais faire tout aussi bien avec les autres outils.

      J'ai déjà été confronté à ce genre de problématiques, quand nous avions voulu réécrire une application HTTP existante.

      Pour cela, j'ai implémenté un reverse-proxy avec Python 3, AsyncIO et aiohttp en quelques lignes, puis en fonction de l'URL, soit ça appelait la nouvelle application, soit ça enrichissait la réponse de l'ancienne, soit ça laissait passer en direct les informations.
      J'ai pu ainsi réécrire l'application petit à petit, sans avoir de moments où la vieille application n'évoluait plus, alors que la nouvelle n'était pas encore finie.

  • # Support du caching par chunk ?

    Posté par  (site web personnel) . Évalué à 6. Dernière modification le 21 juin 2014 à 01:23.

    Vous supportez le caching des requètes partielles utilisant le header "Range" ?

    (Range query ou Vector queries)

    C'est une fonctionalité qui manque énormement sur squid, Varnish ou reverse nginx quand on travaille sur des grands objets (vidéos ou autres).

    Si c'est le cas, vous avez un client.

    • [^] # Re: Support du caching par chunk ?

      Posté par  . Évalué à 2.

      Vous supportez le caching des requètes partielles utilisant le header "Range" ?

      Oui mais nous ne reconstruisons pas le fichier, malheureusement.
      Les cas de range sont très complexe mais pas impossible à gérer.
      Le problème majeur dans le caching en mode chunk est la performance nécessaire à la gestion de ce dernier.

      Si les ranges sont les mêmes alors gatejs ajoutera le Range dans l'url (via le store) pour cacher le chunk.

      • [^] # Re: Support du caching par chunk ?

        Posté par  (site web personnel) . Évalué à 1. Dernière modification le 23 juin 2014 à 08:16.

        Le problème majeur dans le caching en mode chunk est la performance nécessaire à la gestion de ce dernier.

        Si les ranges sont les mêmes alors gatejs ajoutera le Range dans l'url (via le store) pour cacher le chunk.

        C'est toujours mieux que rien, Squid & Varnish sont assez stupides pour fetcher le contenu complet de la resource. Ce qui produit des résultats assez "interessants" quand quelqu'un veut lire 50Mo d'un fichier de 3Go…

  • # Ouvert, libre et contribution

    Posté par  . Évalué à 7.

    Les sources de gatejs étaient fermées pendant plusieurs années, mais différentes raisons ont amené ses créateurs à rendre ouvert ce travail.

    Quelles sont les raisons de rendre ouvert ?
    Sur linuxfr, je me serais attendu, justement, à ce que ce soit développé, ce serait justement l'un des points les plus importants, les raisons et la façon dont cela a été fait. Le pourquoi du comment et toute l'histoire.

    Apparemment, le projet est :

    Mais j'ai beau cherché dans le wiki ou dans le README, il n'y a pas de direction pour la façon de contribuer.
    Que ce soit pour la création de ticket de bug, de ticket d'évolution, de contribution de documentation ou de code proprement dit.

    Donc c'est libre (on a le droit de forké) mais ça reste fermé ?

    En me relisant, je me rends compte que c'est un peu aigri, mais je ne sais pas le tourner de manière différente, désolé. Je m'intéresse surtout aux raisons qui poussent une entreprise à rendre un projet libre :

    • projet poubelle => on ne veut plus s'en occuper
    • publicité sur le savoir-faire => vous pouvez l'utiliser mais on garde exclusivement le cotnrole
    • rendu à la communauté => on utilise du libre, donc on veut redonner une partie de ce que l'on a gagné à la communauté
    • manque de personnel / principaux développeurs partis => on ne sait plus le gérer, on n'a plus les moyens de le gérer, mais c'est toujours utilisés, il faut que ce soit maintenu
    • projet fini et donc plus financé => on le libère, ça fera de la publicité pour la boite et certains le maintiendront gratuitement.

    Bref, plein de raisons (pas mutuellement exclusives), plein de façons de faire. Quels sont vos choix, et pourquoi ?

    • [^] # Re: Ouvert, libre et contribution

      Posté par  . Évalué à 10.

      Sur linuxfr, je me serais attendu, justement, à ce que ce soit développé, ce serait justement l'un des points les plus importants, les raisons et la façon dont cela a été fait. Le pourquoi du comment et toute l'histoire.

      BinarySEC est une société spécialisée en sécurité informatique. Elle a été fondée en 2007, initialement nous avions développé un outils de protection des binaires pour prévenir une bonne partie des types de buffer overflow existants. Cependant après quelques mois nous nous sommes aperçu que cela serait complexe à vendre et surtout à maintenir.

      Aussi nous avions remarqué que les attaques les plus violentes et les plus répandues passent par HTTP et là malheureusement l'outil de détection de BOF ne servait pas à grand chose.
      Alors j'ai décidé à l'époque de penser un nouveau système de protection des sites Internet. Il fallait quelque chose de simple donc en opposition totale avec mod_security etc… J'ai donc pensé un système de corrélation sous forme d'IA faible et cela a permis d'éliminer le risque de faux positifs à hauteur de 90%.

      La première implémentation était un module Apache mais rapidement on nous a demandé une solution en proxy (reverse). À l'époque il n'y avait vraiment que nginx comme solution fiable au reverse proxy, exit squid, varnish et… Apache.

      Nous avons donc implémenté l'interface serveur sur nginx et nous avons été très satisfait des performances de ce soft. Parallèlement nous auditions nginx et c'est à ce moment que nous nous sommes dit qu'il fallait vraiment revoir cela. Inutile de me demander des résultats précis, je vais juste vous dire que nous avons évité plusieurs buffer overflow en production de justesse et sincèrement pour un produit de sécurité ce n'était pas vraiment acceptable…

      Parallèlement on nous a aussi demandé des solutions forward squid based où là encore nous avons eu quelques frayeurs.

      Malheureusement à cette époque nodejs & v8 n'était pas encore stable/fiable pour pouvoir effectuer les opérations nécessaires aux applications reverse & forward proxy. Mais j'avais immédiatement détecté que ce serait le moyen le plus safe d'effectuer des opérations de proxy (ou de serveur) dans le futur. Voir même plus. Mais je ne détaillerais ici.

      J'adore ce lien http://bellard.org/jslinux/

      Il faut bien comprendre que tout cela est possible grâce à v8 qui correspond à une vraie révolution en matière d'informatique technique. Sans cela gatejs n'aurait pas d’intérêt… Pour la faire simpliste, v8 compile du JS en assembleur. nodejs en lui même est très simple et correspond pour ma part à un preloader, il est lui même codé à 70% en JS.

      Bref, j'ai estimé que pour pouvoir augmenter la sécurité il fallait absolument réduire la verbosité d'un langage. Actuellement j'estime prendre bien moins de risque avec gatejs et je n'ai aucune limite à la réalisation de plugins.

      Reste maintenant les risques de sécurité liés à la logique de design mais là encore c'est plus complexe avec le JS simplement parce que ce n'est pas(plus) un simple langage de scripting accessible à monsieur tout le monde, ce n'est pas PHP et il aura du mal à le remplacer du simple fait qu'il faut plus de compétences pour coder en JS. Un expert qui prend en main Javascript a ses sens en ébullitions :) À l'inverse un kiddy aura du mal.

      Pour le choix de l'open source, c'est un peu complexe à détailler ici mais il remonte à bien longtemps et il a fallu convaincre des personnes. Je pense que c'est un gage de confiance et d'assurance dans mon secteur. Compliqué pour ma petite société de convaincre à passer sur des solutions closed sources inconnues. J'espere que cela fera évoluer les choses. Je crois vraiment au modèle économique open source. Je crois que c'est l'avenir. Le problème est qu'il n'y a pas d'école et que tout le monde joue un peu l'empirisme. C'est là mon dilemme.

      Mais j'ai beau cherché dans le wiki ou dans le README, il n'y a pas de direction pour la façon de contribuer.

      On utilise Github massivement, donc fork + pull request. On est pas très au point sur les détails à préciser. Si vous avez des conseils sur la forme je suis preneur !

      Donc c'est libre (on a le droit de forké) mais ça reste fermé ?

      Non non ! Nous sommes dans le cadre de la GPLv3 et les contributions doivent simplement prendre la voie du workflow de Github et très sincèrement j’espère qu'il y aura d'autres contributeurs

      En me relisant, je me rends compte que c'est un peu aigri, mais je ne sais pas le tourner de manière différente, désolé. Je m'intéresse surtout aux raisons qui poussent une entreprise à rendre un projet libre :

      Pour répondre de manière fermée je dirais : publicité sur le savoir-faire, rendu à la communauté et manque de personnel
      Je pense donner quelques indices plus haut.
      Je crois que tout projet open source doit, d'une manière ou d'une autre, avoir une équipe core qu'il rémunère pour assurer la continuité professionnel du projet. Certain utilise le don d'autre le service ou encore la licence duel.
      Je crois beaucoup à la licence duel pour le cas de gatejs où un support pro serait proposé ou encore une garantie sur le fonctionnement (exclue de la GPL) mais aussi des développements spécifiques.

      • [^] # Re: Ouvert, libre et contribution

        Posté par  . Évalué à 2.

        J'adore ce lien http://bellard.org/jslinux/

        Oui oui, on sait : c'est toujours lui qui a la plus grosse… heu… technique… ;-D

        Je retiens l'idée d'être aussi efficace en proxy qu'en reverse. Pour les websockets c'est à tester. Mais vu que je les fais généralement passer dans un stunnel ça ne devrait pas poser trop de problèmes.

        L'autre avantage de Nginx c'est qu'il a un module de proxy mail. Quelque chose d'assez rare qu'on ne trouve que sur Perdition il me semble.

        • [^] # Re: Ouvert, libre et contribution

          Posté par  . Évalué à 2.

          Oui NGINX fait le mail Squid fait aussi le FTP ou le Gopher..
          Je pense que la prochaine feature de gate sera un serveur DNS.
          Le proxy mail est assez simple à réaliser, je vais regarder ce que je peux faire.
          J'aimerais aussi intégrer un serveurs Web complet dans gate… qui pourrait supporter pas mal de feature Apache pour migrer plus facilement…

        • [^] # Re: Ouvert, libre et contribution

          Posté par  (site web personnel) . Évalué à 3.

          Imapproxy existe aussi pour le mail (IMAP), c'est très utilisé par les webmail (et vraiment efficace) : http://www.imapproxy.org/

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.