Un vaste pan de la technologie de Cloudflare est bien documenté. À titre d'exemple, la façon dont nous gérons le trafic entre les utilisateurs finaux (nos clients) et nos serveurs a été abordée à de nombreuses reprises sur ce blog : « A brief primer on anycast (2011) », « Load Balancing without Load Balancers (2013) », « Path MTU discovery in practice (2015) », « Cloudflare's edge load balancer (2020) », « How we fixed the BSD socket API (2022) ».
Cependant, nous avons rarement parlé de la deuxième partie de notre connectivité réseau : la manière dont nos serveurs récupèrent le contenu sur Internet. Dans cet article de blog, nous allons remédier à cette lacune. Nous examinerons de quelle manière nous gérons les adresses IP utilisées par Cloudflare pour récupérer les données sur Internet, l'évolution de l'architecture de notre réseau sortant et la façon dont nous l'avons optimisé pour utiliser au mieux l'espace d'adressage IP disponible.
Accrochez-vous, nous avons beaucoup de choses à voir !
Tout d'abord, parlons de la terminologie.
Chaque serveur Cloudflare traite de nombreux types de trafic réseau, mais on distingue deux grandes catégories :
Le trafic provenant d'Internet – Les connexions entrantes créées par les utilisateurs finaux vers nos serveurs. Dans le contexte de cet article de blog, nous les appellerons « connexions entrantes ».
Le trafic provenant de Cloudflare – Les connexions sortantes créées par nos serveurs vers d'autres hôtes sur Internet. Par souci de concision, nous les appellerons « connexions sortantes ».
La partie « sortante », bien qu'elle soit rarement abordée sur ce blog, est essentielle à notre fonctionnement. Nos serveurs doivent créer des connexions sortantes pour accomplir leur travail. Par exemple :
Dans notre produit de réseau CDN, avant que le contenu ne soit mis en cache, il est récupéré sur les serveurs d'origine. Vous pouvez consulter l'article de blog « How we built Pingora, the proxy that connects Cloudflare to the Internet (2022) », ainsi que les documentations concernant Argo et Tiered Cache.
Pour le produit Spectrum, chaque connexion TCP entrante entraîne une connexion sortante.
Les instances Workers exécutent souvent plusieurs sous-requêtes pour construire une réponse HTTP. Certaines peuvent adresser des requêtes à des serveurs connectés à Internet.
Nous utilisons également des produits de proxy de transfert côté client, tels que WARP et Cloudflare Gateway. Ces proxys gèrent les connexions d'utilisateurs finaux à destination d'Internet. Nos serveurs doivent établir des connexions à Internet au nom de nos utilisateurs.
Et ainsi de suite.
Anycast pour les connexions entrantes, unicast pour les connexions sortantes
L'architecture de notre réseau entrant est très différente de celle de notre réseau sortant. Au niveau du réseau entrant, les connexions provenant d'Internet sont exclusivement gérées par nos plages d'adresses IP anycast. Anycast est une technologie qui permet à chacun de nos datacenters « d'annoncer » et de gérer les mêmes plages d'adresses IP. Face aux nombreuses destinations possibles, comment l'Internet sait-il où acheminer les paquets ? Les paquets des utilisateurs finaux sont acheminés vers le datacenter le plus proche, en fonction des indicateurs BGP d'Internet ; souvent, il s'agit du datacenter le plus proche géographiquement. En règle générale, les itinéraires BGP ne changent pas beaucoup, et le trafic correspondant à chaque adresse IP d'utilisateur final est généralement acheminé vers un datacenter unique.
Toutefois, si anycast gère efficacement le trafic entrant, il ne permet pas de gérer le trafic sortant. Il est impossible d'établir une connexion sortante depuis une adresse IP anycast. Prenons le cas du paquet de réponse : il risque d'être acheminé au mauvais endroit – le datacenter géographiquement le plus proche de l'expéditeur, mais pas nécessairement le datacenter source !
C'est pourquoi, encore récemment, nous établissions les connexions sortantes de manière simple et conventionnelle : une adresse IP unicast était attribuée à chaque serveur. Le terme « adresse IP unicast » signifie qu'il n'existe qu'un seul serveur dans le monde utilisant cette adresse. La gestion des paquets renvoyés est très efficace, et les paquets sont précisément renvoyés au serveur concerné, identifié par l'adresse IP unicast.
Segmenter le trafic en fonction de l'adresse IP de sortie
À l'origine, les connexions établies par Cloudflare étaient principalement des requêtes de récupération de données HTTP transmises à des serveurs d'origine sur Internet. Au fur et à mesure que notre offre de produits s'est développée, la diversité du trafic a fait de même. L'exemple le plus notable est notre application WARP. Pour WARP, nos serveurs utilisent un proxy de transfert et gèrent le trafic provenant des appareils d'utilisateurs finaux. Cela se déroule sans le même niveau d'intermédiation que dans notre produit de réseau CDN, ce qui pose un problème. Les serveurs tiers sur Internet, à l'instar des serveurs d'origine, doivent être en mesure d'établir une distinction entre les connexions provenant des services Cloudflare et celles des utilisateurs de WARP. Cette segmentation du trafic est traditionnellement mise en œuvre en utilisant différentes plages d'adresses IP pour différents types de trafic (bien que nous ayons récemment introduit des techniques plus fiables, telles que les extractions à l’origine authentifiées).
Pour contourner le problème de différenciation entre les pools de trafic fiable et non fiable, nous avons ajouté une adresse IP WARP non fiable à chacun de nos serveurs :
Adresses IP sortantes avec identifiant de pays
Il est rapidement devenu manifeste que les identifiants « fiable » et « non fiable » n'étaient pas les seuls nécessaires. Pour le service WARP, nous avons également besoin d'identifiants de pays. Par exemple, les utilisateurs de WARP au Royaume-Uni s'attendent à ce que le site bbc.com fonctionne, tout simplement. Toutefois, la BBC restreint un grand nombre de ses services aux personnes résidant au Royaume-Uni uniquement.
Pour cela, elle recourt au « geofencing », c'est-à-dire à l'utilisation d'une base de données associant les adresses IP publiques aux pays, et autorise uniquement les adresses IP situées au Royaume-Uni. Le geofencing est très répandu sur Internet aujourd'hui. Pour éviter les problèmes liés au geofencing, nous devons choisir des adresses sortantes spécifiques, avec un identifiant de pays approprié, en fonction de la localisation de l'utilisateur de WARP. À l'instar de nombreuses autres parties sur Internet, nous identifions notre espace d'adressage IP sortant avec des codes pays, et nous le publions sous la forme d'un flux géolocalisé (comme celui-ci). Notez que le flux géolocalisé publié est uniquement constitué de données. Le fait qu'une adresse IP soit identifiée comme étant associée au Royaume-Uni, par exemple, ne signifie pas que cette adresse est servie depuis le Royaume-Uni, mais que l'opérateur souhaite qu'elle soit géolocalisée au Royaume-Uni. Comme de nombreux autres aspects d'Internet, tout cela repose sur la confiance.
Vous remarquerez qu'à ce stade, nous utilisons trois identifiants géographiques indépendants :
L'identifiant du pays de l'utilisateur de WARP (l'adresse IP de connexion de l'utilisateur final)
La localisation du datacenter auquel est connecté l'utilisateur final
L'identifiant de pays de l'adresse IP sortante
Pour assurer une qualité de service optimale, nous voulons choisir l'adresse IP sortante de façon à ce que son identifiant de pays corresponde au pays associé à l'adresse IP de l'utilisateur final. Toutefois, gérer le trafic sortant depuis une adresse IP avec un identifiant de pays spécifique constitue un défi : nos datacenters servent des utilisateurs du monde entier, potentiellement dans de nombreux pays ! N'oubliez pas : en raison d'anycast, nous ne contrôlons pas directement le routage du trafic entrant. La géographie d'Internet ne correspond pas toujours à la géographie physique. Par exemple, notre datacenter de Londres reçoit non seulement du trafic d'utilisateurs situés au Royaume-Uni, mais également d'utilisateurs en Irlande et en Arabie saoudite. Par conséquent, nos serveurs londoniens ont besoin de nombreuses adresses WARP sortantes associées à de nombreux pays :
Vous voyez où je veux en venir ? Le nombre de problèmes potentiels explose ! Au lieu d'une ou deux adresses IP sortantes pour chaque serveur, il nous en faut maintenant des dizaines ; or, les adresses IPv4 ne sont pas données. Avec cette approche, il nous faut de nombreuses adresses sur chaque serveur, et nous gérons des milliers de serveurs. Cette architecture devient donc très coûteuse.
anycast pose-t-il un problème ?
Récapitulons : avec le trafic entrant anycast, nous ne maîtrisons pas le choix du datacenter vers lequel est acheminé le trafic de l'utilisateur. Par conséquent, chacun de nos datacenters doit pouvoir transmettre du trafic sortant depuis une adresse, avec tous les identifiants imaginables. À l'intérieur du datacenter, nous ne maîtrisons pas non plus le serveur vers lequel est acheminée la connexion. Un datacenter peut potentiellement contenir de nombreux identifiants, de nombreux datacenters et de nombreux serveurs.
Le problème vient peut-être de l'architecture du réseau entrant ? Peut-être est-il préférable d'utiliser une architecture de réseau traditionnelle, où un utilisateur final spécifique est acheminé par DNS vers un datacenter spécifique, voire un serveur spécifique ?
C'est une approche envisageable, mais nous avons décidé de ne pas la suivre. Nous tenons à ce que notre trafic entrant soit acheminé par anycast. Cela nous offre de nombreux avantages :
Performances : avec anycast, par définition, l'utilisateur final est acheminé vers le datacenter le plus proche (selon les indicateurs BGP). Il s'agit généralement du datacenter le plus rapide pour un utilisateur donné.
Basculement automatique : si l'un de nos datacenters devient indisponible, le trafic est instantanément et automatiquement réacheminé vers le meilleur site suivant.
Résilience contre les attaques DDoS : en cas d'attaque par déni de service ou de pic de trafic, la charge est automatiquement répartie sur de nombreux datacenters, réduisant considérablement l'impact de l'incident.
Homogénéité des logiciels : les fonctionnalités de chaque datacenter et de chaque serveur dans un datacenter sont identiques. Nous utilisons la même pile logicielle sur tous les serveurs, dans le monde entier. Chaque machine peut effectuer n'importe quelle action, pour n'importe quel produit, ce qui facilite le débogage et l'évolutivité.
Pour ces raisons, nous aimerions conserver anycast pour le traitement du trafic entrant. Nous avons décidé d'employer une autre approche pour résoudre le problème de la cardinalité des adresses sortantes.
Résoudre un problème à un million de dollars
Parmi les milliers de serveurs que nous exploitons, chacun devrait être en mesure d'utiliser une adresse IP sortante avec un identifiant, quel qu'il soit. Pour expliquer notre solution, il est plus facile de commencer par présenter deux architectures extrêmes.
Chaque serveur possède toutes les adresses IP requises : chaque serveur possède toutes les adresses IP sortantes spécialisées, ainsi que les identifiants requis.
Un serveur possède l'adresse IP requise : une adresse IP sortante spécialisée avec un identifiant spécifique réside dans un endroit ; les autres serveurs réacheminent le trafic vers celui-ci.
Les deux approches présentent des avantages et des inconvénients :
Adresse IP spécialisée sur chaque serveur
Specialized IP on every server | Specialized IP on one server |
---|---|
Super expensive $$$, every server needs many IP addresses. | Cheap $, only one specialized IP needed for a tag. |
Egress always local - fast | Egress almost always forwarded - slow |
Excellent reliability - every server is independent | Poor reliability - introduced chokepoints |
Adresse IP spécialisée sur un serveur
Extrêmement coûteuse, chaque serveur doit disposer de nombreuses adresses IP.
Peu coûteuse $, une seule adresse IP spécialisée est nécessaire pour un identifiant.
Trafic sortant toujours local - rapide
Specialized IP on every server | Specialized IP per data center | Specialized IP on one server |
---|---|---|
Super expensive $$$ | Reasonably priced $$ | Cheap $ |
Egress always local - fast | Egress always local - fast | Egress almost always forwarded - slow |
Excellent reliability - every server is independent | Excellent reliability - every server is independent | Poor reliability - many choke points |
Trafic sortant presque toujours réacheminé - lente
Excellente fiabilité - chaque serveur est indépendant
Fiabilité insatisfaisante - provoque des goulets d'étranglement
Il existe une troisième approche
Nous avons longuement réfléchi à ce problème. Très honnêtement, la première option extrême, qui consiste à disposer de toutes les adresses IP nécessaires localement, sur chaque serveur Cloudflare, n'est pas totalement irréalisable. C'est, sommairement, ce que nous avons réussi à faire pour IPv6. Avec IPv6, l'accès au vaste espace d'adressage IP requis n'est pas un problème.
Avec IPv4, cependant, aucune de ces deux options n'est acceptable. La première option offre du trafic sortant rapide et fiable, mais comporte un coût élevé ; les adresses IPv4 requises sont coûteuses. La deuxième option utilise le plus petit espace d'adressage IP possible ; elle est donc économique, mais exige des compromis en termes de performances et de fiabilité.
La solution que nous avons imaginée est un compromis entre ces extrêmes. L'idée consiste, sommairement, à changer l'unité d'attribution. Au lieu d'attribuer une adresse IPv4 /32 à chaque serveur, nous avons élaboré une méthode permettant d'attribuer une adresse IP /32 par datacenter, puis de la partager entre les serveurs physiques.
Adresse IP spécialisée sur chaque serveur
Adresse IP spécialisée par datacenter
198.51.100.1 - forward to LHR
198.51.100.2 - forward to CDG
198.51.100.3 - forward to MAN
...
Adresse IP spécialisée sur un serveur
Extrêmement coûteuse $$$
Raisonnable $$
Économique $
Trafic sortant toujours local - rapide
Trafic sortant toujours local - rapide
Trafic sortant presque toujours réacheminé - lente
Excellente fiabilité - chaque serveur est indépendant
Excellente fiabilité - chaque serveur est indépendant
Fiabilité insatisfaisante - de nombreux goulets d'étranglement
Partager une adresse IP spécialisée à l'intérieur d'un datacenter
L'idée de partager une adresse IP entre plusieurs serveurs n'est pas nouvelle. Traditionnellement, cette approche peut être mise en œuvre en déployant Source NAT sur un routeur. Regrettablement, le nombre d'adresses IP sortantes dont nous avons besoin et l'ampleur de notre réseau nous empêchent de nous reposer sur un pare-feu dynamique/NAT au niveau du routeur. Nous n'aimons pas non plus la notion d'état partagé ; nous ne sommes donc pas convaincus par les installations NAT distribuées.
Ce que nous avons choisi, à la place, c'est de répartir une adresse IP sortante sur plusieurs serveurs en fonction d'une plage de ports. Pour une adresse IP sortante donnée, chaque serveur possède une petite partie des ports sources – une « part des ports ».
Lorsque des paquets renvoyés arrivent depuis Internet, nous devons les réacheminer vers la bonne machine. Pour cette tâche, nous avons personnalisé Unimog, notre équilibreur de charge basé sur XDP en C4 (« Unimog, Cloudflare's edge load balancer (2020) »), et cette solution fonctionne parfaitement.
Avec une « part des ports » de 2 048 ports, par exemple, nous pouvons partager une adresse IP entre 31 serveurs. Cependant, il est toujours possible que nous manquions de ports. Pour remédier à ce problème, nous avons travaillé dur afin de pouvoir réutiliser efficacement les ports sortants. Reportez-vous aux articles de blog « How to stop running out of ephemeral ports and start to love long-lived connections (2022) », « How to share IPv4 addresses (2022) » et notre émission sur Cloudflare.TV.
C'est à peu près tout. Chaque serveur est informé des adresses IP et des « parts des ports » qu'il possède. Pour le routage du trafic entrant, Unimog inspecte les ports et distribue les paquets aux machines concernées.
Partager un sous-réseau entre des datacenters
Toutefois, l'histoire n'est pas encore terminée ; nous n'avons pas expliqué comment nous pouvons acheminer une adresse /32 unique au sein d'un datacenter. Traditionnellement, sur l'Internet public, il est uniquement possible d'acheminer des sous-réseaux avec une granularité de /24, soit 256 adresses IP. Dans notre cas, cela entraînerait une importante perte d'espace d'adressage IP.
Afin de résoudre ce problème et d'améliorer l'utilisation de notre espace d'adressage IP, nous avons configuré nos plages de trafic sortant avec... anycast ! Ensuite, nous avons personnalisé Unimog et l'avons configuré de manière à réacheminer les paquets vers le datacenter concerné, via notre réseau d'infrastructure. Unimog gère une base de données comme ceci :
Avec cette architecture, le datacenter auquel sont transmis les paquets renvoyés n'a pas d'importance. Unimog peut toujours remédier au problème et transmettre les données à la bonne destination. Fondamentalement, nous utilisons anycast au niveau de la couche BGP, en raison de notre architecture ; d'un point de vue sémantique, toutefois, une adresse IP identifie un datacenter, tandis qu'une plage d'adresses IP et de ports identifie une machine spécifique. Cette architecture se comporte presque comme une configuration unicast.
Nous avons appelé cette pile technologique « soft-unicast », et le résultat nous paraît magique. C'est comme si, au niveau logiciel, nous avions configuré unicast sur un réseau anycast au niveau de la couche BGP.
La technologie soft-unicast est magique, tout simplement
Cette configuration nous offre des avantages considérables :
Nous pouvons partager une adresse IP /32 sortante entre de nombreux serveurs.
Nous pouvons étendre un sous-réseau unique à de nombreux datacenters et le modifier facilement, à la volée. Ceci nous permet d'utiliser pleinement nos plages d'adresses IPv4 sortantes.
Nous pouvons regrouper des adresses IP similaires. Par exemple, toutes les adresses IP comportant l'identifiant « UK » peuvent former une plage continue unique, ce qui permet de réduire la taille du flux géolocalisé publié.
Nous pouvons facilement intégrer de nouvelles plages d'adresses IP sortantes, telles que les adresses IP de clients. Cela est utile pour certains de nos produits, comme Cloudflare Zero Trust.
Toutes ces mesures sont mises en œuvre à un coût raisonnable, sans perte de performances et de fiabilité :
Habituellement, l'utilisateur est en mesure de transmettre du trafic sortant directement depuis le datacenter le plus proche ; cette approche offre les meilleures performances possibles.
Nous pouvons attribuer ou libérer des adresses IP en fonction des besoins réels. Cela nous offre davantage de flexibilité au regard de la gestion du coût des adresses IP, et nous n'avons pas besoin de réaliser de dépenses excessives en amont.
Puisque nous gérons plusieurs adresses IP sortantes sur différents sites, la fiabilité n'est pas compromise.
Le véritable emplacement de nos adresses IP est « le cloud »
Bien que la technologie soft-unicast nous offre un immense gain d'efficacité, nous nous sommes heurtés à quelques difficultés. Il arrive que l'on nous demande : « Où se trouve cette adresse IP, physiquement ? ». Mais cette question est sans réponse. Physiquement, nos adresses IP sortantes n'existent nulle part. Du point de vue de BGP, nos plages d'adresses IP sortantes sont configurées avec anycast ; elles résident donc partout. D'un point de vue logique, chaque adresse IP est utilisée dans un seul datacenter à la fois, mais nous pouvons la déplacer à la demande.
Les réseaux CDN acheminent incorrectement le trafic des utilisateurs
Voici un autre exemple de problème que nous avons rencontré avec des réseaux CDN tiers. Comme nous l'avons mentionné plus haut, trois identifiants de pays sont présents dans notre pipeline :
L'identifiant de pays de l'adresse IP depuis laquelle se connecte l'utilisateur final.
L'emplacement de notre datacenter.
L'identifiant de pays des adresses IP que nous avons choisies pour les connexions sortantes.
Ce n'est pas parce qu'une adresse IP sortante comporte l'identifiant « Royaume-Uni » qu'elle est effectivement utilisée au Royaume-Uni. Nous avons constaté, dans certains cas, que le trafic d'un utilisateur de WARP identifié comme étant au Royaume-Uni a été acheminé vers Paris, en raison d'opérations de maintenance dans notre datacenter LHR. Un célèbre réseau CDN a effectué une recherche inversée sur notre adresse IP sortante, a détecté l'identifiant du Royaume-Uni et a dirigé l'utilisateur vers un serveur de réseau CDN situé à Londres. En règle générale, cela ne pose pas de problème... mais cette fois, le trafic sortant partait de Paris. Les paquets de cet utilisateur ont finalement été acheminés depuis son domicile au Royaume-Uni à Paris, puis de nouveau au Royaume-Uni entraînant une baisse des performances.
Nous résolvons ce problème en exécutant des requêtes DNS dans le datacenter d'où provient le trafic sortant. Pour le DNS, nous utilisons des adresses IP identifiées avec la localisation du datacenter, plutôt que la géolocalisation prévue de l'utilisateur. Cela règle généralement le problème, mais malheureusement, des exceptions existent encore.
L'avenir est ici
Nos expériences autour de l'agilité d'adressage en 2021 ont démontré que nous disposons de nombreuses possibilités d'innover en matière d'adressage du trafic entrant. La technologie soft-unicast a démontré que nous pouvons atteindre une flexibilité et une densité élevées du côté du trafic sortant.
Avec chaque nouveau produit, le nombre d'identifiants requis au niveau du trafic sortant augmente – de la fiabilité du trafic à la catégorie de produit et la géolocalisation. À mesure que le nombre d'adresses IPv4 utilisables diminue, nous ne doutons pas que l'innovation se poursuivra dans ce domaine. La technologie soft-unicast est notre solution à cette situation, mais elle n'est certainement pas notre dernière innovation.
Pour l'heure, toutefois, il semble que nous nous éloignions d'une approche unicast traditionnelle. Nos adresses IP de sortie n'existent plus vraiment dans un endroit fixe, et certains de nos serveurs ne possèdent désormais même plus de véritable adresse IP unicast.