Jak przeszliśmy przez Wielki Chiński Firewall (cz. 1)

Cześć wszystkim!

Na łączach Nikita – inżynier systemowy z firmy SEMrush. Dziś opowiem wam o zadaniu, które przed nami stanęło: zapewnienie stabilności działania naszej usługi semrush.com w Chinach oraz z jakimi problemami się spotkaliśmy podczas jej realizacji (biorąc pod uwagę lokalizację naszego centrum danych na wschodnim wybrzeżu USA).

To będzie długa historia, podzielona na kilka artykułów. Opowiem, jak to wszystko u nas wyglądało: od całkowicie nie działającej usługi z Chin, aż po wskaźniki działania usługi na poziomie jej amerykańskiej wersji dla Amerykanów. Obiecuję, że będzie to interesujące i przydatne. No to zaczynamy.

Problemy chińskiego internetu

Nawet najodleglejsza osoba od specyfiki administracji sieciowej przynajmniej raz słyszała o Wielkim Chińskim Firewallu. Uu, brzmi dobrze, prawda? Ale co to jest, jak to naprawdę działa – to dość skomplikowane pytanie. W Internecie można znaleźć wiele artykułów na ten temat, ale z technicznego punktu widzenia, działanie tego firewalla nie jest nigdzie opisane. Co, zresztą, nie jest zaskakujące. Przyznam, że po roku pracy nie będę w stanie powiedzieć dokładnie, jak on działa, ale mogę opisać swoje uwagi i praktyczne wnioski. Zacznijmy od plotek na temat tego firewalla.

Krąży wiele plotek na temat tego firewalla. Zbierzmy najważniejsze i najciekawsze z nich w jedną listę:

  • Google, Facebook, Twitter i inne podobne usługi są zablokowane i nie działają w Chinach.
  • Każdy ruch, który wychodzi z Chin lub wchodzi do Chin, jest przetwarzany i ograniczany przy użyciu uczenia maszynowego (w przypadku podejrzanego ruchu), co znacznie spowalnia (ruch) przechodzący przez granicę.
  • Chińskie służby specjalne złamią każdy zaszyfrowany ruch, który przechodzi przez ich firewall.
  • Tunelowanie VPN, tunelowanie IPSEC jest niestabilne, pada i jest ciągle blokowane.
  • Im prostsze szyfrowanie, im prostsza fraza hasłowa używana do autoryzacji/szyfrowania ruchu, tym szybciej przechodzi przez chiński firewall.

Oto, co udało nam się ustalić na temat tych plotek:

  • Google, Facebook, Twitter i inne podobne usługi są rzeczywiście zablokowane (twój KOD), ale wiele technicznych domen Google, na przykład, nie jest zablokowanych i działa (ta sama gstatic.com). Z tego wynika wniosek: nie należy bezmyślnie blokować wszystkich zasobów Google i innych, które wydają się zablokowane.
  • Każdy ruch przekraczający granicę rzeczywiście dodaje znaczący opóźnienie do swojego czasu. Zobaczcie dwa wyniki. Jedna strona, jedna strona, prosty GET curlz Chiny (wspaniałe miasto Shenzhen). Drugi pomiar z zewnątrz z Hongkongu (ma suwerenność, a między nim a światem nie ma zapory). Odległość między miastami w linii prostej wynosi około 30-40 km.

nikita@china-shenzhen:~# curl -o /dev/null -w@curl_time "https://www.semrush.com/info/ebay.com"
  % Całkowity    % Odebrany % Xferd  Średnia prędkość   Czas    Czas     Czas  Bieżący
                                 Dload  Upload   Całkowity   Spędzony   Pozostanie  Prędkość
100  381k    0  381k    0     0  71824      0 --:--:--  0:00:05 --:--:-- 82832
time_namelookup:  0.004500
time_connect:  0.169342
time_appconnect:  0.723189
time_pretransfer:  0.723499
time_redirect:  0.000000
time_starttransfer:  1.532912
----------
time_total:  5.443407
----------
size_download:  390968 Bajtów
speed_download:  71824.000B/s

