English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

invité
1 / ?
retour aux leçons

Ce qui se trouve devant presque tous les services web

Bienvenue

Si vous tapez example.com dans un navigateur, vous atteignez presque jamais la machine qui exécute réellement l'application. Vous atteignez une machine qui transmet la requête à celle qui le fait. Cette machine de transmission porte un nom : un proxy inverse.

Cette leçon enseigne ce qu'un proxy inverse fait, pourquoi presque tous les services web publics se cachent derrière l'un, et quelles sont les trois tâches que la couche d'extrémité (edge) gère en même temps.

À la fin, vous comprendrez :

- La différence entre un client, un proxy et une origine

- Pourquoi un proxy placé devant une origine protège, met à l'échelle et permet de remplacer des composants sans que personne ne s'en aperçoive

- Les trois tâches qu'un proxy inverse gère simultanément : masquer l'origine, terminer le TLS et répartir la charge entre les répliques

- Comment une requête voyage du navigateur au proxy, puis vers l'amont et retour, saut par saut

À la fin, vous saurez raisonner avec confiance sur le placement des proxies, la séparation des préoccupations à la périphérie et la raison pour laquelle une couche de proxy sans état se multiplie à moindre coût, tandis qu'une origine unique ne le fait pas.

Proxy direct vs Proxy inverse

Deux directions de proxy

Les deux types de proxy se situent entre deux parties et relaient le trafic. Ils diffèrent par la partie qu'ils représentent.

Proxy avant : se place devant un groupe de clients. Les clients connaissent l'existence du proxy ; un serveur externe voit l'adresse du proxy, et non l'adresse du client. Les proxies de sortie d'entreprise, les filtres de contenu et les proxies SOCKS correspondent à ce schéma.

Proxy inverse : se place devant un groupe de serveurs. Le monde extérieur (les clients) communique avec l'adresse du proxy ; les clients n'ont aucune idée qu'un serveur réel se cache derrière. Presque tous les services web publics en utilisent un.

Moyen mnémotechnique : un proxy avant masque les clients aux serveurs. Un proxy inverse masque les serveurs aux clients.

Pourquoi s'intéresser à la direction ? Le rôle, les modes de défaillance et la frontière de sécurité sont tous différents. Un proxy avant s'inquiète de savoir qui ses utilisateurs contactent ; un proxy inverse s'inquiète de savoir qui contacte ses serveurs.

Un client envoyant du trafic à travers les deux types simultanément suit le trajet : client -> forward_proxy -> internet -> reverse_proxy -> origin.

Une petite entreprise exploite une application de chat. Elle souhaite que chaque requête d'un utilisateur externe atterrisse sur une machine qui masque les serveurs de chat réels derrière elle. De quel type de proxy ont-ils besoin, et à quoi l'utilisateur externe se connecte-t-il réellement ?

Pourquoi tant de choses se situent à l'extrémité

La couche d'extrémité justifie son existence

Un proxy inverse assume trois rôles simultanément. L'un d'entre eux suffit à justifier cette couche ; le fait d'assumer les trois à la même adresse explique pourquoi presque toutes les architectures web de production présentent la même forme à l'avant.

Rôle 1 : Masquer l'origine. Le proxy répond sur une IP publique. Les backends sont situés sur des IP privées inaccessibles depuis Internet. Un attaquant souhaitant cibler l'origine doit d'abord compromettre le proxy.

Tâche 2 : Terminer le TLS. Le proxy détient le certificat pour example.com et décode les requêtes HTTPS entrantes. Les backends communiquent en HTTP simple (ou en TLS interne plus simple) avec le proxy à travers un segment de réseau de confiance. La rotation, le renouvellement des certificats et la politique de chiffrement sont tous centralisés en un seul endroit.

Tâche 3 : Distribuer la charge. Le proxy choisit quel backend traite chaque requête. Les backends situés derrière un même proxy forment un pool ; le proxy en sélectionne un par requête en utilisant une stratégie (round-robin, moins de connexions, hachage sur un en-tête). Ajouter de la capacité signifie ajouter un backend au pool, plutôt que d'informer chaque client d'une nouvelle adresse.

Chaque tâche est un petit programme. Ensemble, elles expliquent pourquoi une couche aussi simple que « Caddy devant une application Python » porte plus de poids de conception que l'application Python elle-même.

Proxy inverse assurant trois tâches : masquer l'origine, terminer le TLS, distribuer la charge

