Хабрахабр

Как мы пробивали Великий Китайский Фаервол (ч.1)

Всем привет!

Сегодня я расскажу вам о том, как перед нами встала задача обеспечить стабильность работы нашего сервиса semrush.com в Китае, и с какими проблемами мы столкнулись в ходе ее выполнения (учитывая местонахождение нашего дата-центра на восточном побережье США). На связи Никита — системный инженер из компании SЕMrush.

Расскажу, как все это было у нас: от полностью неработающего сервиса из Китая, до показателей работы сервиса на уровне его американской версии для американцев. Это будет большая история, разбитая на несколько статей. Итак, поехали. Обещаю, будет интересно и полезно.

Проблемы китайского интернета

Ууу, звучит круто, да? Даже самый далекий человек от специфики сетевого администрирования хотя бы раз, да слышал о Великом Китайском Фаерволе. В интернете можно найти много статей, посвященных этому, но с технической точки зрения устройство этого фаервола нигде не описано. Но что это такое, как оно работает на самом деле — вопрос довольно сложный. Признаюсь сразу, по итогам года работы я не смогу сказать точно, как он работает, но смогу рассказать о своих замечаниях и практических выводах. Что, впрочем, неудивительно. И начнем мы со слухов об этом фаерволе.

Давайте соберем основные и наиболее интересные из них в один список: Есть много слухов об этом самом фаерволе.

  • Google, Facebook, Twitter и прочие подобные сервисы заблокированы и не работают в Китае.
  • Любой трафик, идущий ЗА пределы Китая и В Китай, парсится и ограничивается с помощью машинного обучения (в случае подозрительного трафика), что сильно замедляет его (трафик), проходящий через границу.
  • Китайские спецслужбы взломают любой зашифрованный трафик, идущий через их фаервол.
  • VPN-туннели, IPSEC-туннели нестабильны, падают и постоянно блокируются.
  • Чем проще шифрование, чем проще pass phrase, используемая для аутентификации/шифра трафика, тем быстрее он проходит китайский фаервол.

Вот, что нам удалось выяснить об этих слухах:

  • Google, Facebook, Twitter и прочие подобные сервисы действительно заблокированы (ваш КО), но многие технические домены Google, например, не забанены и работают (тот же gstatic.com). Отсюда следует вывод: не стоит безрассудно выпиливать все подряд гугловые и прочие, кажущиеся заблокированными, ресурсы.
  • Любой трафик, проходящий границу, действительно прибавляет к своему времени нешуточный delay. Посмотрите на два результата. Один сайт, одна страница, простой GET curl’ом. Первый замер из самого Китая (прекрасный город Шеньчжень). Второй замер снаружи из Гонконга (имеет суверенитет, и между ним и миром нет фаервола). Расстояние между городами по прямой примерно 30-40 км.

nikita@china-shenzhen:~# curl -o /dev/null -w@curl_time "https://www.semrush.com/info/ebay.com" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed
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 Bytes
speed_download: 71824.000B/s nikita@china-hongkong:~# curl -o /dev/null -w@curl_time "https://www.semrush.com/info/ebay.com" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed
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 Bytes
speed_download: 2616740.000B/s

И в целом, вы видите результат: фаервол добавляет 4 лишних секунды, что чудовищно долго. Обратите внимание на time_connect.

  • VPN и IPSEC-туннели действительно часто падают. Об этом я расскажу чуть позже и подробнее. VPN-серверы, которые используются пользователями, со временем блокируются (обычно в течение суток после начала использования).
  • Есть мнение, полученное от людей, проживающих в Китае, что чем проще шифрование трафика, тем быстрее он проходит через границу, потому что легко понять, что в нем нет ничего противозаконного. И точно также “чистый” трафик получает больше полосы пропускания и скорости прохождения, а “грязный” трафик, в котором ничего не разобрать, получает наоборот более медленный проход. Для примера я приведу curl до ifconfig.co по протоколу HTTPS и 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

При том, делая такой тест несколько раз, можно заметить, что GET на HTTP завершается в целом за одинаковое время каждый раз, в то время как по HTTPS сайт отвечает иногда за 3, 5, 10 и даже 17 секунд. Разница в 5 секунд на общее время загрузки 13 байт. Иногда случаются ошибки SSL:

Unknown SSL protocol error in connection to ifconfig.co:443.

Итак, что мы имеем:

  • Проблемы, создаваемые китайским фаерволом, описанные выше.
  • Пинги до внешних ресурсов и внутри туннелей периодически пропадают.
  • Latency между двумя точками постоянно меняется, а зачастую она просто непредсказуема. Соединяя разные города/регионы, ты ожидаешь, что исходя из географического расположения регионов, задержка будет меньше, а получаешь ровно обратную ситуацию.
  • Интернет и каналы связи работают то быстро, то медленно. Тут есть небольшая зависимость от времени суток и дня недели, но не всегда.
  • DNS-запросы во внешний мир из Китая иногда превышают допустимый таймаут.

