Hoe ons deur die Groot Chinese Firewall gebreek het (deel 2)

Привет!

Nikita is weer by jou, 'n stelselingenieur van die maatskappy SEMrush. En met hierdie artikel gaan ek voort met die storie oor hoe ons vorendag gekom het met 'n oplossing Chinese Firewall vir ons diens semrush.com.

В vorige deel Ek het gesê:

  • watter probleme ontstaan ​​nadat die besluit geneem is "Ons moet ons diens in China laat werk"
  • Watter probleme het die Chinese internet?
  • hoekom het jy 'n TKP-lisensie nodig?
  • hoe en hoekom ons besluit het om ons toetsbeddens met Catchpoint te toets
  • wat die resultaat was van ons eerste oplossing gebaseer op Cloudflare China Network
  • Hoe ons 'n fout in Cloudflare DNS gevind het

Hierdie deel is na my mening die interessantste, want dit fokus op spesifieke tegniese implementerings van staging. En ons sal begin, of liewer voortgaan, met Alibaba Wolk.

Alibaba Wolk

Alibaba Wolk is 'n redelike groot wolkverskaffer, wat al die dienste het wat hom in staat stel om homself eerlik 'n wolkverskaffer te noem. Dit is goed dat hulle die geleentheid het om vir buitelandse gebruikers te registreer, en dat die meeste van die webwerf in Engels vertaal word (vir China is dit 'n luukse). In hierdie wolk kan jy met baie streke van die wêreld, die vasteland van China, sowel as Oseaniese Asië (Hong Kong, Taiwan, ens.) werk.

IPsec

Ons het met geografie begin. Aangesien ons toetswebwerf op Google Cloud geleë was, moes ons Alibaba Cloud met GCP “koppel”, so ons het 'n lys van liggings oopgemaak waarin Google teenwoordig is. Op daardie oomblik het hulle nog nie hul eie datasentrum in Hong Kong gehad nie.
Die naaste streek blyk te wees Asië-Oos 1 (Taiwan). Ali het geblyk die naaste streek van die vasteland van China aan Taiwan te wees cn-shenzhen (Shenzhen).

Met terraform die hele infrastruktuur in GCP en Ali beskryf en verhoog het. ’n 100 Mbit/s-tonnel tussen die wolke het byna onmiddellik opgegaan. Aan die kant van Shenzhen en Taiwan is virtuele volmagmasjiene geskep. In Shenzhen word gebruikersverkeer beëindig, deur 'n tonnel na Taiwan gestuur, en van daar af gaan dit direk na die eksterne IP van ons diens in ons-oos (VSA Ooskus). Ping tussen virtuele masjiene via tonnel 24ms, wat nie so erg is nie.

Terselfdertyd het ons 'n toetsarea in geplaas Alibaba Wolk DNS. Nadat die sone aan NS Ali gedelegeer is, het die resolusietyd van 470 ms tot XNUMX ms afgeneem 50 Me. Voor dit was die sone ook op Cloudlfare.

Parallel met die tonnel na Asië-Oos 1 het 'n ander tonnel van Shenzhen direk na ons-oos4. Daar het hulle meer virtuele proxy-masjiene geskep en albei oplossings begin toets, toetsverkeer met koekies of DNS gelei. Die toetsbank word skematies in die volgende figuur beskryf:

Latency vir tonnels blyk soos volg te wees:
Ali cn-shenzhen <—> GCP asië-ooste1 - 24ms
Ali cn-shenzhen <—> GCP us-east4 - 200ms

Catchpoint-blaaiertoetse het uitstekende verbetering gerapporteer.

Vergelyk toetsresultate vir twee oplossings:

besluit
Uptime
mediaan
75 persentiel
95 persentiel

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Dit is data van 'n oplossing wat 'n IPSEC-tonnel via Asië-Oos 1. Deur us-east4 was die resultate slegter, en daar was meer foute, so ek sal nie die resultate gee nie.

Op grond van die resultate van hierdie toets van twee tonnels, waarvan een in die naaste streek aan China beëindig word, en die ander by die eindbestemming, het dit duidelik geword dat dit belangrik is om so vinnig as wat onder die Chinese brandmuur te "opkom" moontlik is, en gebruik dan vinnige netwerke (CDN-verskaffers, wolkverskaffers, ens.). Dit is nie nodig om deur die firewall te probeer kom en in een klap by jou bestemming uit te kom nie. Dit is nie die vinnigste manier nie.

Oor die algemeen is die resultate nie sleg nie, maar semrush.com het 'n mediaan van 8.8s, en 75 Persentiel 9.4s (op dieselfde toets).
En voordat ek verder gaan, wil ek graag 'n kort liriese afwyking maak.

Liriese toevlug

Nadat die gebruiker die webwerf betree het www.semrushchina.cn, wat deur “vinnige” Chinese DNS-bedieners opgelos word, gaan die HTTP-versoek deur ons vinnige oplossing. Die antwoord word langs dieselfde pad teruggestuur, maar die domein word in alle JS-skrifte, HTML-bladsye en ander elemente van die webblad gespesifiseer semrush.com vir bykomende hulpbronne wat gelaai moet word wanneer die bladsy gelewer word. Dit wil sê, die kliënt los die "hoof" A-rekord op www.semrushchina.cn en gaan in die vinnige tonnel, ontvang vinnig 'n reaksie - 'n HTML-bladsy wat sê:

  • laai sulke en sulke js af van sso.semrush.com,
  • Kry die CSS-lêers van cdn.semrush.com,
  • en neem ook 'n paar foto's van dab.semrush.com
  • en so aan.

Die blaaier begin om na die "eksterne" internet te gaan vir hierdie hulpbronne, en gaan elke keer deur 'n firewall wat reaksietyd opvreet.

Maar die vorige toets wys die resultate wanneer daar geen hulpbronne op die bladsy is nie semrush.comnet semrushchina.cn, en *.semrushchina.cn gaan na die adres van die virtuele masjien in Shenzhen om dan in die tonnel te kom.

Slegs op hierdie manier, deur alle moontlike verkeer tot die maksimum deur jou oplossing te druk om vinnig deur die Chinese firewall te gaan, kan jy aanvaarbare snelhede en webwerf-beskikbaarheid-aanwysers verkry, sowel as eerlike resultate van oplossingstoetse.
Ons het dit gedoen sonder 'n enkele kodewysiging aan die span se produkkant.

Subfilter

Die oplossing is feitlik onmiddellik gebore nadat hierdie probleem opgeduik het. Ons het nodig gehad PoC (Proof of Concept) dat ons firewall penetrasie oplossings regtig goed werk. Om dit te doen, moet u al die werfverkeer soveel as moontlik in hierdie oplossing insluit. En ons het aansoek gedoen subfilter in nginx.

Subfilter is 'n redelik eenvoudige module in nginx wat jou toelaat om een ​​lyn in die antwoordliggaam na 'n ander lyn te verander. Ons het dus alle gebeure verander semrush.com op semrushchina.cn in alle antwoorde.

En ... dit het nie gewerk nie, want ons het saamgeperste inhoud van die backends ontvang, so subfilter het nie die vereiste lyn gevind nie. Ek moes nog 'n plaaslike bediener by nginx voeg, wat die reaksie gedekomprimeer het en dit aan die volgende plaaslike bediener deurgegee het, wat reeds besig was om die string te vervang, dit saam te druk en dit na die volgende instaanbediener in die ketting te stuur.

As gevolg hiervan, waar sou die kliënt ontvang .semrush.com, hy het ontvang .semrushchina.cn en gehoorsaam deur ons besluit gestap het.

Dit is egter nie genoeg om bloot die domein een manier te verander nie, want die backends verwag steeds semrush.com in daaropvolgende versoeke van die kliënt. Gevolglik, op dieselfde bediener waar die eenrigtingvervanging gedoen word, met behulp van 'n eenvoudige gereelde uitdrukking kry ons die subdomein van die versoek, en dan doen ons proxy_pass met veranderlike $gasheer, uitgestal in $subdomein.semrush.com. Dit lyk dalk verwarrend, maar dit werk. En dit werk goed. Vir individuele domeine wat verskillende logika benodig, skep eenvoudig jou eie bedienerblokke en maak 'n aparte konfigurasie. Hieronder is verkorte nginx-konfigurasies vir duidelikheid en demonstrasie van hierdie skema.

Die volgende konfigurasie verwerk alle versoeke vanaf China na .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;
    }
}

