Hallo!
U spreekt weer met Nikita ā systeemingenieur van het bedrijf SEMrush. In dit artikel ga ik verder met het verhaal over hoe we een oplossing voor het omzeilen bedachten van de Chinese Firewall voor onze dienst semrush.com.
In Ik vertelde:
- wat voor problemen er ontstaan na de beslissing āWe moeten ervoor zorgen dat onze dienst in China werktā
- wat voor problemen er zijn met het Chinese internet
- waarom een ICP-licentie nodig is
- hoe en waarom we besloten onze testomgevingen te testen met behulp van Catchpoint
- welk resultaat onze eerste oplossing op basis van het Cloudflare China Network heeft opgegeleverd
- hoe we een bug in DNS Cloudflare hebben gevonden
Dit deel is het interessantste, naar mijn mening, omdat het zich richt op specifieke technische implementaties van de staging. En we beginnen, of beter gezegd, gaan verder met Alibaba Cloud.
Alibaba Cloud
Alibaba Cloud ā een behoorlijk grote cloud provider die alle diensten biedt die hem in staat stellen zich eerlijk een cloudprovider te noemen. Het is goed dat buitenlandse gebruikers zich kunnen registreren en dat een groot deel van de site in het Engels is vertaald (voor China is dat een luxe). In deze cloud kan men werken met verschillende regio's van de wereld, het vasteland van China, evenals de Oceaan AziĆ« (Hongkong, Taiwan, enz.).
IPSEC
We begonnen met de geografie. Omdat onze testsite zich in Google Cloud bevond, moesten we Alibaba Cloud met GCP āverbindenā, dus openden we de lijst met locaties waar Google aanwezig is. Op dat moment hadden ze nog geen datacenter in Hongkong.
De dichtstbijzijnde regio was asia-east1 (Taiwan). De dichtstgelegen regio van Ali voor het continentale China ten opzichte van Taiwan was cn-shenzhen (Shenzhen).
Met terraform we hebben de hele infrastructuur in GCP en Ali beschreven en opgezet. De tunnel van 100 Mbit/s tussen de clouds werd praktisch onmiddellijk opgezet. Aan de Shenzhen- en Taiwan-kant werden proxy-virtuele machines opgezet. In Shenzhen wordt het gebruikersverkeer beƫindigd, gepasseerd via de tunnel naar Taiwan, en van daaruit gaat het rechtstreeks naar het externe IP van onze dienst in us-east (Oostkust van de VS). De ping tussen de virtuele machines via de tunnel 24ms, wat niet slecht is.
Gelijktijdig hebben we een testzone opgezet in Alibaba Cloud DNS. Na delegatie van de zone naar NS Ali, daalde de resolvetijd van 470 ms naar 50 ms. Hiervoor was de zone ook op Cloudflafare.
Gelijktijdig met de tunnel naar asia-east1 hebben we nog een tunnel vanuit Shenzhen rechtstreeks opgezet in us-east4. Ze hebben nog proxy-virtuellen gemaakt en zijn begonnen met het meten van beide oplossingen, waarbij ze testverkeer routeerden met behulp van cookies of DNS. Het teststand is schematisch weergegeven in de volgende afbeelding:
De latency voor de tunnels was als volgt:
Ali cn-shenzhen GCP asia-east1 ā 24ms
Ali cn-shenzhen GCP us-east4 ā 200ms
Browser-testen van Catchpoint rapporteerden een uitstekende verbetering van de prestaties.
Vergelijk de testresultaten voor de twee oplossingen:
Oplossing
Uptime
Mediaan
75 percentiel
95 percentiel
Cloudflare
86.6
18s
30s
60s
IPsec
99.79
18s
21s
30s
Dit zijn de gegevens van de oplossing die een IPSEC-tunnel via asia-east1. Via us-east4 waren de resultaten slechter en waren er meer fouten, dus ik zal de resultaten niet geven.
Op basis van deze test van de twee tunnels, waarvan er ƩƩn eindigt in de dichtstbijzijnde regio bij China en de andere op de eindbestemming, is het duidelijk geworden dat het belangrijk is om zo snel mogelijk "uit" de Chinese firewall te komen en daarna snelle netwerken (CDN-providers, cloudproviders, enz.) te gebruiken. Probeer niet in ƩƩn keer door de firewall te gaan en de bestemming te bereiken. Dit is niet de snelste route.
Over het algemeen zijn de resultaten redelijk, maar semrush.com heeft een mediaan van 8.8s en 75 percentiel van 9.4s (bij dezelfde test).
En voordat we verder gaan, wil ik een kleine lyrische zijstap maken.
Lyrische uitweiding
Nadat de gebruiker de site bezoekt www.semrushchina.cn, die wordt opgelost via de "snelle" Chinese DNS-servers, gaat de HTTP-aanroep via onze snelle oplossing. Het antwoord komt dezelfde weg terug, maar in alle JS-scripts, HTML-pagina's en andere elementen van de webpagina is het domein semrush.com vermeld voor extra bronnen die moeten worden geladen bij het weergeven van de pagina. Dat wil zeggen, de cliĆ«nt lost de "hoofd" A-record op www.semrushchina.cn en gaat via de snelle tunnel, ontvangt snel een response ā een HTML-pagina, waarin staat:
- download bijvoorbeeld deze js van sso.semrush.com,
- verzamel CSS-bestanden van cdn.semrush.com,
- en haal ook afbeeldingen van dab.semrush.com.
- en zo verder.
De browser begint naar het "externe" internet te gaan voor deze bronnen, elke keer door de tijdslopende firewall.
Maar in de vorige test zijn de resultaten gepresenteerd wanneer de pagina geen bronnen heeft semrush.com, alleen semrushchina.cn, terwijl *.semrushchina.cn wordt opgelost naar het adres van de virtuele machine in Shenzhen, om vervolgens de tunnel binnen te gaan.
Alleen door zoveel mogelijk verkeer via onze oplossing voor snel door de Chinese firewall te gaan, kunnen we acceptabele snelheden en beschikbaarheid van de website behalen, evenals eerlijke testresultaten van de oplossingen.
We hebben dit gedaan zonder enige wijziging in de code aan de productzijde.
Subfilter
De oplossing kwam vrijwel onmiddellijk nadat dit probleem opdook. We hadden nodig PoC (Proof of Concept) dat onze oplossingen voor het passeren van de firewall echt goed werken. Hiervoor moest al het verkeer van de site via deze oplossing worden geleid. En we hebben toegepast in nginx.
Subfilter Dit is een vrij eenvoudige module in nginx die het mogelijk maakt om ƩƩn regel in de response body door een andere regel te vervangen. Dus hebben we alle vermeldingen vervangen semrush.com en een werkende opdracht krijgen. semrushchina.cn in alle responses.
En... het werkte niet, omdat we van de backend gecomprimeerde inhoud ontvingen, dus subfilter vond de benodigde regel niet. We moesten een andere lokale server aan nginx toevoegen die de response decompressie deed en deze doorgaf aan de volgende lokale server, die zich bezighield met het vervangen van de regel, comprimeren en deze doorgeven aan de volgende proxyserver in de keten.
Uiteindelijk, waar de klant zou krijgen .semrush.com, kreeg hij .semrushchina.cn en ging geduldig door onze oplossing.
Het is echter niet genoeg om het domein in ƩƩn richting te vervangen, aangezien de backends nog steeds semrush.com verwachten in de daaropvolgende verzoeken van de klant. Dus op dezelfde server, waar de vervangingen in ƩƩn richting plaatsvinden, krijgen we met behulp van een eenvoudig regulier expressie de subdomein uit het verzoek, en dan doen we proxy_pass met de variabele $host, ingesteld op $subdomain.semrush.com.Het lijkt misschien verwarrend, maar het werkt. En het werkt goed. Voor aparte domeinen die andere logica vereisen, worden eenvoudigweg aparte serverblokken aangemaakt met een aparte configuratie. Hieronder zijn verkorte nginx-configuraties weergegeven voor duidelijkheid en demonstratie van dit schema.
De volgende configuratie verwerkt alle verzoeken uit China op .semrushchina.cn:
luister 80;
server_name ~^(?<subdomain>[w-]+).semrushchina.cn$;
sub_filter '.semrush.com' '.semrushchina.cn';
sub_filter_last_modified aan;
sub_filter_once uit;
sub_filter_types *;
gzip aan;
gzip_proxied iedereen;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
locatie / {
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;
}
}Deze configuratie proxy'd naar localhost poort 83, waar de volgende configuratie wacht:
luister 127.0.0.1:8083;
server_name *.semrush.com;
locatie / {
resolver 8.8.8.8 ipv6=uit;
gunzip aan;
proxy_pass https://$host;
proxy_set_header Accept-Encoding gzip;
}
}Ik herhaal, dit zijn ingekorte configuraties.
Zo ongeveer. Het kan ingewikkeld lijken, maar dat is het in woorden. In werkelijkheid is het eenvoudiger dan het lijkt š
Einde van de lyrische zijpaal
Een tijdje waren we gelukkig, omdat de mythe over falende IPSEC-tunnels niet bevestigd werd. Maar toen begonnen de tunnels te vallen. Een paar keer per dag voor een paar minuten. Niet veel, maar het beviel ons niet. Aangezien beide tunnels aan de Ali-kant op ƩƩn router werden beƫindigd, dachten we dat dit misschien een regionaal probleem was en dat we een back-up regio moesten opzetten.
We hebben het opgezet. De tunnels begonnen op verschillende tijden te vallen, maar onze failover werkte uitstekend op upstream-niveau in nginx. Maar toen begonnen de tunnels ongeveer gelijktijdig te vallen š En de 502 en 504-fouten begonnen weer. De uptime begon te verslechteren, dus we gingen een optie uitwerken met Alibaba CEN (Cloud Enterprise Network).
CEN
CEN is de connectiviteit tussen twee VPC's uit verschillende regio's binnen Alibaba Cloud, wat betekent dat je privƩ-netwerken uit verschillende regio's binnen de cloud met elkaar kunt verbinden. En het belangrijkste: dit kanaal heeft een behoorlijk strenge SLA. Het is zeer stabiel wat betreft snelheid en uptime. Maar het is nooit zo eenvoudig:
- het is heel moeilijk te verkrijgen als je geen Chinese burgers of rechtspersonen bent,
- je moet betalen voor elke megabit bandbreedte.
Na de mogelijkheid te hebben gekregen om te verbinden Mainland China en Overzees, hebben we CEN tussen twee Ali-regio's opgezet: cn-shenzhen en us-east-1 (de dichtstbijzijnde locatie bij us-east-4). In Ali us-east-1 hebben we nog een virtuele machine opgezet om nog een hop.
Het resultaat was als volgt:
De resultaten van de browser tests zijn hieronder:
Oplossing
Uptime
Mediaan
75 percentiel
95 percentiel
Cloudflare
86.6
18s
30s
60s
IPsec
99.79
18s
21s
30s
CEN
99.75
16s
21s
27s
De resultaten zijn iets beter dan die van IPSEC. Maar via IPSEC kun je potentieel met een snelheid van 100 Mbit/s downloaden, terwijl dat via CEN slechts 5 Mbit/s is en duurder.
Een hybride oplossing ligt voor de hand, nietwaar? Snelheid van IPSEC combineren met de stabiliteit van CEN.
Zo hebben we het gedaan, door verkeer zowel via IPSEC als via CEN door te laten geven in het geval van een IPSEC-tunneluitval. De uptime is veel hoger geworden, maar de laadsnelheid van de website kon nog beter. Toen tekende ik alle schema's die we al gebruikt en getest hadden en besloot ik om nog wat GCP toe te voegen aan dit schema, namelijk GLB.
GLB
GLB is (of Google Cloud Load Balancer). Het heeft een belangrijk voordeel voor ons: in de context van CDN heeft het anycast IP, wat het mogelijk maakt om verkeer naar de dichtstbijzijnde datacentrum van de klant te routeren, waardoor het verkeer sneller in het snelle netwerk van Google komt en minder via het 'normale' internet gaat.
Zonder al te veel tijd te verspillen hebben we HTTP/HTTPS LB op GCP opgezet en de backend met onze virtuele machines met subfilter ingesteld.
Er waren verschillende schema's:
- Gebruik Cloudflare China Network, maar deze keer als origin de globale IP GLB.
- Klanten beƫindigen in cn-shenzhen, en van daaruit verkeer direct doorsturen naar GLB.
- Direct vanuit China naar GLB.
- Klanten beƫindigen in cn-shenzhen, van daaruit proxen naar asia-east1 via IPSEC (via us-east4 via CEN), van daaruit naar GLB (we zullen hieronder een afbeelding en uitleg hebben)
We hebben al deze opties en nog een paar hybride getest:
- Cloudflare + GLB
Deze opzet voldeed niet aan onze uptime en DNS-fouten. Maar de test werd uitgevoerd voordat de bug aan de CF-zijde was verholpen, misschien is het nu beter (toch sluit dit HTTP-timeouts niet uit).
- Ali + GLB
Deze opzet voldeed ook niet aan onze uptime, aangezien GLB vaak uit de upstream viel door de onmogelijkheid om op een acceptabele tijd verbinding te maken of door timeouts, aangezien het GLB-adres voor de server binnen China nog steeds buiten is, wat betekent dat het achter de Chinese firewalls ligt. Er is geen magie gebeurd.
- GLB only
Een optie die lijkt op de vorige, maar zonder servers in China: het verkeer ging direct naar GLB (we hebben de DNS-records veranderd). Daarom voldeed de situatie niet, aangezien de normale Chinese klanten die gebruikmaken van gewone internetproviders veel meer problemen hebben met het passeren van firewalls dan bij Ali Cloud.
- Shenzhen -> (CEN/IPSEC) -> Proxy -> GLB
Hier besloten we het beste van alle oplossingen te gebruiken:
- de stabiliteit en gegarandeerde SLA van CEN
- hoge snelheid van IPSEC
- het 'snelle' netwerk van Google en zijn anycast.
Het schema ziet er ongeveer zo uit: het verkeer van gebruikers wordt beƫindigd op een virtuele machine in ch-shenzhenDaar zijn upstreams van nginx ingesteld, waarvan een deel verwijst naar private IP-servers aan de andere kant van de IPSEC-tunnel, en een deel van de upstreams verwijst naar private adressen van servers aan de andere kant van CEN. IPSEC werd ingesteld tot de regio asia-east1 in GCP (dit was de dichtstbijzijnde regio bij China op het moment van de oplossing. Nu heeft GCP ook een aanwezigheid in Hongkong). CEN is tot de regio us-east1 in Ali Cloud.
Vervolgens werd het verkeer van beide kanten geleid naar anycast IP GLB, dat wil zeggen naar het dichtstbijzijnde Google-knooppunt, en het ging via zijn netwerken naar de regio us-east4 in GCP, waar vervangende virtuele machines stonden (met subfilter in nginx).
Deze hybride oplossing, zoals we verwachtten, stelde ons in staat om de voordelen van elke technologie te benutten. Over het algemeen gaat het verkeer via snelle IPSEC, maar als er problemen optreden, verwijderen we snel en voor enkele minuten deze servers uit de upstreams en sturen we het verkeer alleen via CEN, totdat de tunnel weer stabiel is.
Door de 4e oplossing uit de bovenstaande lijst te implementeren, hebben we bereikt wat we wilden en wat het bedrijf op dat moment van ons vereiste.
Resultaten van de browser-tests voor de nieuwe oplossing in vergelijking met de vorige:
Oplossing
Uptime
Mediaan
75 percentiel
95 percentiel
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
CDN
In de oplossing die we hebben geĆÆmplementeerd, is alles goed, alleen is er geen CDN dat het verkeer op regionaal en zelfs stedelijk niveau zou kunnen versnellen. In theorie zou dit de werking van de website voor eindgebruikers moeten versnellen door gebruik te maken van de snelle communicatiekanalen van de CDN-provider. En we hebben de hele tijd aan dit aspect gedacht. En nu is het tijd voor de volgende iteratie van het project: op zoek naar en testen van CDN-providers in China.
En hierover zal ik jullie vertellen in het volgende, laatste deel š
Bron: habr.com