Картина вырисовывается просто “отличная”.

Перед нами, как командой системных администраторов, была поставлена задача малыми усилиями быстро начать работать в Китае. Датацентр, как я уже сказал, у нас на востоке США, а весь SEMrush состоит из десятков взаимосвязанных продуктов, бэкэндов, фронтэндов, баз данных, и все это в ДЦ и облаках.

Нам предстояло ответить на важный вопрос: можно ли обойтись малой кровью и решить все проблемы, связанные с китайским интернетом и фаерволом, на уровне сети/облаков/серверов?

Мы начали с получения ICP-лицензии.

ICP-лицензия

Для того, чтобы иметь возможность размещать свой сервис в пределах Китая (Mainland China) и проводить тесты, нужно сначала получить ICP-лицензию на домен.

Интересно, что в ICP-лицензию вписывается конкретный провайдер, будь то Cloudflare или Alibaba Cloud. Если пользовательский трафик вашего сайта терминируется в пределах Mainland China, и если у вашего домена нет лицензии ICP, ваш трафик будет блокироваться на стороне провайдера/хостинга. Необходимо будет добавлять в эту лицензию еще один хостинг. Поэтому, если вы получали ICP-лицензию для Cloudflare и размещали свой сайт у них, в последствии “бесшовно” переехать на Alibaba Cloud у вас не получится.

Получив ICP-лицензию на домен, мы смогли придумывать и реализовывать конкретные технические идеи и решения.

Тестирование решений

Но перед тем, как непосредственно создавать варианты стейджингов, крутить ручки, оптимизировать работу сайта и его скорость, нужно выбрать инструмент для его тестирования, чтобы видеть, какие наши действия улучшают или наоборот ухудшают работу сайта.

Наш инструмент для тестирования должен был соответствовать двум главным требованиям:

  • он должен иметь возможность запуска тестов из Китая,
  • он должен иметь браузерные тесты.

У них отличное покрытие точками тестирования по всему миру. Так мы нашли Catchpoint! В каждой по несколько разных провайдеров + возможность делать Backbone-тесты (что-то типа виртуалки в датацентре) и Lastmile-тесты (максимально приближенные к пользовательским условиям, aka рабочая станция). В Китае через этот инструмент можно запускать тесты тоже из 100500 провинций. Последний тип тестов стоит дороже.

Признаться, мы были приятно удивлены его функционалом. Заключив годовой контракт (меньше нельзя), мы приступили к изучению инструмента. Можно запускать:

  • DNS-тесты,
  • Web-тесты (браузерные, простой GET/POST, эмуляция мобильного клиента и т.д.),
  • Транзакционные проверки (например, логин),
  • API-тесты,
  • Ping, traceroute, NTP и т.д.

И что самое главное, каждый тест можно довольно хорошо кастомизировать, добавив пачку заголовков и других параметров. Всего не перечислишь. Если говорить о самом интересном для нас (браузерные тесты), то результат включает в себя: На выходе получается огромное количество информации, полностью описывающей твой тест.

  • Connect, Wait, Load, SSL, DNS time,
  • TTFB, TTLB, Document complete, Render time, DOM load,
  • Response (что-то близкое к Time To First Byte), Webpage Response (что-то близкое к Time To Last Byte),
  • Любые percentile, Average, Median time
  • И т.п.

Мы, в основном, смотрели на Response, Webpage Response, Median, 75 и 95 Percentiles. Соответственно, все эти метрики отлично помогают видеть изменения и понимать, стало ли лучше.

Отражает ли этот инструмент реальную скорость загрузки сайта в Китае из разных городов или же это просто какой-то тест в вакууме, не имеющий ничего общего с real user experience?
Это большая проблема, потому что находясь в России практически невозможно достоверно узнать, как работает сайт из Китая. Важный вопрос, который витал в воздухе с самого начала: а можно ли верить Catchpoint? Это помогает, потому что данный тест хорошо отражает скорость работы сетевого решения, а если есть еще и браузерные тесты, то совсем хорошо. Делая socks-proxy через виртуалку, на выходе получаешь загрузку сайта в течение пары минут, что для тестов просто неприемлимо, поэтому единственным вариантом ручного тестирования остается curl и простые GET из консоли с замером времени.

Позже мы сами съездили в Китай и убедились, что Catchpoint верить можно, он довольно точно отражает реальные показатели скорости работы.

Cloudflare China Network

Данная опция включается только для Enterprise-сайтов по отдельному запросу и за отдельную плату. Так как для основного домена semrush.com мы успешно используем Cloudflare, решили сразу попробовать их фичу под названием China Network. После ее включения, для сайта становится доступным “китайский CDN” от Cloudflare — трафик из китайских регионов приземляется в ближайшие PoP (Points of Presence) CF, а дальше уже по его сетям или сетям провайдеров/партнеров доставляется до origin. Также она доступна только для сайтов, имеющих соответствующую ICP-лицензию, в которой в качестве провайдера указан Cloudflare.

