Jak jsme prolomili Velký čínský firewall (část 2)

Ahoj!

Nikita je opět s vámi, systémový inženýr ze společnosti SEMrush. A tímto článkem pokračuji v příběhu o tom, jak jsme přišli s řešením Čínský firewall pro naši službu semrush.com.

В předchozí díl Řekl jsem:

  • jaké problémy nastanou po přijetí rozhodnutí „Musíme zajistit, aby naše služby fungovaly v Číně“
  • Jaké problémy má čínský internet?
  • proč potřebujete licenci ICP?
  • jak a proč jsme se rozhodli otestovat naše testovací zařízení pomocí Catchpoint
  • jaký byl výsledek našeho prvního řešení založeného na Cloudflare China Network
  • Jak jsme našli chybu v Cloudflare DNS

Tato část je podle mého názoru nejzajímavější, protože se zaměřuje na konkrétní technické realizace inscenace. A začneme, nebo spíše budeme pokračovat Alibaba Cloud.

Alibaba Cloud

Alibaba Cloud je poměrně velký cloudový poskytovatel, který má všechny služby, díky kterým se může poctivě nazývat cloudovým poskytovatelem. Je dobře, že mají možnost se zaregistrovat pro zahraniční uživatele a že většina stránek je přeložena do angličtiny (pro Čínu je to luxus). V tomto cloudu můžete pracovat s mnoha regiony světa, pevninskou Čínou i oceánskou Asií (Hongkong, Tchaj-wan atd.).

IPSEC

Začali jsme zeměpisem. Vzhledem k tomu, že náš testovací web byl umístěn na Google Cloud, potřebovali jsme „propojit“ Alibaba Cloud s GCP, takže jsme otevřeli seznam lokalit, ve kterých je Google přítomen. V té chvíli ještě neměli vlastní datové centrum v Hong Kongu.
Nejbližší region se ukázal být Asie-východ 1 (Tchaj-wan). Ali se ukázalo být nejbližší oblastí pevninské Číny k Tchaj-wanu cn-shenzhen (Shenzhen).

S terraform popsal a zvýšil celou infrastrukturu v GCP a Ali. Tunel o rychlosti 100 Mbit/s mezi mraky se zvedl téměř okamžitě. Na straně Shenzhenu a Tchaj-wanu byly vytvořeny virtuální stroje proxy. V Shenzhenu je uživatelský provoz ukončen, přes proxy server přes tunel na Tchaj-wan a odtud jde přímo na externí IP naší služby v USA východ (východní pobřeží USA). Ping mezi virtuálními stroji přes tunel 24ms, což není tak špatné.

Zároveň jsme umístili testovací oblast Alibaba Cloud DNS. Po delegování zóny na NS Ali se doba rozlišení snížila z 470 ms na 50 ms. Předtím byla zóna také na Cloudlfare.

Paralelně s tunelem k Asie-východ 1 zvedl další tunel ze Shenzhenu přímo do nás-východ 4. Tam vytvořili další proxy virtuální stroje a začali testovat obě řešení, přičemž testovací provoz směrovali pomocí cookies nebo DNS. Zkušební stolice je schematicky popsána na následujícím obrázku:

Latence pro tunely se ukázala být následující:
Ali cn-shenzhen <—> GCP Asie-východ1 – 24 ms
Ali cn-shenzhen <—> GCP us-east4 — 200 ms

Testy prohlížeče Catchpoint hlásily vynikající zlepšení.

Porovnejte výsledky testů pro dvě řešení:

rozhodnutí
Uptime
Medián
75 percentil
95 percentil

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Jedná se o data z řešení, které využívá IPSEC tunel přes Asie-východ 1. Přes nás-východ4 byly výsledky horší a bylo tam více chyb, takže výsledky neuvedu.

Na základě výsledků tohoto testu dvou tunelů, z nichž jeden je ukončen v nejbližším regionu k Číně a druhý v cílové destinaci, se ukázalo, že je důležité „vynořit se“ zpod čínského firewallu co nejrychleji možné a poté použít rychlé sítě (poskytovatelé CDN , poskytovatelé cloudu atd.). Není třeba se pokoušet dostat přes firewall a dostat se do cíle jedním tahem. Toto není nejrychlejší způsob.

Výsledky obecně nejsou špatné, nicméně semrush.com má medián 8.8 s a 75 percentil 9.4 (ve stejném testu).
A než budu pokračovat, rád bych udělal krátkou lyrickou odbočku.

Lyrická odbočka

Poté, co uživatel vstoupí na web www.semrushchina.cn, který řeší prostřednictvím „rychlých“ čínských serverů DNS, požadavek HTTP prochází naším rychlým řešením. Odpověď je vrácena stejnou cestou, ale doména je uvedena ve všech skriptech JS, HTML stránkách a dalších prvcích webové stránky semrush.com pro další zdroje, které je nutné načíst při vykreslování stránky. To znamená, že klient vyřeší „hlavní“ záznam A www.semrushchina.cn a přejde do rychlého tunelu, rychle obdrží odpověď - stránku HTML, která uvádí:

  • stáhněte si takový a takový js z sso.semrush.com,
  • Získejte soubory CSS z cdn.semrush.com,
  • a také pořiďte nějaké obrázky z dab.semrush.com
  • a tak dále.

