Comment nous avons franchi le grand pare-feu chinois (partie 2)

Salut!

Nikita est de nouveau avec vous, ingénieur système de l'entreprise SEMrush. Et avec cet article, je continue l'histoire sur la façon dont nous avons trouvé une solution de contournement Pare-feu chinois pour notre service semrush.com.

В section précédente J'ai dit:

  • quels problèmes surviennent une fois la décision prise « Nous devons faire en sorte que notre service fonctionne en Chine »
  • Quels sont les problèmes de l’Internet chinois ?
  • pourquoi avez-vous besoin d'une licence ICP ?
  • comment et pourquoi nous avons décidé de tester nos bancs d'essai avec Catchpoint
  • quel a été le résultat de notre première solution basée sur Cloudflare China Network
  • Comment nous avons trouvé un bug dans Cloudflare DNS

Cette partie est la plus intéressante, à mon sens, car elle se concentre sur des implémentations techniques spécifiques de la mise en scène. Et nous commencerons, ou plutôt continuerons, par Cloud Alibaba.

Cloud Alibaba

Cloud Alibaba est un fournisseur de cloud assez important, qui dispose de tous les services qui lui permettent de se qualifier honnêtement de fournisseur de cloud. C'est bien qu'ils aient la possibilité de s'inscrire pour les utilisateurs étrangers, et que la majeure partie du site soit traduite en anglais (pour la Chine, c'est un luxe). Dans ce cloud, vous pouvez travailler avec de nombreuses régions du monde, de la Chine continentale, ainsi que de l'Asie océanique (Hong Kong, Taiwan, etc.).

IPSEC

Nous avons commencé par la géographie. Notre site de test étant situé sur Google Cloud, nous devions « lier » Alibaba Cloud à GCP, nous avons donc ouvert une liste d'emplacements dans lesquels Google est présent. À cette époque, ils ne disposaient pas encore de leur propre centre de données à Hong Kong.
La région la plus proche s'est avérée être asie-est1 (Taïwan). Ali s'est avéré être la région de la Chine continentale la plus proche de Taiwan cn-shenzhen (Shenzhen).

Avec terraform a décrit et développé l'ensemble de l'infrastructure dans GCP et Ali. Un tunnel de 100 Mbit/s entre les nuages ​​s'est creusé presque instantanément. Du côté de Shenzhen et de Taiwan, des machines virtuelles proxy ont été évoquées. À Shenzhen, le trafic des utilisateurs est terminé, via un tunnel vers Taiwan, et de là, il va directement à l'adresse IP externe de notre service à nous-est (Côte Est des USA). Ping entre machines virtuelles via tunnel 24ms, ce qui n'est pas si mal.

Parallèlement, nous avons placé une zone test dans DNS Cloud d'Alibaba. Après avoir délégué la zone à NS Ali, le temps de résolution est passé de 470 ms à 50 ms. Avant cela, la zone se trouvait également sur Cloudlfare.

Parallèlement au tunnel pour asie-est1 a creusé un autre tunnel de Shenzhen directement à nous-est4. Là, ils ont créé davantage de machines virtuelles proxy et ont commencé à tester les deux solutions, en acheminant le trafic de test à l'aide de cookies ou de DNS. Le banc de test est décrit schématiquement dans la figure suivante :

La latence des tunnels s'est avérée être la suivante :
Ali cn-shenzhen <—> GCP asie-est1 — 24 ms
Ali cn-shenzhen <—> GCP us-east4 — 200 ms

Les tests du navigateur Catchpoint ont rapporté une excellente amélioration.

Comparez les résultats des tests pour deux solutions :

décision
Uptime
Moyenne
75 centile
95 centile

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Il s'agit de données issues d'une solution qui utilise un tunnel IPSEC via asie-est1. Grâce à us-east4, les résultats étaient pires et il y avait plus d'erreurs, donc je ne donnerai pas les résultats.

Sur la base des résultats de ce test de deux tunnels, dont l'un se termine dans la région la plus proche de la Chine et l'autre à la destination finale, il est devenu clair qu'il est important de « sortir » du pare-feu chinois le plus rapidement possible. possible, puis utilisez des réseaux rapides (fournisseurs CDN, fournisseurs de cloud, etc.). Il n’est pas nécessaire d’essayer de traverser le pare-feu et d’arriver à destination d’un seul coup. Ce n'est pas le moyen le plus rapide.

