Les hébergeurs diffèrent de par leurs offres, leur taille, etc, mais également de par leurs choix d’infrastructures. Or ces derniers, qui sont un vecteur majeur de l’efficacité d’une offre d’hébergement, sont souvent peu connus. NBS System se lance donc dans une série d’articles présentant ses infrastructures et les outils utilisés, pour plus de transparence et pour faire connaître cette partie cachée du secteur de l’hébergement informatique.

infra_NBS_RP

Qu’est-ce qu’un reverse proxy ?

Le terme « proxy », en anglais, signifie mandataire. Cela représente tout à fait la fonction de cet équipement : le Reverse Proxy (ou mandataire inverse, que l’on appellera RP dans l’ensemble de l’article) fait l’intermédiaire entre deux entités, en l’occurrence l’internaute et un serveur web (hébergeant le site auquel l’internaute veut accéder par exemple).

SéparationRP_mandataire

Il est important de noter que les RP ont une mission de séparation entre ces deux entités. En effet, l’internaute envoie une requête au RP, qui envoie lui-même une requête au serveur. Le serveur répondra alors au RP, qui transmettra alors la réponse à l’internaute. Il n’y a aucun échange direct entre l’internaute et le serveur : c’est la base du fonctionnement du RP. Ainsi, l’internaute n’a jamais accès directement au serveur, et toutes les requêtes passent par le RP. Cela a plusieurs avantages, que nous allons lister ci-dessous.

Confort / Simplification

balanceUn site doit être stable, performant et sécurisé. Or, ces trois conditions dépendent les unes des autres ; par exemple, améliorer la sécurité de son site entraînera une plus grande consommation des ressources du serveur, et donc baissera la performance générale du site. Ainsi, il est important pour un hébergeur infogérant tel que NBS System de collaborer avec son client, afin que la configuration du serveur (gérée par le premier) et celle de l’applicatif (gérée par le second) s’accordent pour arriver au meilleur équilibre possible entre ces trois leviers.

Les RP permettent également de jouer sur la performance, la stabilité et la sécurité, souvent beaucoup plus simplement que par une modification applicative. Grâce à la mise en place d’une configuration simple sur les RP, des opérations lourdes peuvent parfois être évitées, ce qui soulage grandement les équipes techniques du client. Cela permet également à l’hébergeur infogérant de s’assurer que certaines contraintes sont respectées, laissant aux équipes de développement applicatif plus de temps pour implémenter les modifications directement dans l’applicatif.

Performance

Concentrons-nous justement sur ce levier. Les RP améliorent la performance des sites en fournissant une couche de cache additionnelle, en plus de celles déjà existantes (applicatif, base de donnée, etc). Elle allège le travail des serveurs en stockant le résultat des requêtes afin de les renvoyer directement aux internautes effectuant la même requête. Les serveurs peuvent donc se consacrer à la gestion d’autres requêtes, pour un service encore plus rapide, et une capacité de traitement accrue sur une architecture applicative à périmètre équivalent.

RP_cache

Cette fonction de cache est contrôlée par l’applicatif de nos clients via les en-têtes (headers) http renvoyés en réponse à une requête http d’un internaute navigant sur le site. Cette configuration est générique et partagée par de nombreux hébergeurs. Le cache est donc actif, mais est par défaut configuré pour qu’aucun résultat ne soit stocké. Ce sont les en-têtes des réponses aux requêtes http effectuées auprès du serveur qui déterminent s’il faut que le RP mette le résultat en cache, pendant combien de temps, etc. Ainsi, les RP obéissent aux instructions du client.

Ex : « expires : +3d » dans un en-tête http envoyé par l’applicatif client signifie à notre RP qu’il peut garder en cache le résultat pendant trois jours.

Service

Les RP, en « filtrant » tout le trafic, nous permettent également d’avoir un suivi et des statistiques (web et sécurité) de l’activité du site (fichiers journaux, ou « logs »). C’est un service rendu au client, qui bénéficiera donc de statistiques précises, comme par exemple le nombre de visites uniques, de pages vues, etc. L’analyse en interne de ces statistiques nous permet également de conseiller au mieux nos clients, afin de les accompagner dans leur développement et dans la résolution de leurs problèmes.

Sécurité

Les informations collectées sur les RP (de manière anonyme) ont également un autre but. En effet, la configuration et les fonctions des RP sont parfois modifiées, adaptées, selon ces informations. Par exemple, une vulnérabilité peut être détectée sur un applicatif et être corrigée immédiatement sur le RP, laissant le temps nécessaire aux équipes de développement pour implémenter la protection directement dans l’applicatif.