Hierdie konfigurasie gee gevolmagtigdes na localhost na poort 83, en die volgende konfigurasie wag daar:

    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;
    }
}

Ek herhaal, dit is afgesnyde konfigurasies.

Soos dit. Dit lyk dalk ingewikkeld, maar dit is in woorde. Trouens, alles is eenvoudiger as gestoomde raap :)

Einde van afwyking

Vir 'n rukkie was ons bly omdat die mite oor vallende IPSEC-tonnels nie bevestig is nie. Maar toe begin die tonnels val. Verskeie kere per dag vir 'n paar minute. Bietjie, maar dit het ons nie gepas nie. Aangesien beide tonnels aan die Ali-kant op dieselfde roeteerder beëindig is, het ons besluit dat dit miskien 'n streeksprobleem is en dat ons die rugsteunstreek moet verhoog.

Hulle het dit opgetel. Die tonnels het op verskillende tye begin misluk, maar die failover het goed gewerk vir ons op die stroomop-vlak in nginx. Maar toe begin die tonnels omtrent dieselfde tyd val 🙂 En weer begin 502 en 504. Uptyd het begin verswak, so ons het begin werk aan die opsie met Alibaba CEN (Cloud Enterprise Network).

CEN

CEN - dit is die verbinding van twee VPC's uit verskillende streke binne Alibaba Cloud, dit wil sê, jy kan private netwerke van enige streke binne die wolk met mekaar verbind. En die belangrikste: hierdie kanaal het 'n redelik streng SLA. Dit is baie stabiel in spoed en uptyd. Maar dit is nooit so eenvoudig nie:

  • dit is BAIE moeilik om te verkry as jy nie Chinese burgers of 'n regspersoon is nie,
  • Jy moet betaal vir elke megabit kanaalkapasiteit.