En général, les résultats ne sont pas mauvais, cependant, semrush.com a une médiane de 8.8 et un 75 centile de 9.4 (sur le même test).
Et avant de poursuivre, je voudrais faire une petite digression lyrique.

digression

Une fois que l'utilisateur entre sur le site www.semrushchina.cn, qui est résolu via des serveurs DNS chinois « rapides », la requête HTTP passe par notre solution rapide. La réponse est renvoyée par le même chemin, mais le domaine est spécifié dans tous les scripts JS, pages HTML et autres éléments de la page Web semrush.com pour des ressources supplémentaires qui doivent être chargées lors du rendu de la page. Autrement dit, le client résout l'enregistrement A « principal » www.semrushchina.cn et entre dans le tunnel rapide, reçoit rapidement une réponse - une page HTML qui indique :

  • téléchargez tel ou tel js depuis sso.semrush.com,
  • Récupérez les fichiers CSS sur cdn.semrush.com,
  • et prenez également quelques photos de dab.semrush.com
  • et ainsi de suite.

Le navigateur commence à accéder à l'Internet « externe » pour ces ressources, en passant à chaque fois par un pare-feu qui consomme du temps de réponse.

Mais le test précédent montre les résultats lorsqu'il n'y a pas de ressources sur la page semrush.comseulement semrushchina.cn, et *.semrushchina.cn se résout à l'adresse de la machine virtuelle à Shenzhen afin d'accéder ensuite au tunnel.

Ce n'est qu'ainsi, en poussant au maximum tout le trafic possible via votre solution pour passer rapidement le pare-feu chinois, que vous pourrez obtenir des vitesses et des indicateurs d'accessibilité de site Web acceptables, ainsi que des résultats honnêtes de tests de solution.
Nous l'avons fait sans une seule modification de code du côté produit de l'équipe.

Sous-filtre

La solution est née presque immédiatement après l’apparition de ce problème. Nous avions besoin PoC (Preuve de Concept) que nos solutions de pénétration de pare-feu fonctionnent vraiment bien. Pour ce faire, vous devez intégrer autant que possible tout le trafic du site dans cette solution. Et nous avons postulé sous-filtre dans nginx.

Sous-filtre est un module assez simple dans nginx qui vous permet de remplacer une ligne du corps de la réponse par une autre ligne. Nous avons donc changé toutes les occurrences semrush.com sur semrushchina.cn dans toutes les réponses.

Et... cela n'a pas fonctionné car nous avons reçu du contenu compressé des backends, donc le sous-filtre n'a pas trouvé la ligne requise. J'ai dû ajouter un autre serveur local à nginx, qui a décompressé la réponse et l'a transmise au serveur local suivant, qui était déjà occupé à remplacer la chaîne, à la compresser et à l'envoyer au prochain serveur proxy de la chaîne.

En conséquence, où le client recevrait-il .semrush.com, il a reçu .semrushchina.cn et avons obéi docilement à notre décision.

Cependant, il ne suffit pas de simplement changer de domaine dans un sens, car les backends attendent toujours semrush.com dans les requêtes ultérieures du client. En conséquence, sur le même serveur où le remplacement unidirectionnel est effectué, à l'aide d'une simple expression régulière, nous obtenons le sous-domaine de la requête, puis nous le faisons proxy_pass avec variable $hôte, exposé dans $sous-domaine.semrush.com. Cela peut paraître déroutant, mais cela fonctionne. Et ça marche bien. Pour les domaines individuels nécessitant une logique différente, créez simplement vos propres blocs de serveur et effectuez une configuration distincte. Vous trouverez ci-dessous les configurations nginx raccourcies pour plus de clarté et de démonstration de ce schéma.