Schema_plusieursRPL’avantage est que, de par leur fonction de mandataire, les RP « filtrent » l’ensemble des requêtes adressées à chacun des clients. Ainsi, ces derniers peuvent tous bénéficier des améliorations des autres. Pour reprendre l’exemple ci-dessus, les sites ayant la même vulnérabilité applicative profiteront donc également des correctifs globaux (non spécifiques à un client), et ce automatiquement.

L’utilisation de plusieurs RP ralentit également les attaques de pirates. En effet, cela rajoute une couche de protection supplémentaire puisque les requêtes sont réparties aléatoirement entre les différents RP, puis entre les différents serveurs hébergeant le site visé.

Cependant, cela ne stoppera pas l’attaque en elle-même ; un pirate patient pourra continuer jusqu’à ce qu’il ait eu accès à un même serveur un nombre de fois suffisant pour en prendre le contrôle.

Les Reverse Proxies chez NBS System

Quelques chiffres

Voici pour commencer quelques chiffres généraux sur les RP dans l’infrastructure de NBS System :

  • 32 Reverse Proxies
  • 4 groupes de RP : Equinix, Iliad (nos deux datacenters) et CerberHost (pour nos clients disposant de cette offre de Cloud de très haute sécurité, répartis sur les 2 datacenters évoqués précédemment), ainsi que nos infrastructures étendues sur les différentes régions Amazon Web Services.
  • 25 000 connexions en parallèle traitées par chacun de ces RP

A noter : nos RP n’assument pas de rôle de répartition de charge vers nos équipements en aval. Cette fonction d’équilibrage de charge (load balancing) est assurée par des équipements spécialisés ne remplissant que ce rôle (plus de détails dans un article à venir…)

Nos outils

Deux noms sont à retenir concernant les RP de NBS System : NGINX et NAXSI.

NGINX

NginxNGINX est un logiciel libre de serveur web et de RP écrit par Igor Sysoev. Nous l’utilisons depuis 2011, uniquement pour sa fonction de RP. Il est très efficace notamment grâce à deux particularités :

– Il est asynchrone : les requêtes sont découpées en plusieurs mini-tâches, et peuvent donc être traitées en parallèle par plusieurs processeurs. De plus, ces processeurs n’attendent pas de retour en envoyant une tâche ; ils peuvent donc passer directement à la tâche suivante sans être dépendant du temps de réponse des éléments auxquels ils ont envoyé cette tâche.

– Il est très facile de contribuer au projet : NGINX est codé en C, mais avec une surcouche de fonctions (écrites dans un langage spécifique) qui vont « envelopper », inclure les fonctions en C. Cela permet une homogénéisation des contributions. En interne, nous avons notamment des développeurs actifs de NGINX ; ce sont eux qui ont créé NAXSI.

NAXSI

NaxsiNAXSI est un module NGINX de pare-feu applicatif (Web Application Firewall ou WAF) permettant un contrôle général des requêtes et une sécurisation des applicatifs. Si les autres pare-feu applicatifs acceptent, par défaut, toutes les requêtes sauf celles interdites (fonctionnement en blacklist, ou liste noire), NAXSI a un fonctionnement bien particulier. Il est équipé d’un module d’auto-apprentissage lui permettant d’enregistrer les requêtes légitimes, et donc de les reconnaître par la suite. Il bloque ensuite toutes les requêtes non reconnues. C’est le fonctionnement en whitelist, ou liste blanche. Cela permet également de s’adapter aux spécificités de chaque site afin d’éviter les faux positifs.

Comment nous avons amélioré la performance de nos Reverse Proxies

Un peu de contexte

Nous souhaitions optimiser autant que possible la performance de nos RP, et avons tout mis en œuvre pour atteindre cet objectif. Il y a 2 ans, nous avons donc procédé à des changements sur ces machines :

  • CPU : nous avons défini en interne que nos RP doivent impérativement fonctionner avec des CPU Intel de dernière génération, dont nous équipons nos serveurs les plus récents afin de mettre avant tout l’accent sur la rapidité de traitement des actions. Chaque proxy bénéficie de 8 CPUs, uniquement afin de conserver une taille moyenne nous autorisant à déployer rapidement de nouveaux RP sur nos infrastructures en cas de montée en charge des sites de nos clients (il est toujours plus simple de trouver 8 CPUs disponibles que 24 ou 32). Ajouter plus de CPUs sur un RP ne ferait qu’augmenter la capacité de traitement des requêtes, c’est-à-dire le nombre de requêtes traitées en parallèle, ce qui n’est pas notre priorité. De plus, nous préférons fonctionner avec plusieurs RP de taille rationnelle, plutôt qu’avec peu de RP de grande taille. En effet, la panne de l’un de ces derniers aurait des conséquences importantes proportionnellement, avec une grosse augmentation de trafic à traiter sur chacun des équipements, et donc un risque de surcharge. Avec la configuration choisie par NBS System, la panne d’un de nos RP n’entraîne pas de grande augmentation de charge sur les autres équipements, et donc n’impacte pas leur performance (cf. schéma ci-dessous).RP_config
  • RAM : la quantité de RAM allouée à un RP dépend de l’activité des sites de nos clients. Ainsi nous sommes-nous fixés, après analyses des données recueillies sur nos serveurs, sur 32GB, quantité de RAM permettant de traiter au mieux toutes les requêtes en parallèle. Cette quantité est révisée régulièrement afin de conserver les RP les plus adaptés aux services de production de nos clients.