Prohlížeč začne pro tyto zdroje přecházet na „externí“ internet, pokaždé, když prochází bránou firewall, která spotřebovává dobu odezvy.

Předchozí test však ukazuje výsledky, když na stránce nejsou žádné zdroje semrush.compouze semrushchina.cna *.semrushchina.cn se přeloží na adresu virtuálního počítače v Shenzhenu, aby se pak dostal do tunelu.

Jedině tak, vytlačením veškerého možného provozu na maximum přes vaše řešení pro rychlý průchod čínským firewallem, můžete získat přijatelné rychlosti a indikátory dostupnosti webu a také poctivé výsledky testů řešení.
Udělali jsme to bez jediné úpravy kódu na produktové straně týmu.

Podfiltr

Řešení se zrodilo téměř okamžitě poté, co se tento problém objevil. Potřebovali jsme PoC (Proof of Concept), že naše řešení pronikání firewallem opravdu fungují dobře. Chcete-li to provést, musíte do tohoto řešení co nejvíce zabalit veškerý provoz webu. A přihlásili jsme se podfiltr v nginx.

Podfiltr je poměrně jednoduchý modul v nginx, který vám umožňuje změnit jeden řádek v těle odpovědi na jiný řádek. Takže jsme změnili všechny výskyty semrush.com na semrushchina.cn ve všech odpovědích.

A... nefungovalo to, protože jsme obdrželi komprimovaný obsah z backendů, takže podfiltr nenašel požadovaný řádek. Musel jsem přidat další místní server do nginx, který dekomprimoval odpověď a předal ji dalšímu místnímu serveru, který byl již zaneprázdněn výměnou řetězce, jeho komprimací a odesláním na další proxy server v řetězci.

V důsledku toho, kde by klient obdržel semrush.com, obdržel .semrushchina.cn a poslušně prošel naším rozhodnutím.

Nestačí však jednoduše změnit doménu jedním způsobem, protože backendy stále očekávají semrush.com v následných požadavcích od klienta. V souladu s tím na stejném serveru, kde se provádí jednosměrné nahrazení, pomocí jednoduchého regulárního výrazu získáme subdoménu z požadavku a poté provedeme proxy_pass s proměnnou $ hostitel, vystavený v $subdomain.semrush.com. Může se to zdát matoucí, ale funguje to. A funguje to dobře. Pro jednotlivé domény, které vyžadují odlišnou logiku, jednoduše vytvořte vlastní bloky serveru a proveďte samostatnou konfiguraci. Níže jsou zkrácené konfigurace nginx pro jasnost a demonstraci tohoto schématu.

Následující konfigurace zpracovává všechny požadavky z Číny do .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;
    }
}

Tato konfigurace proxy servery k localhost na port 83 a čeká tam následující konfigurace:

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

Opakuji, toto jsou oříznuté konfigurace.

Takhle. Možná to vypadá složitě, ale je to slovy. Ve skutečnosti je vše jednodušší než tuřín v páře :)

Konec odbočky

Chvíli jsme byli rádi, protože mýtus o padajících IPSEC tunelech se nepotvrdil. Pak ale začaly padat tunely. Několikrát denně na několik minut. Trochu, ale to nám nevyhovovalo. Vzhledem k tomu, že oba tunely byly ukončeny na straně Ali na stejném routeru, rozhodli jsme se, že se možná jedná o regionální problém a potřebujeme zvýšit záložní region.

Sebrali to. Tunely začaly selhávat v různých časech, ale přepnutí při selhání nám fungovalo dobře na upstream úrovni v nginx. Pak ale začaly padat tunely zhruba ve stejnou dobu 🙂 A znovu začaly 502 a 504. Doba provozu se začala zhoršovat, takže jsme začali pracovat na možnosti s Alibaba CEN (Cloud Enterprise Network).

CEN

CEN - jedná se o konektivitu dvou VPC z různých regionů v rámci Alibaba Cloud, to znamená, že můžete vzájemně propojit privátní sítě libovolných regionů v cloudu. A co je nejdůležitější: tento kanál je poměrně přísný SLA. Je velmi stabilní jak v rychlosti, tak v době provozu. Ale nikdy to není tak jednoduché:

  • je VELMI obtížné získat, pokud nejste čínští občané nebo právnická osoba,
  • Musíte platit za každý megabit kapacity kanálu.

Mít možnost se připojit Čína pevniny и Zámoří, vytvořili jsme CEN mezi dvěma regiony Ali: cn-shenzhen и nás-východ-1 (nejbližší bod k nám-východ4). V Ali nás-východ-1 zvedl další virtuální stroj, takže existuje ještě jeden poskok.

Dopadlo to takto:

Výsledky testu prohlížeče jsou níže:

rozhodnutí
Uptime
Medián
75 percentil
95 percentil

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