Схема данного тестового стенда представлена ниже.

Получается, что второй домен будет тоже за CF, что не прибавляет количество решений, используемых в компании, а также практически не усложняет инфраструктуру. Для нас это прекрасный вариант.

Мы запустили браузерные тесты, и вот что получилось:

Фейлы снизу — DNS ошибки (resolve timeout). Красные ромбики — это фейлы тестов. Фейлы сверху — таймауты.

6
Median: 18s
75 Percentile: 29. Uptime: 86. 3s
95 Percentile: 60s

Но все равно это ужасные показатели, если учесть, что такой же тест для semrush.com (из США) давал менее 10 секунд для 95% пользователей (из США) на ту же самую страницу (статика + динамика). Медиана, после того, как убрали загрузку reCaptcha (сервис гугла, заблокированный в Китае), снизилась с 28 до 18 сек.

Мы начали исследовать причины ошибок, и если для таймаутов все более менее понятно: интернет в Китае “то съезжается, то разъезжается”, из-за этого скорость коннекта и загрузки ресурсов из-за границы нестабильна и неодинакова, то DNS-ошибки нас сильно удивили. В каждый тест можно зайти и посмотреть Waterfall и другие более подробные параметры. Мы обнаружили, что PoP у Cloudflare действительно находятся в Китае, адрес сайта резолвится в один anycast IP, но DNS-серверы используются американские, из-за чего DNS-запросы вынуждены проходить через границу, поэтому иногда они фейлятся.

Уточнив этот вопрос у CF, выяснилось, что своих DNS-серверов в Китае у них нет, а когда будет — пока неизвестно.

Это такой режим, когда Cloudflare не проксирует трафик через себя, а значит, не предоставляет DDoS-защиты, CDN и прочие фичи, и работает в режиме обычного DNS-сервера. Поэтому мы решили потестировать только DNS Cloudflare и поменяли механизм работы Cloudflare для нашего сайта на режим “Только DNS”.

На рисунке учтены появившиеся знания о том, что DNS-сервера Cloudflare за фаерволом. Данный стенд схематично представлен на следующем рисунке.

Причиной их были все те же DNS ошибки. В Catchpoint мы запустили простые GET-тесты (не браузерные), которые показали очень много фейлов.

Это с чего вдруг? Начали дебажить эти ошибки с помощью dig и обнаружили, что при первом запросе адрес определяется правильно, а при повторном запросе мы получаем каждый раз SERVFAIL и not found.

root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn has address 220.170.186.192
Host semrushchina.cn not found: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn has address 220.170.186.192
Host semrushchina.cn not found: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn has address 220.170.186.192
Host semrushchina.cn not found: 2(SERVFAIL)
root@iZwz97n2wgbp61qucbfrjsZ:~# host semrushchina.cn
semrushchina.cn has address 220.170.186.192
Host semrushchina.cn not found: 2(SERVFAIL)

При запросе NS-серверов Cloudflare напрямую таких ошибок нет:

root@iZwz97n2wgbp61qucbfrjsZ:~# for i in `seq 1 2`; do host semrushchina.cn ray.ns.cloudflare.com.; done
Using domain server:
Name: ray.ns.cloudflare.com.
Address: 173.245.59.138#53
Aliases: semrushchina.cn has address 220.170.186.192
semrushchina.cn has address 220.170.186.192
Using domain server:
Name: ray.ns.cloudflare.com.
Address: 173.245.59.138#53
Aliases: semrushchina.cn has address 220.170.186.192
semrushchina.cn has address 220.170.186.192

Значит, проблема на стороне “локального” DNS-сервера или сервера провайдера.
Дальнейшее расследование показало, что SERVFAIL мы получаем на резолве AAAA-записи.

Из-за чего локальному резолверу (x.x.x.x) это не нравилось, и он отвечал SERVFAIL. Оказалось, что при запросе у Cloudflare АААА-записи, которой в домене нет, Cloudflare отвечал А-записью, что является ошибкой и несоответствием RFC. В логе ниже это поведение отчетливо видно:

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

Оказалось интересно: на настоящий момент в Китае до сих пор нет поддержки IPv6, поэтому Cloudflare не мог выдавать там свой IPv6 адрес в ответе на запрос АААА-записи. Мы отправили bug-репорт Cloudflare, и они это исправили через какое-то время. В итоге все решилось так, что для Китая Cloudflare стал отвечать NODATA на такие запросы.

Таймауты тоже никуда не делись: Так, ошибки DNS в тестах Catchpoint резко уменьшились, но не до конца.

И мы начали искать другое решение.

В следующей части я расскажу, как мы тестировали китайское облако Alibaba Cloud, как с помощью небольшой "магии" Nginx мы смогли быстро создавать PoC (Proof of Concept) решений, как мы создавали Multi-Cloud решения, одно из которых в итоге очень сильно помогло ускорить работу сервиса из Китая.

Stay tuned!

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»