Ce gabarit de machine permet donc de fournir un ratio correct entre les performances offertes, l’impact sur le service global en cas de défaillance, la consommation des ressources disponibles sur notre Cloud privé, etc.

  • Disque : nous voulions pousser les performances de stockage au maximum et envisager de dépasser les excellentes performances offertes par les disques SSD. L’idée a donc été émise, tout simplement, d’ôter le disque… Ainsi, l’efficacité de la machine ne dépend pas de cet élément relativement limitant. La RAM peut être jusqu’à 20 fois plus rapide sur certains modes de lecture que les disques SSD (et jusqu’à 1000 fois plus rapide qu’un disque mécanique…).

Comment alors faire marcher ces RP avec uniquement de la RAM et du CPU ? Il a fallu beaucoup de R&D pour arriver à un bon résultat malgré deux grandes contraintes. La première est que la RAM n’offre que du stockage volatile et donc ne peut pas « garder en mémoire » un système d’exploitation pour permettre à la machine de se mettre en route. L’autre est la perte de données lorsque la machine s’éteint.

Notre avantage était que nous avions déjà une infrastructure en place, ce qui nous a aidés à contourner le problème…

Comment nos RP fonctionnent sans disque

Lors du démarrage de la machine virtuelle, la carte réseau de cette dernière enverra un signal sur le réseau afin d’obtenir les infos nécessaires au démarrage du système d’exploitation.

C’est le service PXE (Preboot Execution Environment ou Environnement d’Execution avant Démarrage, hébergé sur l’un de nos serveurs) qui lui répond en lui indiquant où trouver des fichiers utiles, nommément un « kernel » (noyau), base de tout système d’exploitation, et un « InitRD ». Ce dernier est une « image de démarrage minimaliste » : son rôle est de préparer l’environnement nécessaire au fonctionnement du Système d’Exploitation. La carte réseau va ensuite, naturellement, récupérer ces deux éléments à l’endroit indiqué par le PXE et les charger en RAM.

La machine va alors faire démarrer le noyau, qui va lui-même faire démarrer l’InitRD. Ce dernier va aller récupérer les éléments dont il a besoin, pour préparer l’environnement, grâce au noyau, qui tiendra le rôle d’intermédiaire et de « traducteur » entre le système et les composants électroniques de la machine (CPU, RAM, carte réseau, etc.). Une fois que l’InitRD a récupéré les informations nécessaires au démarrage et préparé le système de fichier directement en RAM, celui-ci rend la main au noyau qui fera démarrer le Système d’Exploitation définitif.

C’est ainsi que démarrent nos RP.

 Schema_Boot RS

Considérations sur la maintenance et l’exploitation

Comme toute architecture réseau ou système, l’ensemble des caractéristiques techniques de nos RP ont été déterminées en mesurant les avantages et risques associés. Ces systèmes ne pourraient fonctionner sans la modification des méthodes d’exploitation et de maintenance, effectuée en accord avec nos contraintes de production.

Outre les gains majeurs de performance d’accès aux données stockées, l’absence d’un périphérique de stockage persistant (disques durs mécaniques ou SSD) permet la réduction d’une partie du temps passé pour la maintenance de ces systèmes. Un système de fichier persistant demande de la maintenance régulière pour rester dans les meilleures conditions opérationnelles. Ainsi, régulièrement, une vérification du système de fichier (fsck ou filesystem-check) doit être menée sur le disque afin de garantir la bonne cohérence des données stockées. La durée de cette opération est variable et augmente avec la taille du système de fichier, pouvant aller jusqu’à plusieurs heures pour les plus volumineux. Dans le cadre d’un système de fichier créé sur un stockage volatile (RAM), les contraintes de maintenance directement liées à ce système sont quasi-inexistantes puisque celui-ci est systématiquement recréé à chaque démarrage du système. Nous disposons donc toujours d’un stockage fraichement créé et intègre pour assumer les services de production.

L’absence de disque offre ainsi des avantages majeurs, mais également des contraintes notables en termes de fonctionnement.