La configuration suivante traite toutes les demandes de la Chine vers .semrushchina.cn :

    listen 80;

    server_name ~^(?<subdomain>[w-]+).semrushchina.cn$;

    sub_filter '.semrush.com' '.semrushchina.cn';
    sub_filter_last_modified on;
    sub_filter_once off;
    sub_filter_types *;

    gzip on;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    location / {
        proxy_pass http://127.0.0.1:8083;
        proxy_set_header Accept-Encoding "";
        proxy_set_header Host $subdomain.semrush.com;
        proxy_set_header X-Accept-Encoding $http_accept_encoding;
    }
}

Cette configuration proxy pour localhost sur le port 83, et la configuration suivante y attend :

    listen 127.0.0.1:8083;

    server_name *.semrush.com;

    location / {
        resolver 8.8.8.8 ipv6=off;
        gunzip on;
        proxy_pass https://$host;
        proxy_set_header Accept-Encoding gzip;
    }
}

Je le répète, ce sont des configurations recadrées.

Comme ça. Cela peut paraître compliqué, mais c'est en mots. En fait, tout est plus simple que des navets vapeur :)

Fin de la parenthèse

Pendant un moment, nous étions heureux car le mythe de la chute des tunnels IPSEC n'était pas confirmé. Mais ensuite les tunnels ont commencé à s’effondrer. Plusieurs fois par jour pendant quelques minutes. Un peu, mais cela ne nous convenait pas. Étant donné que les deux tunnels se terminaient du côté Ali sur le même routeur, nous avons décidé qu'il s'agissait peut-être d'un problème régional et que nous devions augmenter la région de sauvegarde.

