Hvordan vi brøt gjennom den store kinesiske brannmuren (del 2)

Hei!

Nikita er med deg igjen, en systemingeniør fra selskapet SEMrush. Og med denne artikkelen fortsetter jeg historien om hvordan vi kom opp med en løsning Kinesisk brannmur for vår tjeneste semrush.com.

В forrige del Jeg sa:

  • hvilke problemer som oppstår etter at avgjørelsen er tatt "Vi må få tjenesten vår til å fungere i Kina"
  • Hvilke problemer har det kinesiske Internett?
  • hvorfor trenger du en ICP-lisens?
  • hvordan og hvorfor vi bestemte oss for å teste testsengene våre med Catchpoint
  • hva var resultatet av vår første løsning basert på Cloudflare China Network
  • Hvordan vi fant en feil i Cloudflare DNS

Denne delen er den mest interessante, etter min mening, fordi den fokuserer på spesifikke tekniske implementeringer av iscenesettelse. Og vi skal begynne, eller rettere sagt fortsette, med Alibaba Cloud.

Alibaba Cloud

Alibaba Cloud er en ganske stor skyleverandør, som har alle tjenestene som gjør at den ærlig kan kalle seg en skyleverandør. Det er bra at de har mulighet til å registrere seg for utenlandske brukere, og at det meste av siden er oversatt til engelsk (for Kina er dette en luksus). I denne skyen kan du jobbe med mange regioner i verden, fastlands-Kina, så vel som Oceanic Asia (Hong Kong, Taiwan, etc.).

IPsec

Vi startet med geografi. Siden testsiden vår var lokalisert på Google Cloud, måtte vi "koble" Alibaba Cloud med GCP, så vi åpnet en liste over steder der Google er til stede. På det tidspunktet hadde de ennå ikke sitt eget datasenter i Hong Kong.
Den nærmeste regionen viste seg å være Asia-øst 1 (Taiwan). Ali viste seg å være den nærmeste regionen på fastlands-Kina til Taiwan cn-shenzhen (Shenzhen).

Med terra beskrevet og hevet hele infrastrukturen i GCP og Ali. En 100 Mbit/s tunnel mellom skyene gikk opp nesten øyeblikkelig. På siden av Shenzhen og Taiwan ble virtuelle maskiner med proxy-tjener reist. I Shenzhen termineres brukertrafikken, prokseres gjennom en tunnel til Taiwan, og derfra går den direkte til den eksterne IP-en til tjenesten vår i oss-øst (USAs østkyst). Ping mellom virtuelle maskiner via tunnel 24ms, som ikke er så ille.

Samtidig plasserte vi et testområde i Alibaba Cloud DNS. Etter delegering av sonen til NS Ali, ble oppløsningstiden redusert fra 470 ms til 50 ms. Før dette var sonen også på Cloudlfare.

Parallelt med tunnelen til Asia-øst 1 hevet en annen tunnel fra Shenzhen direkte til oss-øst4. Der opprettet de flere virtuelle proxy-maskiner og begynte å teste begge løsningene, rute testtrafikk ved hjelp av informasjonskapsler eller DNS. Testbenken er beskrevet skjematisk i følgende figur:

Latens for tunneler viste seg å være som følger:
Ali cn-shenzhen <—> GCP asia-east1 — 24ms
Ali cn-shenzhen <—> GCP us-east4 — 200ms

Catchpoint-nettlesertester rapporterte utmerket forbedring.

Sammenlign testresultater for to løsninger:

beslutning
Oppetid
median
75 prosentil
95 prosentil

CloudFlare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Dette er data fra en løsning som bruker en IPSEC-tunnel via Asia-øst 1. Gjennom us-east4 var resultatene dårligere, og det var flere feil, så jeg vil ikke gi resultatene.

Basert på resultatene av denne testen av to tunneler, hvorav den ene er avsluttet i den nærmeste regionen til Kina, og den andre på den endelige destinasjonen, ble det klart at det er viktig å "komme opp" fra under den kinesiske brannmuren så raskt som mulig, og deretter bruke raske nettverk (CDN-leverandører, skyleverandører, etc.). Det er ingen grunn til å prøve å komme seg gjennom brannmuren og komme deg til destinasjonen med ett brak. Dette er ikke den raskeste måten.

Generelt er resultatene ikke dårlige, men semrush.com har en median på 8.8 s, og 75 Percentile 9.4 s (på samme test).
Og før jeg går videre, vil jeg gjøre en kort lyrisk digresjon.

Lyrisk digresjon

Etter at brukeren går inn på nettstedet www.semrushchina.cn, som løses gjennom "raske" kinesiske DNS-servere, går HTTP-forespørselen gjennom vår raske løsning. Svaret returneres langs samme vei, men domenet er spesifisert i alle JS-skript, HTML-sider og andre elementer på nettsiden semrush.com for ytterligere ressurser som må lastes inn når siden gjengis. Det vil si at klienten løser "hoved" A-posten www.semrushchina.cn og går inn i den raske tunnelen, mottar raskt et svar - en HTML-side som sier:

  • last ned slike og slike js fra sso.semrush.com,
  • Få CSS-filene fra cdn.semrush.com,
  • og ta også noen bilder fra dab.semrush.com
  • og så videre.