En effet, la recréation du système de fichier à chaque démarrage du RP implique une impossibilité de conserver de la donnée de manière fiable. Un arrêt du système entraînera systématiquement une perte globale de toutes les données ayant été stockées pendant le fonctionnement, sans aucune possibilité de récupération ultérieure. Nos services de RP assumant l’un des rôles clés dans le fonctionnement des sites de production de nos clients, la donnée produite sur ceux-ci ne peut en aucun cas être perdue. Afin de répondre à cette contrainte, l’intégralité des informations considérées comme essentielles est enregistrée hors du système local, via l’utilisation de services réseau reposant, eux, sur des systèmes de stockage persistant. D’une part, les journaux d’accès aux services, et plus généralement les journaux d’évènements système (logs), sont transférés directement vers certains de ces services, dédiés à la gestion de ces informations ; il en est de même pour les données de monitoring, de métrologie, etc. liées au fonctionnement de ces systèmes, et devant être conservées. D’autre part, les configurations sont déployées dynamiquement à partir d’un dépôt central unique, stocké sur notre réseau. Cela permet un suivi des modifications effectuées sur les configurations des RP.

L’adoption d’un tel fonctionnement place le service avant tout et relègue la machine au rang de simple moyen. Cela implique nécessairement une modification de la philosophie d’évolution potentielle du RP et des techniques de maintenance opérationnelles qui seront mises en œuvre sur de tels systèmes. Ainsi, chaque RP fonctionnant est une « coquille vide » recevant les informations nécessaires au démarrage et pouvant être supprimée ou remplacée en un temps record selon les besoins (montées en charge, dysfonctionnements, évolutions, etc.). L’importance accordée à un seul RP est négligeable, et seule la quantité globale de ressources en activité sera prise en compte. En utilisant le principe de fonctionnement entièrement en RAM, ces « clones » sont capables de démarrer en environ 10s et d’assumer un service de production en environ 35s. Ces performances offrent beaucoup de souplesse pour adapter, à un instant donné, la quantité de ressources disponibles selon le besoin.

Ainsi, les maintenances majeures et les ajouts de nouvelles fonctionnalités sont menés sur le système de référence (le dépôt central unique) utilisé pour déployer les RP. Les déploiements de ces évolutions majeures sont ensuite effectués séquentiellement (« rolling updates ») en remplaçant purement et simplement, groupe par groupe, les RP sans pénaliser les services, c’est-à-dire sans impacter la production. Seules les maintenances mineures restent industrialisées et appliquées directement sur les RP en marche.

attentionUn fonctionnement entièrement basé en RAM implique également la mise en place d’une surveillance accrue sur certains points de vigilance. La mémoire vive physique (RAM) des serveurs est utilisée pour stocker des données en cours de traitement. En général, lorsque celle-ci arrive à saturation mais que le système nécessite plus de ressources pour procéder à des traitements, certaines données sont déplacées vers un espace d’échange sur disque appelé le SWAP. Il arrive qu’aucun espace d’échange ne soit disponible, comme c’est le cas sur nos RP : ces derniers ne disposant pas de disque, la RAM ne peut pas s’appuyer sur un SWAP. Cette opération ne peut alors pas être menée, et la stabilité des services nécessitant de la mémoire additionnelle est alors mise en péril. Dans les cas les plus extrêmes, la stabilité même du système peut être impactée (exemple : panne de la machine). Pour répondre à ces problématiques, le dimensionnement et le suivi de l’activité de ces systèmes doivent être effectués avec une attention particulière (c’est le capacity planning). Ainsi des systèmes de surveillance et des mécanismes de sécurité ont été mis en place par nos équipes afin de contrôler, en temps réel, les besoins des RP en termes de mémoire. Ceci nous permet de réviser rapidement la quantité de ressources allouées pour assumer une éventuelle hausse ponctuelle de la consommation de mémoire, en répartissant la charge sur un plus grand nombre de RP, réduisant ainsi la quantité de mémoire utilisée par chacun à un niveau non dangereux. Le dimensionnement de ces systèmes est quant à lui révisé régulièrement pour répondre au mieux à l’évolution de l’activité des services de production.

Vous connaissez donc maintenant le fonctionnement des reverse proxies chez NBS System. Le prochain article de notre série « Découvrez l’infrastructure NBS System » portera sur les pare-feu et les répartisseurs de charge.

 Source technique : Denis Pompilio

Lucie Saunois
Lucie Saunois
Passionnée d'informatique, en particulier de sécurité, depuis qu'elle a rejoint l'OT Group en 2015, Lucie se spécialise dans la vulgarisation technique pour permettre à tous d'appréhender ces sujets parfois complexes.