Met die geleentheid om te verbind China и oorsese, ons het 'n CEN tussen twee Ali-streke geskep: cn-shenzhen и ons-oos-1 (naaste punt aan ons-oos4). In Ali ons-oos-1 'n ander virtuele masjien opgewek sodat daar nog een is hop.

Dit het so uitgedraai:

Die blaaiertoetsresultate is hieronder:

besluit
Uptime
mediaan
75 persentiel
95 persentiel

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

Die werkverrigting is effens beter as IPSEC. Maar deur IPSEC kan jy moontlik aflaai teen 'n spoed van 100 Mbit/s, en deur CEN slegs teen 'n spoed van 5 Mbit/s en meer.

Klink soos 'n baster, reg? Kombineer IPSEC-spoed en CEN-stabiliteit.

Dit is wat ons gedoen het, wat verkeer deur beide IPSEC en CEN toegelaat het in die geval van 'n mislukking van die IPSEC-tonnel. Uptyd het baie hoër geword, maar die laaispoed van die webwerf laat nog veel te wense oor. Toe teken ek al die stroombane wat ons reeds gebruik en getoets het, en besluit om 'n bietjie meer GCP by hierdie stroombaan te probeer voeg, nl. pet.

pet

pet - Is Global Load Balancer (of Google Cloud Load Balancer). Dit het 'n belangrike voordeel vir ons: in die konteks van 'n CDN het dit anycast IP, wat jou toelaat om verkeer na die datasentrum naaste aan die kliënt te stuur, sodat verkeer vinnig by Google se vinnige netwerk inkom en minder deur die "gewone" internet gaan.

Sonder om twee keer te dink, het ons grootgemaak HTTP/HTTPS LB Ons het ons virtuele masjiene met subfilter in GCP en as 'n backend geïnstalleer.