Nettleseren begynner å gå til det "eksterne" Internett for disse ressursene, hver gang den går gjennom en brannmur som spiser opp responstiden.

Men den forrige testen viser resultatene når det ikke er ressurser på siden semrush.combare semrushchina.cn, og *.semrushchina.cn løser til adressen til den virtuelle maskinen i Shenzhen for deretter å komme inn i tunnelen.

Bare på denne måten, ved å presse all mulig trafikk til det maksimale gjennom løsningen din for raskt å passere den kinesiske brannmuren, kan du oppnå akseptable hastigheter og nettstedtilgjengelighetsindikatorer, samt ærlige resultater av løsningstester.
Vi gjorde dette uten en eneste koderedigering på teamets produktside.

Underfilter

Løsningen ble født nesten umiddelbart etter at dette problemet dukket opp. Vi trengte PoC (Proof of Concept) at våre brannmurpenetrasjonsløsninger virkelig fungerer bra. For å gjøre dette, må du pakke inn all nettstedtrafikken i denne løsningen så mye som mulig. Og vi søkte underfilter i nginx.

Underfilter er en ganske enkel modul i nginx som lar deg endre en linje i responskroppen til en annen linje. Så vi endret alle forekomster semrush.comsemrushchina.cn i alle svar.

Og ... det fungerte ikke fordi vi mottok komprimert innhold fra backends, så subfilter fant ikke den nødvendige linjen. Jeg måtte legge til en annen lokal server til nginx, som dekomprimerte svaret og sendte det videre til neste lokale server, som allerede var opptatt med å erstatte strengen, komprimere den og sende den til neste proxy-server i kjeden.

Som et resultat, hvor ville klienten motta .semrush.com, han mottok .semrushchina.cn og gikk lydig gjennom avgjørelsen vår.

Det er imidlertid ikke nok å bare endre domenet én vei, fordi backends fortsatt forventer semrush.com i påfølgende forespørsler fra klienten. Følgelig, på den samme serveren der enveiserstatningen gjøres, ved å bruke et enkelt regulært uttrykk henter vi subdomenet fra forespørselen, og så gjør vi proxy_pass med variabel $ vert, utstilt i $subdomain.semrush.com. Det kan virke forvirrende, men det fungerer. Og det fungerer bra. For individuelle domener som krever forskjellig logikk, lag ganske enkelt dine egne serverblokker og lag en separat konfigurasjon. Nedenfor er forkortede nginx-konfigurasjoner for klarhet og demonstrasjon av dette opplegget.

Følgende konfigurasjon behandler alle forespørsler fra Kina til .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;
    }
}

Denne konfigurasjonen proxyer til localhost til port 83, og følgende konfigurasjon venter der:

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

Jeg gjentar, dette er beskårne konfigurasjoner.

Slik. Det kan se komplisert ut, men det er i ord. Faktisk er alt enklere enn dampede kålrot :)

Slutt på digresjon

En stund var vi glade fordi myten om fallende IPSEC-tunneler ikke ble bekreftet. Men så begynte tunnelene å falle. Flere ganger om dagen i noen minutter. Litt, men det passet ikke oss. Siden begge tunnelene ble avsluttet på Ali-siden på samme ruter, bestemte vi oss for at dette kanskje var et regionalt problem, og vi måtte heve reserveregionen.

De tok den opp. Tunnelene begynte å svikte til forskjellige tider, men failoveren fungerte bra for oss på oppstrømsnivå i nginx. Men så begynte tunnelene å falle omtrent samtidig 🙂 Og 502 og 504 startet igjen. Oppetiden begynte å bli dårligere, så vi begynte å jobbe med alternativet med Alibaba CEN (Cloud Enterprise Network).

CEN

CEN - dette er tilkoblingen til to VPC-er fra forskjellige regioner i Alibaba Cloud, det vil si at du kan koble private nettverk i alle regioner i skyen med hverandre. Og viktigst av alt: denne kanalen har en ganske streng SLA. Den er veldig stabil både i hastighet og oppetid. Men det er aldri så enkelt:

  • det er VELDIG vanskelig å få tak i hvis du ikke er kinesiske statsborgere eller en juridisk enhet,
  • Du må betale for hver megabit med kanalbåndbredde.

Å ha muligheten til å koble seg på Fastlands-Kina и Overseas, opprettet vi en CEN mellom to Ali-regioner: cn-shenzhen и us-øst-1 (nærmeste punkt til oss-øst4). I Ali us-øst-1 hevet en annen virtuell maskin slik at det er en til hop.

Det ble slik:

Nettlesertestresultatene er nedenfor:

beslutning
Oppetid
median
75 prosentil
95 prosentil

CloudFlare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