nikita@china-hongkong:~# curl -o /dev/null -w@curl_time "https://www.semrush.com/info/ebay.com"
  % Całkowity    % Odebrany % Xferd  Średnia prędkość   Czas    Czas     Czas  Bieżący
                                 Dload  Upload   Całkowity   Spędzony   Pozostanie  Prędkość
100  319k    0  319k    0     0  2555k      0 --:--:-- --:--:-- --:--:-- 2573k
time_namelookup:  0.029366
time_connect:  0.030742
time_appconnect:  0.047310
time_pretransfer:  0.047388
time_redirect:  0.000000
time_starttransfer:  0.120793
----------
time_total:  0.124871
----------
size_download:  326755 Bajtów
speed_download:  2616740.000B/s

Zwróć uwagę na time_connect. I ogólnie, widzisz wynik: zapora dodaje 4 dodatkowe sekundy, co jest niesamowicie długo.

  • VPN i tunele IPSEC rzeczywiście często się psują. O tym opowiem później i dokładniej. Serwery VPN, których używają użytkownicy, z czasem są blokowane (zwykle w ciągu doby po rozpoczęciu użytkowania).
  • Istnieje opinia pochodząca od ludzi mieszkających w Chinach, że im prostsze szyfrowanie ruchu, tym szybciej przechodzi on przez granicę, ponieważ łatwo jest zrozumieć, że nie zawiera nic nielegalnego. I podobnie „czysty” ruch otrzymuje więcej pasma i prędkości przejścia, a „brudny” ruch, w którym nic nie da się rozróżnić, wręcz przeciwnie, uzyskuje wolniejsze przejście. Na przykład przedstawię curl do ifconfig.co protokół HTTPS i HTTP.

curl -o /dev/null -w@curl_time "https://ifconfig.co/"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    13  100    13    0     0      2      0  0:00:06  0:00:05  0:00:01     3
time_namelookup:  0.004305
time_connect:  0.397465
time_appconnect:  5.149305
time_pretransfer:  5.149393
time_redirect:  0.000000
time_starttransfer:  5.568847
----------
time_total:  5.568893
----------
size_download:  13 Bytes
speed_download:  2.000B/s

curl -o /dev/null -w@curl_time "http://ifconfig.co/"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    13  100    13    0     0     28      0 --:--:-- --:--:-- --:--:--    28
time_namelookup:  0.004282
time_connect:  0.212457
time_appconnect:  0.000000
time_pretransfer:  0.212484
time_redirect:  0.000000
time_starttransfer:  0.450565
----------
time_total:  0.450620
----------
size_download:  13 Bytes
speed_download:  28.000B/s

Różnica w czasie ładowania 13 bajtów wynosi 5 sekund. Warto zauważyć, że wykonując ten test kilka razy, GET na HTTP kończy się w zasadzie w tym samym czasie za każdym razem, podczas gdy na HTTPS strona czasami odpowiada w ciągu 3, 5, 10 a nawet 17 sekund. Czasami występują błędy SSL:

Nieznany błąd protokołu SSL podczas łączenia z ifconfig.co:443.

Zatem, co mamy:

  • Problemy generowane przez chiński firewall, opisane powyżej.
  • Ping do zewnętrznych zasobów oraz wewnątrz tuneli okresowo znika.
  • Opóźnienie między dwoma punktami stale się zmienia, a często jest po prostu nieprzewidywalne. Łącząc różne miasta/regiony, oczekujesz, że w oparciu o geograficzne położenie regionów, opóźnienie będzie mniejsze, a otrzymujesz dokładnie odwrotną sytuację.
  • Internet i kanały komunikacyjne działają raz szybko, raz wolno. Istnieje tu pewna zależność od pory dnia i dnia tygodnia, ale nie zawsze.
  • Zapytania DNS do świata zewnętrznego z Chin czasami przekraczają dozwolony czas oczekiwania.

Obraz rysuje się po prostu “doskonały”.

Centrum danych, jak już wspomniałem, znajduje się na wschodzie USA, a cały SEMrush składa się z dziesiątek wzajemnie powiązanych produktów, backendów, frontendów, baz danych, i wszystko to w DC oraz w chmurach. Przed nami, jako zespołem administratorów systemów, postawiono zadanie, aby przy minimalnym wysiłku szybko rozpocząć działalność w Chinach.