Ils l'ont ramassé. Les tunnels ont commencé à échouer à différents moments, mais le basculement a bien fonctionné pour nous au niveau amont de nginx. Mais ensuite les tunnels ont commencé à tomber à peu près au même moment 🙂 Et les 502 et 504 ont recommencé. La disponibilité a commencé à se détériorer, nous avons donc commencé à travailler sur l'option avec Alibaba CEN (Réseau d'entreprise cloud).

CEN

CEN - il s'agit de la connectivité de deux VPC de régions différentes au sein d'Alibaba Cloud, c'est-à-dire que vous pouvez connecter les réseaux privés de n'importe quelle région du cloud entre eux. Et surtout : cette chaîne a un contrôle assez strict Contrat de niveau de service. Il est très stable en termes de vitesse et de disponibilité. Mais ce n'est jamais aussi simple :

  • il est TRÈS difficile à obtenir si vous n'êtes pas citoyen chinois ou personne morale,
  • Vous devez payer pour chaque mégabit de capacité de canal.

Avoir la possibilité de se connecter Chine continentale и Étranger, nous avons créé un CEN entre deux régions Ali : cn-shenzhen и nous-est-1 (point le plus proche de us-east4). À Ali nous-est-1 a soulevé une autre machine virtuelle pour qu'il y en ait une de plus houblon.

Cela s'est passé comme ceci :

Les résultats des tests du navigateur sont ci-dessous :

décision
Uptime
Moyenne
75 centile
95 centile

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

Les performances sont légèrement meilleures que celles d'IPSEC. Mais via IPSEC, vous pouvez potentiellement télécharger à une vitesse de 100 Mbit/s, et via CEN uniquement à une vitesse de 5 Mbit/s et plus.

On dirait un hybride, non ? Combinez vitesse IPSEC et stabilité CEN.

C'est ce que nous avons fait, en autorisant le trafic via IPSEC et CEN en cas de panne du tunnel IPSEC. La disponibilité est devenue beaucoup plus élevée, mais la vitesse de chargement du site laisse encore beaucoup à désirer. Ensuite j'ai dessiné tous les circuits que nous avions déjà utilisés et testés, et j'ai décidé d'essayer d'ajouter un peu plus de GCP à ce circuit, à savoir GLB.

GLB

GLB - Est Équilibreur de charge global (ou Google Cloud Load Balancer). Cela présente pour nous un avantage important : dans le cadre d’un CDN, il a IP anycast, qui vous permet d'acheminer le trafic vers le centre de données le plus proche du client, afin que le trafic pénètre rapidement dans le réseau rapide de Google et passe moins par l'Internet « classique ».

Sans y réfléchir à deux fois, nous avons soulevé Livret HTTP/HTTPS Nous avons installé nos machines virtuelles avec sous-filtre dans GCP et en backend.

Il y avait plusieurs schémas :

  • À utiliser Réseau Cloudflare Chine, mais cette fois, Origin devrait spécifier global IP GLB.
  • Mettre fin aux clients à cn-shenzhen, et à partir de là, envoyez le trafic directement vers GLB.
  • Partir directement de Chine vers GLB.
  • Mettre fin aux clients à cn-shenzhen, de là proxy à asie-est1 via IPSEC (en nous-est4 via CEN), de là allez à GLB (calmement, il y aura une photo et une explication ci-dessous)

Nous avons testé toutes ces options et plusieurs autres options hybrides :

  • Cloudflare + GLB

Ce schéma ne nous convenait pas en raison d'erreurs de disponibilité et de DNS. Mais le test a été effectué avant que le bug ne soit corrigé côté CF, c'est peut-être mieux maintenant (cela n'exclut cependant pas les timeouts HTTP).

  • Ali + GLB

Ce schéma ne nous convenait pas non plus en termes de disponibilité, puisque GLB tombait souvent en amont en raison de l'impossibilité de se connecter dans un délai ou un timeout acceptable, car pour un serveur en Chine, l'adresse GLB reste à l'extérieur, et donc derrière le Pare-feu chinois. La magie n'a pas eu lieu.

  • GLB uniquement

Une option similaire à la précédente, sauf qu'elle n'utilisait pas de serveurs en Chine même : le trafic allait directement vers GLB (les enregistrements DNS ont été modifiés). En conséquence, les résultats n'ont pas été satisfaisants, car les clients chinois ordinaires utilisant les services de fournisseurs Internet ordinaires ont une situation bien pire en matière de passage du pare-feu qu'Ali Cloud.

  • Shenzhen -> (CEN/IPSEC) -> Proxy -> GLB

Ici, nous avons décidé d'utiliser la meilleure de toutes les solutions :

  • stabilité et SLA garanti par le CEN
  • haute vitesse d'IPSEC
  • Le réseau « rapide » de Google et son anycast.

Le schéma ressemble à ceci : le trafic utilisateur se termine sur une machine virtuelle dans ch-shenzhen. Les amonts Nginx y sont configurés, dont certains pointent vers des serveurs IP privés situés à l'autre extrémité du tunnel IPSEC, et certains amonts pointent vers des adresses privées de serveurs de l'autre côté du CEN. IPSEC configuré pour la région asie-est1 dans GCP (était la région la plus proche de la Chine au moment de la création de la solution. GCP est désormais également présent à Hong Kong). CEN - vers la région nous-est1 dans Ali Cloud.

Ensuite, le trafic des deux côtés a été dirigé vers anycast IPGLB, c'est-à-dire jusqu'au point de présence de Google le plus proche, et a traversé ses réseaux jusqu'à la région nous-est4 dans GCP, dans lequel il y avait des machines virtuelles de remplacement (avec sous-filtre dans nginx).

Cette solution hybride, comme nous l’espérions, a profité des avantages de chaque technologie. En général, le trafic passe par IPSEC rapide, mais si des problèmes commencent, nous expulsons rapidement et pendant quelques minutes ces serveurs du flux amont et envoyons le trafic uniquement via le CEN jusqu'à ce que le tunnel se stabilise.

En mettant en œuvre la solution 4 de la liste ci-dessus, nous avons obtenu ce que nous souhaitions et ce que l'entreprise exigeait de nous à ce moment-là.

Résultats des tests du navigateur pour la nouvelle solution par rapport aux précédentes :

décision
Uptime
Moyenne
75 centile
95 centile

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

CEN/IPsec + GLB
99.79
13s
16s
25s

CAN

Tout est bon dans la solution que nous avons mise en œuvre, mais il n'existe pas de CDN qui pourrait accélérer le trafic au niveau régional et même urbain. En théorie, cela devrait accélérer le site pour les utilisateurs finaux en utilisant les canaux de communication rapides du fournisseur CDN. Et nous y pensions tout le temps. Et maintenant, le moment est venu de passer à la prochaine itération du projet : rechercher et tester des fournisseurs de CDN en Chine.

Et je vous en parlerai dans la prochaine et dernière partie :)

Source: habr.com

Ajouter un commentaire