Ytelsen er litt bedre enn IPSEC. Men gjennom IPSEC kan du potensielt laste ned med en hastighet på 100 Mbit/s, og gjennom CEN kun med en hastighet på 5 Mbit/s og mer.

Høres ut som en hybrid, ikke sant? Kombiner IPSEC-hastighet og CEN-stabilitet.

Dette er hva vi gjorde, og tillot trafikk gjennom både IPSEC og CEN i tilfelle feil i IPSEC-tunnelen. Oppetiden har blitt mye høyere, men lastehastigheten på nettstedet etterlater fortsatt mye å være ønsket. Så tegnet jeg alle kretsene som vi allerede hadde brukt og testet, og bestemte meg for å prøve å legge til litt mer GCP til denne kretsen, nemlig lokk.

lokk

lokk - Er Global Load Balancer (eller Google Cloud Load Balancer). Det har en viktig fordel for oss: i sammenheng med et CDN har det anycast IP, som lar deg rute trafikk til datasenteret nærmest klienten, slik at trafikk raskt kommer inn i Googles raske nettverk og mindre går gjennom det «vanlige» Internett.

Uten å tenke to ganger hevet vi HTTP/HTTPS LB Vi installerte våre virtuelle maskiner med subfilter i GCP og som backend.

Det var flere ordninger:

  • Bruk Cloudflare China Network, men denne gangen bør Origin spesifisere global IP GLB.
  • Avslutt kunder kl cn-shenzhen, og derfra proxy trafikken direkte til lokk.
  • Gå rett fra Kina til lokk.
  • Avslutt kunder kl cn-shenzhen, derfra proxy til Asia-øst 1 via IPSEC (in oss-øst4 via CEN), derfra gå til GLB (rolig, det vil være et bilde og forklaring nedenfor)

Vi testet alle disse alternativene og flere hybride:

  • Cloudflare + GLB

Dette opplegget passet ikke oss på grunn av oppetid og DNS-feil. Men testen ble utført før feilen ble fikset på CF-siden, kanskje den er bedre nå (dette utelukker imidlertid ikke HTTP-tidsavbrudd).

  • Ali + GLB

Dette opplegget passet heller ikke oss med tanke på oppetid, siden GLB ofte falt ut av oppstrøms på grunn av umuligheten av å koble til i en akseptabel tid eller timeout, fordi for en server inne i Kina forblir GLB-adressen utenfor, og derfor bak Kinesisk brannmur. Magien skjedde ikke.

  • Kun GLB

Et alternativ som ligner på det forrige, bare det brukte ikke servere i selve Kina: trafikken gikk direkte til GLB (DNS-postene ble endret). Følgelig var resultatene ikke tilfredsstillende, siden vanlige kinesiske kunder som bruker tjenestene til vanlige Internett-leverandører har en mye verre situasjon med å passere brannmuren enn Ali Cloud.

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

Her bestemte vi oss for å bruke den beste av alle løsninger:

  • stabilitet og garantert SLA fra CEN
  • høy hastighet fra IPSEC
  • Googles "raske" nettverk og dets anycast.

Opplegget ser omtrent slik ut: brukertrafikk avsluttes på en virtuell maskin i ch-shenzhen. Nginx oppstrøms er konfigurert der, hvorav noen peker til private IP-servere plassert i den andre enden av IPSEC-tunnelen, og noen oppstrøms peker til private adresser til servere på den andre siden av CEN. IPSEC konfigurert til region Asia-øst 1 i GCP (var den nærmeste regionen til Kina på det tidspunktet løsningen ble opprettet. GCP har nå også en tilstedeværelse i Hong Kong). CEN - til region oss-øst1 i Ali Cloud.

Da ble trafikk fra begge ender dirigert til anycast IP GLB, det vil si til det nærmeste stedet for tilstedeværelse av Google, og gikk gjennom nettverkene til regionen oss-øst4 i GCP, der det var virtuelle erstatningsmaskiner (med subfilter i nginx).

Denne hybridløsningen, som vi forventet, utnyttet fordelene med hver teknologi. Generelt går trafikken gjennom rask IPSEC, men hvis problemer starter, sparker vi raskt og i noen minutter disse serverne ut av oppstrøms og sender trafikk kun gjennom CEN til tunnelen stabiliserer seg.

Ved å implementere den fjerde løsningen fra listen ovenfor, oppnådde vi det vi ønsket og hva virksomheten krevde av oss på det tidspunktet.

Nettlesertestresultater for den nye løsningen sammenlignet med tidligere:

beslutning
Oppetid
median
75 prosentil
95 prosentil

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

Alt er bra i løsningen vi implementerte, men det er ingen CDN som kan akselerere trafikken på regionalt og til og med bynivå. I teorien bør dette øke hastigheten på siden for sluttbrukere ved å bruke de raske kommunikasjonskanalene til CDN-leverandøren. Og vi tenkte på det hele tiden. Og nå er tiden inne for neste iterasjon av prosjektet: søk og testing av CDN-leverandører i Kina.

Og jeg skal fortelle deg om dette i neste, siste del :)

Kilde: www.habr.com

Legg til en kommentar