Daar was verskeie skemas:

  • maak gebruik van Cloudflare China-netwerk, maar hierdie keer moet Origin globaal spesifiseer IP GLB.
  • Beëindig kliënte by cn-shenzhen, en van daar af proxy die verkeer direk na pet.
  • Gaan reguit van China na pet.
  • Beëindig kliënte by cn-shenzhen, van daar gevolmagtigde na Asië-Oos 1 via IPSEC (in ons-oos4 via CEN), gaan van daar na GLB (rustig, daar sal 'n foto en verduideliking hieronder wees)

Ons het al hierdie opsies en nog verskeie baster opsies getoets:

  • Cloudflare + GLB

Hierdie skema het ons nie gepas nie weens uptyd en DNS-foute. Maar die toets is uitgevoer voordat die fout aan die CF-kant reggestel is, miskien is dit nou beter (dit sluit egter nie HTTP-time-outs uit nie).

  • Ali + GLB

Hierdie skema het ons ook nie gepas in terme van uptyd nie, aangesien GLB dikwels uit die stroomop geval het as gevolg van die onmoontlikheid om binne 'n aanvaarbare tyd of time-out te koppel, want vir 'n bediener binne China bly die GLB-adres buite, en dus agter die Chinese firewall. Die magie het nie gebeur nie.

  • Slegs GLB

'N Opsie soortgelyk aan die vorige, maar dit het nie bedieners in China self gebruik nie: die verkeer het direk na GLB gegaan (die DNS-rekords is verander). Gevolglik was die resultate nie bevredigend nie, aangesien gewone Chinese kliënte wat die dienste van gewone internetverskaffers gebruik, 'n baie erger situasie het om die firewall te slaag as Ali Cloud.

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

Hier het ons besluit om die beste van alle oplossings te gebruik:

  • stabiliteit en gewaarborgde SLA van CEN
  • hoë spoed van IPSEC
  • Google se "vinnige" netwerk en sy enige uitsending.

Die skema lyk iets soos volg: gebruikersverkeer word beëindig op 'n virtuele masjien in ch-shenzhen. Nginx-stroomop word daar gekonfigureer, waarvan sommige verwys na private IP-bedieners wat aan die ander kant van die IPSEC-tonnel geleë is, en sommige stroomop verwys na private adresse van bedieners aan die ander kant van die CEN. IPSEC opgestel na streek Asië-Oos 1 in GCP (was die naaste streek aan China toe die oplossing geskep is. GCP het nou ook 'n teenwoordigheid in Hong Kong). CEN - na streek ons-oos1 in Ali Cloud.

Toe is die verkeer van albei kante na anycast IP GLB, dit wil sê, na die naaste punt van teenwoordigheid van Google, en het deur sy netwerke na die streek gegaan ons-oos4 in GCP, waarin daar virtuele vervangingsmasjiene was (met subfilter in nginx).

Hierdie hibriede oplossing, soos ons verwag het, het voordeel getrek uit die voordele van elke tegnologie. Oor die algemeen gaan verkeer deur vinnige IPSEC, maar as probleme begin, skop ons hierdie bedieners vinnig en vir 'n paar minute uit die stroomop en stuur verkeer slegs deur CEN totdat die tonnel stabiliseer.

Deur die 4de oplossing uit die lys hierbo te implementeer, het ons bereik wat ons wou hê en wat die besigheid op daardie tydstip van ons vereis het.

Blaaiertoetsresultate vir die nuwe oplossing in vergelyking met voriges:

besluit
Uptime
mediaan
75 persentiel
95 persentiel

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

Alles is goed in die oplossing wat ons geïmplementeer het, maar daar is geen CDN wat verkeer op streek- en selfs stadsvlak kan versnel nie. In teorie behoort dit die webwerf vir eindgebruikers te bespoedig deur die vinnige kommunikasiekanale van die CDN-verskaffer te gebruik. En ons het heeltyd daaraan gedink. En nou het die tyd aangebreek vir die volgende herhaling van die projek: soek en toets CDN-verskaffers in China.

En ek sal jou hieroor vertel in die volgende, laaste deel :)

Bron: will.com

Voeg 'n opmerking