Musieliśmy odpowiedzieć na ważne pytanie: czy można obejść się małym kosztem i rozwiązać wszystkie problemy związane z chińskim internetem i firewallem na poziomie sieci/chmur/serwerów?

Zaczęliśmy od uzyskania ICP-licencji.

Licencja ICP

Aby móc umieścić swoją usługę w Chinach (Mainland China) i przeprowadzać testy, należy najpierw uzyskać licencję ICP na domenę.

Jeśli ruch użytkowników na twojej stronie jest zakończony w kontynentalnych Chinach i jeśli twoja domena nie ma licencji ICP, twój ruch będzie blokowany po stronie dostawcy / hostingu. Co ciekawe, do licencji ICP wpisany jest konkretny dostawca, czy to Cloudflare, czy Alibaba Cloud. Dlatego, jeśli uzyskałeś licencję ICP dla Cloudflare i umieściłeś swoją stronę u nich, późniejsze „bezproblemowe” przeniesienie na Alibaba Cloud nie będzie możliwe. Będzie konieczne dodanie do tej licencji jeszcze jednego hostingu.

Uzyskując licencję ICP dla domeny, mogliśmy wymyślać i wdrażać konkretne techniczne pomysły i rozwiązania.

Testowanie rozwiązań

Ale zanim bezpośrednio zaczniemy tworzyć opcje stagingowe, kręcić gałkami, optymalizować działanie strony oraz jej szybkość, musimy wybrać narzędzie do jej testowania, aby zobaczyć, jakie nasze działania poprawiają lub wręcz przeciwnie, pogarszają działanie strony.

Nasze narzędzie do testowania musi spełniać dwa główne wymagania:

  • musi mieć możliwość uruchamiania testów z Chin,
  • musi mieć testy przeglądarkowe.

W ten sposób znaleźliśmy Catchpoint! Mają doskonałe pokrycie punktami testowymi na całym świecie. W Chinach za pomocą tego narzędzia można uruchamiać testy również z 100500 prowincji. W każdej po kilku różnych dostawców + możliwość wykonywania testów Backbone (coś w rodzaju wirtualki w centrum danych) oraztestów Lastmile (jak najbardziej zbliżonych do warunków użytkowników, aka stacja robocza). Ostatni typ testów jest droższy. Zawierając roczną umowę (mniej nie można), przystąpiliśmy do badania narzędzia. Muszę przyznać, byliśmy miło zaskoczeni jego funkcjonalnością. Można uruchamiać:testy DNS,

testy Web (przeglądarkowe, prosty GET/POST, emulacja klienta mobilnego itd.),

  • sprawdzanie transakcyjne (na przykład logowanie),
  • testy API,
  • Ping, traceroute, NTP itd.
  • Nie da się wszystkiego wymienić. I co najważniejsze, każdy test można całkiem dobrze dostosować, dodając zestaw nagłówków i innych parametrów. W rezultacie otrzymujesz ogromną ilość informacji, w pełni opisujących twój test. Jeśli chodzi o to, co nas najbardziej interesuje (testy przeglądarkowe), wyniki obejmują:
  • Czas połączenia, Czas oczekiwania, Czas ładowania, SSL, Czas DNS,

TTFB, TTLB, Zakończenie dokumentu, Czas renderowania, Ładowanie DOM,

  • Odpowiedź (coś bliskiego Czasowi Do Pierwszego Bajtu), Odpowiedź Strony WWW (coś bliskiego Czasowi Do Ostatniego Bajtu),
  • Wszelkie percentyle, Średni czas, Mediana czasu
  • I tym podobne.
  • Dowolne percentyle, Średnia, Mediana czasu
  • I tym podobne.

W związku z tym wszystkie te metryki doskonale pomagają dostrzegać zmiany i rozumieć, czy sytuacja się poprawiła. Głównie skupialiśmy się na Response, Webpage Response, Median, 75 i 95 percentyla.