Výkon je o něco lepší než IPSEC. Ale přes IPSEC můžete potenciálně stahovat rychlostí 100 Mbit/s a přes CEN pouze rychlostí 5 Mbit/s a více.

Zní to jako hybrid, že? Kombinujte rychlost IPSEC a stabilitu CEN.

To jsme udělali a umožnili provoz přes IPSEC i CEN v případě selhání tunelu IPSEC. Uptime se stal mnohem vyšší, ale rychlost načítání stránek stále zůstává hodně žádoucí. Poté jsem nakreslil všechny obvody, které jsme již použili a otestovali, a rozhodl jsem se, že se pokusím do tohoto obvodu přidat trochu více GCP, jmenovitě víčko.

víčko

víčko - Je Global Load Balancer (nebo Google Cloud Load Balancer). Má to pro nás důležitou výhodu: v kontextu CDN to má anycast IP, který umožňuje směrovat provoz do datového centra nejblíže klientovi, takže se provoz rychle dostane do rychlé sítě Google a méně přes „běžný“ internet.

Bez přemýšlení jsme zvedli HTTP/HTTPS LB Nainstalovali jsme naše virtuální stroje s podfiltrem v GCP a jako backend.

Bylo několik schémat:

  • Chcete-li použít Cloudflare China Network, ale tentokrát by Origin měl specifikovat global IP GLB.
  • Ukončit klienty na cn-shenzhena odtud proxy provoz přímo na víčko.
  • Jděte přímo z Číny do víčko.
  • Ukončit klienty na cn-shenzhen, odtud proxy do Asie-východ 1 přes IPSEC (v nás-východ 4 přes CEN), odtud jděte do GLB (klidně níže bude obrázek a vysvětlení)

Testovali jsme všechny tyto možnosti a několik dalších hybridních:

  • Cloudflare + GLB

Toto schéma nám nevyhovovalo kvůli dostupnosti a chybám DNS. Ale test byl proveden před opravou chyby na straně CF, možná je to nyní lepší (to však nevylučuje časové limity HTTP).

  • Ali + GLB

Toto schéma nám nevyhovovalo ani z hlediska dostupnosti, protože GLB často vypadávalo z upstreamu kvůli nemožnosti připojení v přijatelném čase nebo časovém limitu, protože pro server v Číně zůstává adresa GLB mimo, a tedy za čínský firewall. Kouzlo se nekonalo.

  • Pouze GLB

Možnost podobná předchozí, pouze nepoužívala servery v samotné Číně: provoz šel přímo do GLB (došlo ke změně DNS záznamů). Výsledky tedy nebyly uspokojivé, protože běžní čínští klienti využívající služby běžných poskytovatelů internetu mají mnohem horší situaci s průchodem firewallem než Ali Cloud.

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

Zde jsme se rozhodli použít to nejlepší ze všech řešení:

  • stabilita a garantovaná SLA od CEN
  • vysoká rychlost od IPSEC
  • „Rychlá“ síť Google a její Anycast.

Schéma vypadá asi takto: uživatelský provoz je ukončen na virtuálním počítači v ch-shenzhen. Jsou tam konfigurovány upstreamy Nginx, z nichž některé ukazují na privátní IP servery umístěné na druhém konci tunelu IPSEC a některé upstreamy odkazují na soukromé adresy serverů na druhé straně CEN. IPSEC nakonfigurováno pro region Asie-východ 1 v GCP (v době vytvoření řešení to byl nejbližší region k Číně. GCP má nyní také zastoupení v Hongkongu). CEN - do regionu nás-východ 1 v Ali Cloud.

Poté byl provoz z obou konců směrován na anycast IP GLB, tedy do nejbližšího bodu přítomnosti Googlu, a prošel jeho sítěmi do regionu nás-východ 4 v GCP, ve kterých byly náhradní virtuální stroje (s podfiltrem v nginx).

Toto hybridní řešení, jak jsme očekávali, využilo výhod jednotlivých technologií. Obecně platí, že provoz prochází rychlým IPSEC, ale pokud začnou problémy, rychle a na několik minut tyto servery vykopneme z upstreamu a pošleme provoz pouze přes CEN, dokud se tunel nestabilizuje.

Implementací 4. řešení z výše uvedeného seznamu jsme dosáhli toho, co jsme chtěli a co od nás podnikání v daném okamžiku vyžadovalo.

Výsledky testů prohlížeče pro nové řešení ve srovnání s předchozími:

rozhodnutí
Uptime
Medián
75 percentil
95 percentil

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

V námi implementovaném řešení je vše dobré, ale chybí CDN, která by mohla zrychlit dopravu na regionální a dokonce městské úrovni. Teoreticky by to mělo zrychlit web pro koncové uživatele pomocí rychlých komunikačních kanálů poskytovatele CDN. A celou dobu jsme na to mysleli. A nyní nastal čas pro další iteraci projektu: vyhledávání a testování poskytovatelů CDN v Číně.

A o tom vám povím v další, závěrečné části :)

Zdroj: www.habr.com

Přidat komentář