Përshëndetje!
С вами снова Никита — системный инженер из компании SЕMrush. И этой статьей я продолжаю историю про то, как мы придумывали решение обхода Китайского Фаервола для нашего сервиса semrush.com.
Në я рассказал:
- какие появляются проблемы после того, как принимается решение «Нам нужно сделать так, чтобы наш сервис работал в Китае»
- какие проблемы есть у китайского интернета
- зачем нужна ICP-лицензия
- как и почему мы решили тестировать наши тестовые стенды с помощью Catchpoint
- какой результат дал наш первый вариант решения, базирующийся на Cloudflare China Network
- как мы нашли баг в DNS Cloudflare
Эта часть — самая итересная, на мой взгляд, потому что сосредоточена на конкретных технических реализациях стейджингов. И начнем мы, а точнее продолжим, с Alibaba Cloud.
Alibaba Cloud
Alibaba Cloud — довольно большой облачный провайдер, в котором есть все сервисы, позволяющие ему честно величать себя cloud provider. Хорошо, что у них есть возможность зарегаться иностранным пользователям, и что большая часть сайта переведена на английский (для Китая это роскошь). В данном облаке можно работать со множеством регионов мира, материкового Китая, а также Океанической Азии (Гонконг, Тайвань, и т.д.).
IPSEC
Начали с географии. Так как тестовый сайт у нас находился в Google Cloud, нам необходимо было “связать” Alibaba Cloud c GCP, поэтому открыли список локаций, в которых присутствует Google. В тот момент у них еще не было своего датацентра в Гонконге.
Ближайшим регионом оказался asia-east1 (Тайвань). У Ali наиболее близким регионом континентального Китая к Тайваню оказался cn-shenzhen (Шеньчжень).
Me terraform описали и подняли всю инфраструктуру в GCP и Ali. Туннель 100 мбит/с между облаками поднялся практически моментально. На стороне Шеньчженя и Тайваня подняли проксирующие виртуалки. В Шеньчжене пользовательский трафик терминируется, проксируется через туннель в Тайвань, а оттуда уже идет напрямую на внешний IP нашего сервиса в us-east (Восточное побережье США). Пинг между виртуалками по туннелю 24ms, что не так плохо.
Одновременно мы разместили тестовую зону в Alibaba Cloud DNS. После делегирования зоны на NS Ali, время резолвинга снизилось с 470 ms до 50 ms. До этого зона тоже была на Cloudlfare.
Параллельно с туннелем до asia-east1 подняли еще один туннель из Шеньчженя прямо в us-east4. Там создали еще проксирующих виртуалок и начали мерить оба решения, маршрутизируя тестовый трафик с помощью Cookies или DNS. Схематично тестовый стенд описан на следующем рисунке:
Latency для туннелей получилась следующей:
Ali cn-shenzhen <—> GCP asia-east1 — 24ms
Ali cn-shenzhen GCP us-east4 — 200ms
Браузерные тесты Catchpoint рапортовали об отличном улучшении показателей.
Сравните результаты тестов для двух решений:
Zgjidhja
Disponueshmëria
Median
75 Percentile
95 Percentile
Cloudflare
86.6
18s
30s
60s
IPsec
99.79
18s
21s
30s
Это данные решения, использующего IPSEC-туннель через asia-east1. Через us-east4 результаты были хуже, да и ошибок было больше, поэтому результаты приводить не буду.
По результатам данного теста двух туннелей, один из которых терминируется в ближайшем регионе к Китаю, а другой в финальном пункте назначения, стало понятно, что важно как можно быстрее “выныривать” из-под китайского фаервола, а дальше использовать быстрые сети (CDN-провайдеров, облачных провайдеров и т.д.). Не надо пытаться одним махом пройти фаервол и попасть в пункт назначения. Это не самый быстрый путь.
В целом, результаты неплохи, однако, у semrush.com медиана 8.8s, а 75 Percentile 9.4s (на том же тесте).
И прежде чем двигаться дальше, я хотел бы сделать небольшое лирическое отступление.
Një shpërndarje lirikë
После того, как пользователь заходит на сайт www.semrushchina.cn, который резолвится через “быстрые” китайские DNS-серверы, HTTP-запрос идет через наше быстрое решение. Ответ возвращается по тому же пути, но во всех JS-скриптах, HTML-страницах и прочих элементах вэб-страницы указан домен semrush.com для дополнительных ресурсов, которые должны быть загружены при отрисовке страницы. То есть клиент резолвит “главную” А-запись www.semrushchina.cn и идет в быстрый туннель, быстро получает response — HTML-страницу, в которой указано:
- скачай такой-то js с sso.semrush.com,
- CSS файлы забери с cdn.semrush.com,
- и еще возьми картинок с dab.semrush.com
- etj.
Браузер начинает идти во “внешний” интернет за этими ресурсами, проходя каждый раз через пожирающий время ответа фаервол.
Но на в предыдущем тесте представлены результаты, когда на странице нет ресурсов semrush.com, только semrushchina.cn, а *.semrushchina.cn резволвится в адрес виртуалки в Шеньчжене, чтобы попасть потом в туннель.
Только так, по максимуму закидывая весь возможный трафик через свое решение быстрого прохода китайского фаервола, можно получить приемлемые скорости и показатели доступности сайта, а также честные результаты тестов решений.
E realizuam këtë pa një rresht të vetëm kodi në anën e produkteve të ekipit.
Subfilter
Zgjidhja lindi pothuajse menjëherë pas shfaqjes së këtij problemi. Na duhej PoC (Proof of Concept), që zgjidhjet tona për kalimin e firewall-it funksionojnë vërtet mirë. Për këtë, ne duhet të mbështjellim gjithë trafikun e faqes në këtë zgjidhje. Dhe aplikumë në nginx.
Subfilter — ky është një moduli mjaft i thjeshtë në nginx, i cili lejon të ndryshohet një linjë në trupin e përgjigjes me një linjë tjetër. Kështu që ne e ndryshuam gjithçka në semrush.com në semrushchina.cn të gjitha përgjigjet.
Dhe… kjo nuk funksionoi, sepse nga backend-et merrnim përmbajtje të kompresuar, kështu që subfilter nuk mund të gjente linjën e nevojshme. Duhej të shtonim një server lokal tjetër në nginx, i cili decomprimonte përgjigjen dhe ia dërgonte serverit tjetër lokal, i cili merrej me zëvendësimin e linjës, kompresimin dhe dërgimin e saj tek serveri tjetër në zinxhir.
Në fund, aty ku klienti do të merrte .semrush.com, ai merrte .semrushchina.cn dhe ndjekte kujdesshëm zgjidhjen tonë.
Megjithatë, nuk është mjaftueshëm thjesht të ndryshosh domenin në një drejtim, pasi backend-et gjithashtu presin semrush.com në kërkesat e mëvonshme nga klienti. Përkatësisht, në të njëjtin server, ku bëhet zëvendësimi në një drejtim, me ndihmën e një shprehje të thjeshtë të rregullt ne nxjerrim subdomenin nga kërkesa, dhe më pas bëjmë proxy_pass me ndryshoren $host, e cila është vendosur në $subdomain.semrush.com.Mund të duket e komplikuar, por funksionon. Dhe funksionon mirë. Për domenet e veçanta që kërkojnë logjikë tjetër, thjesht krijohen blloqe të veçanta server dhe bëhet një konfigurim i veçantë. Më poshtë janë paraqitur konfigurime të shkurtra në nginx për qartësi dhe demonstrim të kësaj skeme.
Konfigurimi në vijim përpunon të gjitha kërkesat nga Kina në .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;
}
}Ky konfigurim prokson në localhost në portin 83, dhe aty pret konfigurimin tjetër:
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;
}
}Përsëris, këto janë konfigurime të prera.
Në këtë mënyrë. Mund të duket e komplikuar, por në fjalë. Në të vërtetë, gjithçka është më e thjeshtë se një qepë 🙂
Këtu përfundon një shkëputje poetike.
Për një kohë të caktuar ishim të lumtur, sepse miti i tunelëve IPSEC që po bien nuk u konfirmua. Por më pas tunelët filluan të bien. Disa herë në ditë për disa minuta. Pak, por kjo nuk na kënaqte. Pasi të dy tunelët u terminuan në anën e Ali në një router, menduam se ndoshta kjo është një problem rajonal dhe duhet të ngremë një rajon të dytë.
E ngritëm. Tunelët filluan të bien në kohë të ndryshme, por failover në nivelin upstream në nginx funksionoi shumë mirë. Por më pas tunelët filluan të bien në mënyrë të ngjashme 🙂 Dhe përsëri filluan 502 dhe 504. Uptime-u filloi të përkeqësohej, për këtë arsye filluam të punojmë mbi opsionin me Alibaba CEN (Cloud Enterprise Network).
CEN
CEN — kjo është lidhja e dy VPC-ve nga rajone të ndryshme brenda Alibaba Cloud, pra mund të lidhen rrjetet private nga çdo rajon brenda cloud-it mes tyre. Dhe ajo që është më e rëndësishmja: ky kanal ka një SLA. Ai është shumë stabil si në shpejtësi, ashtu edhe në uptime. Por asnjëherë nuk është aq e thjeshtë:
- është shumë e vështirë të merret, nëse nuk je qytetar ose subjekt ligjor kinez,
- duhet të paguash për çdo megabit kapaciteti të kanalit.
Duke marrë mundësinë për të lidhur Mainland China dhe Overseas, krijuam CEN midis dy rajoneve Ali: cn-shenzhen dhe us-east-1 (pika më e afërt me us-east4). Në Ali us-east-1 ngritëm një tjetër virtual machine, për të pasur një hop.
Doli kështu:
Rezultatet e testeve të shfletuesit më poshtë:
Zgjidhja
Disponueshmëria
Median
75 Percentile
95 Percentile
Cloudflare
86.6
18s
30s
60s
IPsec
99.79
18s
21s
30s
CEN
99.75
16s
21s
27s
Të dhënat janë pak më të mira se ato të IPSEC. Por përmes IPSEC potencialisht mund të shkarkohet me një shpejtësi prej 100 mbit/s, ndërsa përmes CEN vetëm me një shpejtësi prej 5 mbit/s dhe më shtrenjtë.
Po duket një hibrid, apo jo? Të lidhësh shpejtësinë e IPSEC dhe stabilitetin e CEN.
Kështu vepruam, duke lënë trafikun përmes IPSEC dhe CEN në rast të rënies së tunelit IPSEC. Uptime-u u bë shumë më i lartë, por shpejtësia e ngarkesës së faqes akoma kishte nevojë për përmirësim. Atëherë krijova të gjitha skemat që kishim përdorur dhe testuar, dhe vendosa të përpiqem të shtoj dhe pak GCP, konkretisht GLB.
GLB
GLB — kjo është (ose Google Cloud Load Balancer). Ai ka një avantazh të rëndësishëm për ne: në kontekstin e CDN ka anycast IP, e cila lejon të drejtohet trafiku në qendrën më të afërt të të dhënave me klientin, për shkak të së cilës trafiku arrin më shpejt në rrjetin e shpejtë të Google dhe kalon më pak në 'internetin normal'.
Pa dyshuarit, ne ngritëm HTTP/HTTPS LB në GCP dhe vendosëm virtualet tona me subfilter si back-end.
Ishte disa skema:
- Përdorni Cloudflare China Network, por këtë herë të specifikohet globali IP GLB.
- Për të terminuar klientët në cn-shenzhen, dhe prej atje të proksojmë trafik direkt në GLB.
- Të shkojmë direkt nga Kina në GLB.
- Për të terminuar klientët në cn-shenzhen, dhe prej atje të proksojmë në asia-east1 nëpërmjet IPSEC (në us-east4 nëpërmjet CEN), dhe prej aty të shkojmë në GLB (qetë, poshtë do të ketë një imazh dhe shpjegim)
Kemi provuar të gjitha këto variante dhe disa hibridë:
- Cloudflare + GLB
Kjo skemë nuk na kënaqte për uptime dhe gabimet DNS. Por testi u bë para zgjidhjes së gabimit nga ana e CF, ndoshta tani ka përmirësuar (megjithatë, kjo nuk përjashton HTTP-timeoutet).
- Ali + GLB
Kjo skemë gjithashtu nuk na kënaqte për uptime, pasi GLB shpesh shkonte jashtë nga upstream për shkak të pamundësisë për të u lidhur në kohë të pranueshme ose timeout, pasi për serverin brenda Kinës adresa GLB mbetet jashtë, që e bën atë prapa murit të zjarrit kinez. Nuk ndodhi ndonjë magji.
- GLB only
Një variant i ngjashëm me të mëparshmin, që vetëm nuk përdorë serverë brenda Kinës: trafiku shkonte direkt në GLB (kemi ndërruar rekordet DNS). Prandaj, rezultatet nuk ishin të kënaqshme, pasi për klientët e zakonshëm kinezë që përdorin shërbimet e ofruesve të zakonshëm të internetit, situata për kalimin e murit të zjarrit është shumë më e keqe se sa për Ali Cloud.
- Shenzhen -> (CEN/IPSEC) -> Proxy -> GLB
Këtu vendosëm të përdorim më të mirën nga të gjitha zgjidhjet:
- stabiliteti dhe SLA i garantuar nga CEN
- shpejtësinë e lartë nga IPSEC
- rrjetin "shpejt" të Google dhe anycast-in e tij.
Skema duket si më poshtë: trafik nga përdoruesit terminon në një virtual në ch-shenzhen. Atje janë konfiguruar upstream-et nginx, disa prej të cilëve i referohen IP-ve private të serverëve që ndodhen në anën tjetër të tunelit IPSEC, dhe disa upstream-e janë për adresat private të serverëve në anën tjetër të CEN. IPSEC u konfigurua deri në rajonin asia-east1 në GCP (ishte rajoni më afër Kinës në momentin e krijimit të zgjidhjes. Tani GCP ka gjithashtu prezencë në Hong Kong). CEN — deri në rajonin us-east1 në Ali Cloud.
Më pas, trafiku nga të dyja anët u drejtuar në anycast IP GLB, pra në pikën më të afërt të prezencës së Google, dhe shkonte nëpërmjet rrjeteve të tij në rajonin us-east4 në GCP, ku ishin virtualet e zëvendësimit (me subfilter në nginx).
Kjo zgjidhje hibride, siç e prisnim, na lejojë të përfitojmë nga përfitimet e çdo teknologjie. Në përgjithësi, trafiku kalon përmes IPSEC të shpejtë, por nëse fillojnë problemet, ne shpejt dhe për disa minuta ndalojmë këto servera nga upstream-et dhe dërgojmë trafikun vetëm përmes CEN, derisa tuneli të stabilizohet.
Duke implementuar zgjidhjen e katërt nga lista më lart, arritëm atë që donim, dhe që biznesi ynë kërkonte në atë moment.
Rezultatet e testeve të shfletuesit për zgjidhjen e re në krahasim me ato të mëparshme:
Zgjidhja
Disponueshmëria
Median
75 Percentile
95 Percentile
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
Në zgjidhjen që implementuam, gjithçka është mirë, vetëm se nuk ka CDN që mund të akseleronte trafik në nivel rajonesh dhe madje qytetesh. Idealisht, kjo duhet të përshpejtonte funksionimin e faqes për përdoruesit fundorë përmes përdorimit të kanaleve të shpejtë të ofruesit të CDN. Dhe ne gjithmonë kemi menduar për këtë. Dhe tani, ka ardhur koha për itëracionin e ardhshëm të projektit: kërkimi dhe testimi i ofruesve të CDN në Kinë.
Dhe për këtë do t'ju tregoj në pjesën e ardhshme, përfundimtare 🙂
Burimi: habr.com