Ważne pytanie, które wisi w powietrzu od samego początku: czy można ufać Catchpoint? Отражает ли этот инструмент реальную скорость загрузки сайта в Китае из разных городов или же это просто какой-то тест в вакууме, не имеющий ничего общего с real user experience?
To duży problem, ponieważ będąc w Rosji, praktycznie niemożliwe jest wiarygodne sprawdzenie, jak działa strona z Chin. Korzystając z proxy socks przez wirtualną maszynę, otrzymuje się ładowanie strony przez kilka minut, co jest całkowicie nieakceptowalne dla testów, więc jedyną opcją ręcznego testowania pozostaje curl i proste GET z konsoli z pomiarem czasu. To pomaga, ponieważ ten test dobrze odzwierciedla prędkość działania rozwiązania sieciowego, a jeśli są również testy przeglądarkowe, jest to jeszcze lepsze.

Później sami pojechaliśmy do Chin i upewniliśmy się, że Catchpoint można ufać, dokładnie odzwierciedla rzeczywiste wskaźniki prędkości działania.

Cloudflare China Network

Ponieważ dla głównej domeny semrush.com z powodzeniem korzystamy z Cloudflare, postanowiliśmy od razu wypróbować ich funkcję o nazwie China Network. Ta opcja aktywowana jest tylko dla stron Enterprise na specjalne żądanie i za dodatkową opłatą. Jest również dostępna tylko dla stron, które mają odpowiednią licencję ICP, w której jako dostawcę wskazano Cloudflare. Po jej włączeniu, dla strony dostępny staje się „chiński CDN” od Cloudflare — ruch z chińskich regionów ląduje w najbliższych PoP (Punktach Obecności) CF, a następnie dostarczany jest przez jego sieci lub sieci dostawców /partnerów do origin.

Schemat tego testowego stanowiska przedstawiony jest poniżej.

Dla nas to doskonała opcja. Okazuje się, że drugi domena również będzie za CF, co nie zwiększa liczby rozwiązań używanych w firmie i praktycznie nie komplikuje infrastruktury.

Uruchomiliśmy testy przeglądarkowe i oto co uzyskaliśmy:

Czerwone romby to niepowodzenia testów. Niepowodzenia na dole to błędy DNS (timeout rozwiązywania). Niepowodzenia na górze to timeouty.

Uptime: 86.6
Median: 18s
75 percentyl: 29.3s
95 percentyl: 60s

Mediana, po usunięciu załadunku reCaptcha (usługa Google, zablokowana w Chinach), spadła z 28 do 18 sek. Jednak nadal są to straszne wskaźniki, biorąc pod uwagę, że ten sam test dla semrush.com (z USA) dawał mniej niż 10 sekund dla 95% użytkowników (z USA) na tę samą stronę (statyka + dynamika).

Do każdego testu można wejść i sprawdzić Waterfall i inne bardziej szczegółowe parametry. Zaczęliśmy badać przyczyny błędów, a jeśli chodzi o timeouty, to wszystko jest mniej więcej jasne: internet w Chinach „raz działa, raz nie działa”, przez co prędkość połączenia i ładowania zasobów z zagranicy jest niestabilna i różna. Błędów DNS był dla nas dużym zaskoczeniem. Odkryliśmy, że PoP w Cloudflare rzeczywiście znajdują się w Chinach, adres strony jest rozwiązywany na jeden anycast IP, ale używane są amerykańskie serwery DNS, co powoduje, że zapytania DNS muszą przechodzić przez granicę, przez co czasami się nie udają.

Ustalając tę kwestię z CF, okazało się, że nie mają swoich serwerów DNS w Chinach, a na kiedy to się zmieni - na razie nie wiadomo.

Dlatego postanowiliśmy przetestować tylko DNS Cloudflare i zmieniliśmy mechanizm działania Cloudflare dla naszej strony na tryb „Tylko DNS”. Jest to tryb, w którym Cloudflare nie proxy'uje ruchu przez siebie, a to oznacza, że nie zapewnia ochrony DDoS, CDN ani innych funkcji, i działa w trybie zwykłego serwera DNS.

Niniejszy schemat jest schematycznie przedstawiony na następnym rysunku. Na rysunku uwzględniono nowo zdobyte wiedzę, że serwery DNS Cloudflare znajdują się za firewallem.

W Catchpoint uruchomiliśmy proste testy GET (nie przeglądarkowe), które pokazały wiele błędów. Ich przyczyną były te same błędy DNS.