Concevoir pour les trois tâches

Votre équipe exécute une petite API sur un seul processus Python à l'écoute du port 8000 sur une seule VM. Le trafic a suffisamment augmenté pour qu'une seule VM ne puisse plus suivre, et une revue de sécurité a signalé que la VM possède une IP publique et gère son propre certificat TLS.

Vous décidez de placer un proxy inverse en avant. Esquissez la configuration : où pointe le DNS, où se trouve le certificat, comment la charge atteint-elle les backends, et qu'est-ce qui change pour la VM d'origine ?

Parcourez la nouvelle architecture. Traitez les quatre éléments : la cible DNS, l'emplacement de la terminaison TLS, la stratégie de distribution de charge, et ce que la VM d'origine conserve ou perd.

Remplacer un composant sans que personne ne s'en aperçoive

L'indirection achète la liberté

Un vieux adage de l'informatique veut que tout problème puisse être résolu en ajoutant une couche d'indirection (sauf le problème de trop de couches d'indirection). Le proxy inverse est l'une des indirections les plus utiles dans les systèmes distribués.

Ce que cela vous apporte :

- Backends interchangeables. Vous déplacez l'application de Python vers Go ? Vous migrez d'un centre de données à un autre ? Vous déployez une nouvelle version avec une interruption zéro ? Chacune de ces opérations se déroule derrière une adresse publique stable. Rien ne change pour les utilisateurs.

- Mise à l'échelle indépendante. La couche proxy se met à l'échelle en fonction de la bande passante et du CPU au niveau TLS. La couche backend se met à l'échelle en fonction de la charge applicative. Chacune grandit sur son propre axe car elles résident sur des machines différentes.

- Confinement des pannes. Un mauvais déploiement sur le backend ne met pas à terre l'adresse publique. Le proxy reste en ligne ; vous poussez une correction ou effectuez un retour arrière ; le monde se reconnecte lorsque le backend récupère.

- Préoccupations transversales en un seul endroit. Limitation de débit, blocage géographique, journalisation des requêtes, réécriture des en-têtes, mise en cache, compression des réponses : tout cela réside sur le proxy. Le code du backend reste concentré sur l'application.

Sans le proxy, chacun de ces problèmes doit résider dans le processus applicatif. Avec le proxy, ils résident dans une couche unique détenue par une seule équipe.

Le coût : une couche supplémentaire à exploiter. Les équipes matures acceptent ce coût car la couche proxy elle-même fonctionne sans état et se met à l'échelle horizontalement ; remplacer un proxy par deux ne nécessite aucune coordination.

Un déploiement bleu/vert via le proxy

Votre équipe exécute la version 1 de l'API sur trois VM back-end (pool bleu) derrière un proxy inverse. Vous souhaitez déployer la version 2 avec la possibilité de revenir en arrière en moins de trente secondes si un problème survient.

Vous lancez trois nouvelles VM back-end (pool vert) exécutant la version 2, côte à côte avec le pool bleu, mais vous ne redirigez pas encore le trafic vers elles.

Expliquez comment le proxy inverse vous permet de basculer du bleu au vert & de revenir en arrière rapidement, & expliquez ce qui ne serait pas possible si l'application était exposée directement aux clients sans proxy.

Du navigateur au backend et retour

Suivre une requête de bout en bout

Suivez une seule requête HTTPS GET de https://api.example.com/users/42 à travers un proxy inverse placé devant un pool de backends.

Hop 1 : Résolution DNS. Le navigateur demande au résolveur l'adresse de api.example.com. Le résolveur retourne l'IP publique du proxy (par exemple, 203.0.113.10). Le navigateur ouvre une connexion TCP vers 203.0.113.10:443.

Hop 2 : Poignée de main TLS. Le proxy présente son certificat pour api.example.com. Le navigateur valide le certificat, les deux parties conviennent d'une clé de session, et le canal chiffré s'ouvre.

Hop 3 : Requête HTTP dans le TLS. Le navigateur envoie GET /users/42 HTTP/1.1\nHost: api.example.com\n.... Le proxy déchiffre les octets de la requête.

Hop 4 : Sélection du backend. Le proxy consulte son pool d'amont pour api.example.com & choisit un backend (par exemple 10.0.0.21:8000) en utilisant sa stratégie d'équilibrage de charge.

Hop 5 : Demande amont. Le proxy ouvre (ou réutilise) une connexion HTTP simple vers 10.0.0.21:8000 & transmet la demande. Le proxy peut réécrire les en-têtes en cours de route : ajouter X-Forwarded-For: <client-ip>, définir correctement Host:, supprimer les en-têtes hop-by-hop comme Connection.

Hop 6 : Traitement par le backend. L'application backend lit la demande, interroge sa base de données, et construit une réponse JSON.

Hop 7 : Réponse amont. Le backend renvoie la réponse au proxy en HTTP simple.

Hop 8 : Réponse à la périphérie. Le proxy peut réécrire ou compresser la réponse, la chiffre à nouveau via la session TLS, & l'envoie au navigateur.

Hop 9 : Cycle de vie de la connexion. La session TLS reste généralement ouverte pour la demande suivante (HTTP/2 multiplexe de nombreuses demandes sur une seule connexion). La connexion proxy-vers-backend est souvent mise en pool pour réutilisation.

Tout service web public suit une variante de cette structure. Connaître les hops permet de raisonner sur l'endroit où la latence s'accumule, où le journalisation doit être placée, & où une défaillance peut se cacher.

Cycle de vie de la demande : navigateur, DNS, proxy, TLS, amont, backend, réponse

Où est passé le temps ?

Un utilisateur se plaint que l'API semble lente. Vous mesurez et constatez que la requête prend 850 ms de bout en bout. Les journaux du serveur sur le backend indiquent que l'application a traité la requête en 40 ms. Les journaux du proxy montrent que le proxy a passé 50 ms sur sa partie du travail (poignée de main TLS + routage + écriture de la réponse).

Où sont passés les 760 ms restants ? Citez au moins deux candidats qui se trouvent en dehors du temps de traitement du proxy et du backend, et expliquez comment chacun d'eux se manifesterait dans les mesures.

Concevoir un edge minimal pour un nouveau service

Synthèse

Vous avez appris la différence entre un proxy avant et un proxy inverse, les trois tâches qu'un proxy inverse gère simultanément, pourquoi masquer l'origine rapporte des dividendes à chaque fois qu'une modification est nécessaire, et comment une requête se propage de saut en saut à travers l'edge.

Appliquez maintenant ces connaissances.

Une petite équipe prévoit de lancer un nouveau service appelé notes.example.com. Les utilisateurs liront et écriront des notes personnelles. L'équipe exécutera deux VM back-end au lancement et prévoit de passer à dix au cours de l'année suivante. Ils souhaitent du HTTPS pour les utilisateurs, un déploiement progressif pour les nouvelles versions, et aucune exposition publique des IP des back-ends.

Concevez l'architecture edge pour notes.example.com. Abordez les points suivants : où pointe le DNS, où se trouve le certificat TLS, comment les requêtes atteignent un back-end, ce qui change lorsqu'ils passent de deux à dix back-ends, et une préoccupation transversale (limitation de débit, journalisation, réécriture d'en-têtes, etc.) que vous ajouteriez à l'edge plutôt qu'à l'intérieur de l'application.

Où va ce cours ensuite

Où va ce cours ensuite

Cette leçon a établi la forme de la couche d'extrémité (edge). Quatre leçons supplémentaires dans ce cours s'appuient dessus :

- Mise à l'échelle horizontale sans état : pourquoi une couche de proxy (et les backends qui se trouvent derrière) se multiplie à moindre coût, et les calculs pour dimensionner le nombre de répliques en cas de pic de trafic.

- Séparation Ingress / Egress : pourquoi une seule boîte proxy qui gère à la fois le trafic entrant et sortant finit par échouer de manière surprenante, et comment séparer les couches.

- Modes d'échec & Rayon d'explosion : comment un simple changement de configuration peut provoquer une panne en cascade, et comment rédiger des actions correctives sans blâme pour prévenir les récidives.

- Observabilité & Capacité : quoi mesurer au niveau de l'edge pour détecter une panne avant que les utilisateurs ne s'en rendent compte.

Chaque leçon est autonome. Ensemble, elles vous offrent un modèle mental opérationnel d'une flotte à l'échelle du web.

Leçon complémentaire : geometry_of_proxies_and_origins reformule tout le contenu de cette leçon sous forme de graphe orienté et explore ce que la théorie des graphes vous apprend sur le chemin d'une requête.

Bravo. En avant.