Zaczęliśmy debugować te błędy za pomocą dig i odkryliśmy, że przy pierwszym zapytaniu adres jest określany poprawnie, a przy ponownym zapytaniu otrzymujemy za każdym razem SERVFAIL i not found. Skąd to nagle?

root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn ma adres 220.170.186.192
Host semrushchina.cn nie znaleziony: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn ma adres 220.170.186.192
Host semrushchina.cn nie znaleziony: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn ma adres 220.170.186.192
Host semrushchina.cn nie znaleziony: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn ma adres 220.170.186.192
Host semrushchina.cn nie znaleziony: 2(SERVFAIL)

Przy zapytaniu o serwery NS Cloudflare takich błędów nie ma:

root@iZwz97n2wgbp61qucbfrjsZ:~# for i in `seq 1 2`; do host semrushchina.cn ray.ns.cloudflare.com.; done
Korzystanie z serwera domeny:
Nazwa: ray.ns.cloudflare.com.
Adres: 173.245.59.138#53
Alias:

semrushchina.cn ma adres 220.170.186.192
semrushchina.cn ma adres 220.170.186.192
Korzystanie z serwera domeny:
Nazwa: ray.ns.cloudflare.com.
Adres: 173.245.59.138#53
Alias:

semrushchina.cn ma adres 220.170.186.192
semrushchina.cn ma adres 220.170.186.192

Więc problem leży po stronie „lokalnego” serwera DNS lub serwera dostawcy.
Dalsze dochodzenie wykazało, że SERVFAIL otrzymujemy podczas rozwiązania AAAA-rekordy.

Okazało się, że przy zapytaniu o Cloudflare AAAA-rekord, którego nie ma w domenie, Cloudflare odpowiedział A-zapisem, co jest błędem i niezgodnością z RFC. Z tego powodu lokalny resolverowi (x.x.x.x) to się nie podobało, i odpowiadał SERVFAIL. W poniższym logu to zachowanie jest wyraźnie widoczne:

root@iZwz97n2wgbp61qucbfrjsZ:~# dig -t AAAA semrushchina.cn @x.x.x.x

; <> DiG 9.10.3-P4-Ubuntu <> -t AAAA semrushchina.cn @x.x.x.x
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 55467
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;semrushchina.cn.               IN      AAAA

;; Query time: 334 msec
;; SERVER: x.x.x.x#53(x.x.x.x)
;; WHEN: Tue Aug 14 23:38:50 CST 2018
;; MSG SIZE  rcvd: 44

root@iZwz97n2wgbp61qucbfrjsZ:~# dig -t AAAA semrushchina.cn @dana.ns.cloudflare.com.

; <> DiG 9.10.3-P4-Ubuntu <> -t AAAA semrushchina.cn @dana.ns.cloudflare.com.
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63944
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;semrushchina.cn.               IN      AAAA

;; ANSWER SECTION:
semrushchina.cn.        300     IN      A       220.170.186.192

;; Query time: 185 msec
;; SERVER: 173.245.58.105#53(173.245.58.105)
;; WHEN: Tue Aug 14 23:43:03 CST 2018
;; MSG SIZE  rcvd: 60

Wysłaliśmy raport błędu do Cloudflare, a oni naprawili to po pewnym czasie. Okazało się to interesujące: obecnie w Chinach nadal nie ma wsparcia dla IPv6, więc Cloudflare nie mógł dostarczać tam swojego adresu IPv6 w odpowiedzi na zapytanie AAAA-rekordy. W rezultacie wszystko zakończyło się tak, że dla Chin Cloudflare zaczął odpowiadać NODATA na takie zapytania.

W ten sposób błędy DNS w testach Catchpoint znacznie się zmniejszyły, ale nie całkowicie. Timeouty również nie zniknęły:

I zaczęliśmy szukać innego rozwiązania.

W następnej części opowiem, jak testowaliśmy chmurę chińską Alibaba Cloud, jak za pomocą małej "magii" Nginx udało nam się szybko tworzyć PoC (Proof of Concept) rozwiązań, które opracowaliśmy przy Multi-Cloud rozwiązaniach, jedno z nich ostatecznie bardzo pomogło przyspieszyć działanie serwisu z Chin.

Bądźcie na bieżąco!

Następne części

Część 2

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster