DNS и anycast: решения и проблемы

Устойчивость системы DNS, ее надежность, а также достоверность получаемой из DNS инфор­мации чрезвычайно важны для функционирования современного Интернета. Одним из таких механизмов повышения надежности является построение DNS-anycast-облаков. Тема реализации сервиса DNS на основе технологии anycast обширна. Реализация DNS-облаков требует глубокого анализа DNS-статистики, продуманных инженерных решений и высокой квалификации обслу­живающего персонала. Тем не менее, на данный момент anycast – это наиболее стабильное и надежное решение для построения высоконагруженных DNS-сервисов, к которым предъявляются высокие требования по устойчивости и надежности.

Система доменных имен (Domain Name System — DNS) имеет критически важное значение для современного Интернета. Мало кто помнит IP-адреса сервисов поиска «Яндекса» (5.255.255.70, 77.88.55.80, 77.88.55.70, 5.255.255.80), например. Однако все прекрасно помнят доменное имя yandex.ru.

DNS, придуманная для облегчения именования адресов электронной почты, в настоящее время стала одним из важнейших инфраструктурных сервисов. Обращение к системе DNS всегда предваряет любое другое обращение к информационным ресурсам Сети, будь то сайты World Wide Web, социальные сети, потоковые сервисы или электронная почта.

Устойчивость системы DNS, ее надежность, а также досто­верность получаемой из DNS информации чрезвычайно важны для функционирования современного Интернета. Одним из таких механизмов повышения надежности является построение DNS-anycast-облаков.

От серверов к облакам

Давайте посмотрим на стандартный вывод утилиты dig для домена .ru:

«Интернет изнутри». DNS и anycast: решения и проблемы

 

Из него видно, что за поддержку домена .ru отвечают пять серверов доменных имен. Каждому из них назначены IP-адреса форматов IPv4 и IPv6:

«Интернет изнутри». DNS и anycast: решения и проблемы

 

А теперь проведем следующий эксперимент: запросим список серверов доменных имен домена .ru из трех уда­ленных мест, скажем, из Франкфурта (Amazon), Орегона (Amazon, Западное побережье США) и Москвы (Beeline). Обращаться будем к одному и тому же авторитетному серверу доменных имен f.dns.ripn.net. А также посмотрим на расстояния между этими точками в терминах времени отклика от DNS-серверов, установленных в этих точках [1]. Измерения времени отклика приведены в таблице 1.

«Интернет изнутри». DNS и anycast: решения и проблемы

 

Если принять простое топографическое представление расстояний между точками измерения, то f.dns.ripn.net должен располагаться где-то на Карибских островах.

Однако если задать в команде dig опцию +nsid [2], то можно увидеть нечто большее, чем время отклика, а именно – идентификатор авторитетного сервера (таблица 2).

 

«Интернет изнутри». DNS и anycast: решения и проблемы

 

Таким образом, мы увидели два любопытных момента:

  • под одним именем и одним адресом «скрываются» два разных сервера;
  • география отвечающих серверов не согласуется с просты­ми географическими представлениями, а определяется топологией сети и политиками маршрутизации провайде­ров (Internet Service Provider — ISP).

 

Назначение одного IP-адреса (а в нашем случае и одного имени) многим хостам в данном случае определяется технологией anycast, которая применяется при реализации поддержки домена .ru.

Домен .ru поддерживают не пять серверов, а пять групп серверов. Каждой группе соответствует свое имя (в дальнейшем мы будем их называть по первым буквам имени: a, b, d, e, f). Все серверы в группе имеют одинаковые IP-адреса.

Запросы от резолверов при обращении за информацией о домене .ru в общем случае направляются на ближайшую (в смысле времени отклика) группу серверов, а в ней, соответственно, на ближайший (в смысле длины маршрута) сервер из группы. Группу DNS-серверов мы будем называть anycast-облаком.

Вообще говоря, когда рассуждают об anycast в DNS, то речь идет не столько о DNS, сколько о маршрутизации и требованиях к сервису, для которого устанавливаются anycast-маршруты.

Быть ближе к народу

Если коротко, то при технологии anycast нескольким географиче­ски распределенным серверам назначается один и тот же IP-адрес (IPv4 или IPv6), называемый anycast-адресом. Когда какой-либо хост отправляет пакеты (датаграммы) на anycast-адрес, система маршрутизации Интернета выбирает, а Сеть отвечает за кратчайший наилучший маршрут к этому адресу. Таким образом обмен трафиком будет происходить с наиболее близким (в терминах протокола маршрутизации BGP) к клиенту сервером доставки пакетов как минимум одному и, даже наиболее предпочтительно, только одному из серверов, которые могут получить эти пакеты на anycast-адрес [3].

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

Если применять эту идею к DNS, то она состоит в том, чтобы разработать и развернуть сеть DNS-серверов в районах, которые не покрывались ранее сервисом DNS, и таким образом сократить время отклика на запросы резолверов в этих районах [4].

Сервис, для которого предполагается применять anycast, должен отвечать определенным требованиям:

  • anycast может быть реализован только на стабильном списке адресов;
  • маршруты к этому списку могут быть анонсированы из различных физически (топологически) разнесенных мест;
  • для реализации anycast наилучшим образом подходят так называемые stateless протоколы.

 

Для сервиса DNS все перечисленные требования к реали­зации сервиса хорошо подходят.

В своей массе запросы к DNS используют транспорт UDP, т.е. мы имеем дело со stateless протоколом. Кроме того, при этом большинство запросов вмещаются в один DNS-пакет, что, собственно, не требует поддержания канала между клиентом и сервером в течение длительного времени.

Список IP-адресов авторитетных серверов стабилен и задан в файле описания зоны. Изменения списка возмож­ны, но они происходят не чаще, чем происходит изменение адресных записей в соответствующих файлах описания зон доменов.

Здесь следует заметить, что когда речь заходит об anycast для DNS, то, как правило, имеют в виду либо группы серверов, которые поддерживают корень DNS, либо группы серверов, поддерживающих национальные домены (country code top level domains – ссTLD), либо домены верхнего уровня общего назначения (General Top Level Domains – gTLD). Политика маршрутизации автоном­ных систем для этих серверов обычно довольно стабильна. Технологии типа fastflux для серверов, поддерживающих эти домены, также не используется.

При реализации маршрутов к узлам anycat-облака могут быть использованы два разных способа объявления маршрутов: анонсирование «глобальных» узлов и анонси­рование «локальных» узлов.

«Глобальные» узлы анонсируются таким образом, что они могут обслуживать резолверы, размещенные в любой точке Интернета. Как правило, «глобальные» узлы подключены к нескольким интернет-сервис-провайдерам. Обычно глобальный узел устанавливается в сетях глобаль­ных или крупных региональных провайдеров.

«Локальные» узлы анонсируются только определенной группе провайдеров и не должны быть доступны «всему Интернету». Для анонсирования таких узлов могут быть применены технологии ограничения «видимости» маршрутов к таким узлам [5]. «локальные» узлы обычно обслуживают локальное сообщество пользователей и размещаются в точках обмена трафиком (IX).

Со временем список задач DNS, которые можно решать в рамках технологии anycat, постепенно расширился до:

  1. Распределение трафика среди множества серверов.
  2. Противодействие DDoS-атакам на DNS-инфраструк­туру за счет распределения трафика атаки.
  3. Локализации DDoS-атак вокруг «локальных» DNS-узлов.
  4. Сокращение времени отклика.
  5. Сокращение списка записей NS (Name Service) в файле описания зоны при фактическом увеличении количества серверов, что положительно сказывает­ся на размер DNS-пакета.
  6. Обслуживание максимального количества запросов резолверов при соблюдении соглашений об уровне предоставления сервиса (Service Level Agreement – SLA).

 

Это далеко не весь перечень задач, для решения которых можно использовать anycast.


Зри в корень: противодействие DDoS-атакам

Устойчивость системы DNS постоянно испытывается широкомасштабными атаками со стороны хакеров. Anycast – это технологический ответ на такие «испыта­ния».

Первая значимая атака на корневые серверы системы DNS была зафиксирована 21 октября 2002 года [6]. Атаке подверглись все 13 серверов (в то время технология anycast еще не была внедрена). Мощность атаки состави­ла от 50 до 100 Мбит/с на каждую букву [7].

Это был ICMP-флуд (очень большой объем трафика по протоколу ICMP), пакеты TCP SYN и фрагментированные TCP- и UDP-пакеты (т.е. использовались уязвимости транс­портного уровня стека протоколов TCP/IP). От этого флуда пострадали девять из 13 корневых серверов.

По результатам разбора атаки протокол ICMP зафиль­тровали [8], описали атаку, но, главное, в ICANN был создан комитет Security and Stability Advisory Committee (SSAC), который занялся анализом угроз и выработкой рекоменда­ций по их нейтрализации. К слову, в настоящее время ICMP на многих корневых узлах не фильтруют.

Следующая атака случилась 6 февраля 2007 года [9]. Согласно отчету ICANN, мощность атаки составляла около 1 Гбит/с на один сервер. Атаке поверглись в основном серверы Азиатско-Тихоокеанского региона. Из 13 серверов были атакованы шесть, но только два из них реально имели серьезные проблемы с обслуживанием DNS-запросов (более 95% получили отказ обслуживания). Это были сервер Министерства обороны США (g-root) и сервер ICANN (l-root).

Проблемы на этих серверах возникли из-за того, что администрация серверов еще не внедрила технологию anycast (anycast-облака), которая начала активно приме­няться после 2002 года. Благодаря заранее проделанной работе по обеспечению безопасной и стабильной работы системы, корень системы DNS в 2007 году был готов принять новые мощные атаки.

Собственно, сама технология anycast была предложена в 1993 году в RFC 1546 [10]. Уже в этом документе отмечалось, что DNS прекрасно подходит для развертывания на anycast-адресах из-за особенностей транспортного уровня, где более 80% трафика приходится на UDP.

В апреле 2002, т.е. еще до атаки на корневые серверы, в RFC 3258 [11] были даны уточнения и рекомендации относительно развертывания сервиса DNS на anycast-адресах. Документ специально не содержал в названии термин «anycast», чтобы подчеркнуть тот факт, что никаких специальных усилий по выделению отдельного anycast-пространства адресов и особенной маршрутизации не требуется по сравнению со стандартными процедурами, ориентированными на unicast.

Следующая значимая атака была проведена 30 ноября – 1 декабря 2015 года на корневые серверы системы DNS [12]. Мощность атаки составляла 5 миллионов запросов на каждый корневой сервер (букву). Существенные задержки обслуживания и отказы обслуживания по timeout наблюда­лись у корневых серверов b-root, c-root, g-root, и h-root.

Атака на корень была реализована за счет эффекта усиления на резолверах (кэширующих DNS-серверах ISP) и подмены адресов источника в UDP-пакетах (spoof). Наиболее устойчиво себя ощущали «буквы» (корневые серверы), для развертывания которых использовалось решение DNS-anycast-cloud.

Таким образом, во всех последних случаях атак на корень системы DNS технология anycast помогла справиться атаками. Но как показали последующие события, anycast не является «универсальной таблеткой» от всех болезней.

«Шагреневая кожа» DNS-сети

21 октября 2016 года DNS-сеть компании DYN подверглась мощной сочетанной атаке со стороны неизвестных хакеров [13]. Анализ атаки показал [14], что для организации атаки использовался ботнет Mirai [15], что по некоторым данным суммарная мощность атаки составила 1,2 Тб/с и что создавали его устройства «интернета вещей» (Internet of Things – IoT). Представители DYN не назвали суммарную мощность атаки, но заметили, что объем DNS-трафика во время атаки увеличился в 10-20 раз.

За обсуждением роли IoT в атаке на DYN на второй план отошел тот факт, что основной объем трафика составили не легитимные DNS-запросы, а флуд. Согласно данным redware.com, набор векторов атаки ботнета Mirai довольно разнообразен (рис. 1).

DNS-трафик определен только в качестве одного из источ­ников нагрузки. Все остальное – это в основном невалидный трафик, который можно и нужно отфильтровать на оборудо­вании провайдера (ISP) и не допускать до DNS-серверов.

Следует заметить, что фильтрация таких объемов на сетях глобальных провайдеров – это довольно дорогое мероприя­тие. Если под защиту провайдера ставить каждый DNS-узел в anycast-облаке, то затраты на содержание такой anycast-сети будут впечатляющими.

По этой причине при возникновении сочетанной атаки или атаки с использованием обычного флуда anycast-облака сожмутся до размера защищенных высокопроизводительных узлов или окуклятся в своем регионе, став «локальными» узлами.

Борьбу с формально валидным трафиком будут вести DNS-узлы с плавающими по ситуации лимитами и квотами на обработку запросов. «Размазывание» трафика по anycast-облакам в этом случае не стоит рассматривать как панацею от любого типа атаки. В сети по некоторым оценкам [16], например, в 2014 году было обнаружено 24 миллиона открытых резолверов на домашних маршрути­заторах, которые можно было использовать для генерации трафика в рефлекторных атаках, а также множество IoT-устройств, которые помогут организовать атаки на основе алгоритмов DGA (Domain Generation Algorithm), как это было в случае атаки на DYN.

«Интернет изнутри». DNS и anycast: решения и проблемы

 

Дьявол в деталях…

Кроме DDoS существуют другие «подводные камни», кото­рые подстерегают DNS-сеть, реализованную по технологии anycast. Перечислим основные:

  • для каждого сервера в узле необходимо предусмотреть два канала подключения (один для предоставления сер­виса, а другой для управления);
  • определиться со структурой узла (маршрутизатор, DNS-сервер, сервер статистики и прочее, а также опреде­литься с возможностью виртуализации всех этих функ­ций);
  • выбрать ПО и «железо», которыми в совершенстве владе­ет персонал;
  • провести настройку компонентов узла, добиваясь макси­мальной производительности и надежности;
  • увеличение количества узлов повышает вероятность ошибок при их (узлов) конфигурации;
  • усложняется синхронизация размещенных на серверах файлов зон;
  • требуется защита предаваемых по публичной сети фай­лов зон;
  • требуется отлаженная процедура взаимодействия со службами провайдеров, у которых размещены узлы;
  • требуется развитая система мониторинга;
  • необходимо определиться с уровнем предоставления сервиса и оформить его в виде соглашения (Service Level Agreement);
  • требуется определить такое понятие, как «инцидент» и порядок реагирования в случае его наступления.

 

Наличие двух каналов подключения проистекает из самой сути технологии anycast. Один интерфейс доступен по anycast-адресу, и именно на нем происходит обслуживание запросов резолверов. Второй интерфейс – интерфейс управления и канал передачи файла зоны. Ведь файл зоны нужно передавать по всем хостам облака, а не выборочно какому-то одному. Для этого нужен unicast-адрес.

При выборе параметров интерфейса управления нужно учитывать особенности DNS-сервиса, который предпола­гается оказывать. Одно дело – передавать большой файл зоны TLD четыре раза в сутки, и совершенно другое дело – каждые 5-10 минут передавать множество небольших файлов зон клиентов, которые к тому же еще подвержены постоянным массовым изменениям.

Структура узла сильно зависит от той производительности, которую ожидают от узла. Если это «глобальный» узел в сети крупного провайдера, то он должен держать высокую нагрузку, и в первую очередь может подвергнуться атаке из Интернета.

«Локальный» узел, напротив, обычно не предполагает высоких нагрузок. Это значит, что его можно виртуализо­вать. Хотя и из этого правила возможны исключения.

В настоящее время наиболее распространённым ПО, которое поддерживает DNS, являются серверы BIND [17] и NSD [18]. Каждый из них имеет свои положительные и отри­цательные свойства. BIND более универсален, NSD в ряде случаев более производителен.

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

Система мониторинга – это вообще отдельный проект, который должен обеспечить независимую оценку работо­способности серверов, узлов и всей системы в целом.

Можно, конечно, воспользоваться чем-то типа RIPE-ATLAS [19]. Но если, скажем, для Европы, где находится множество узлов этой системы, это очевидно хороший вариант, то для Российской Федерации такой вариант подходит не очень – слишком мало узлов и слишком мало бесплатных кредитов, чтобы долго обеспечивать существо­вание широкой сети пробников.

Синхронизация файлов зон – это отдельная большая проблема в распределенной DNS-сети. Спецификации DNS20 допускают временное расхождение файлов зон на разных серверах. В частности, в рамках параметров SOA-записи, отвечающих за обновление зоны на вторичных серверах.

Следует также заметить, что в настоящее время измене­ния в содержание зоны сначала вносятся на недоступных из Сети основных авторитетных серверах (hidden-master), а потом распространяются по вторичным серверам. В рамках такого подхода под синхронизацией имеется в виду не расхождение между основным сервером и вторичным, а между вторичными серверами.

Задача может быть усложнена тем обстоятельством, что основных (hidden-master) серверов — из соображений безопасности, надежности и стабильности — может быть несколько. Выгрузка из реестра зоны верхнего уровня может осуществляться поочередно на каждый их них. При больших размерах зон и малом промежутке обновления файла зоны из реестра вероятна ситуация, когда зона на основном сервере обновится раньше, чем предыдущая копия зоны будет доставлена на один из удаленных вторичных серверов. В этом случае ситуацию нужно будет сначала детектировать, а затем и устранить расхождение.

При распространении файлов зоны их следует передавать по защи­щенным каналам, подписывая. Это нужно для того, чтобы принимаю­щая сторона могла удостовериться в истинности источника информа­ции, а также в том, что содержание файла зоны не было искажено при передаче.

В случае аварии или атаки необходим надежный контакт со службами эксплуатации на местах. Обычно это службы провайдера. Они должны вовремя отреагировать на атаку и просьбы о проведении каких-либо мероприятий. Отсутствие такого плотного взаимодействия во время атаки на турецкий национальный домен .tr было одной из причин его длительной (с 13 ноября по 27 декабря 2015 года) [21] неработоспособности.

Еще один важный момент, который связан с вне­дрением anycast на DNS-узлах, это установление и поддержание определенного уровня сервиса (соблюде­ние SLA). Наиболее известный в настоящее время такой документ – это приложение 10 к контракту на админи­стрирование доменов верхнего уровня по программе new gTLD [22] (таблица 3).

«Интернет изнутри». DNS и anycast: решения и проблемы

В принципе, добиться таких показателей можно и без anycast при условии отсутствия атак. Но вот в условиях современного токсичного Интернета обеспечить их без технологии-anycast будет крайне сложно. Кроме того, время отклика DNS по UDP в 500 мс – это очень много. Примерно 25% пользователей веба прекращает загрузку страницы, если время ожидания загрузки превышает 4 секунды [23]. А на одной странице в настоящее время размещено несколько единиц контента, которые могут потребовать нескольких обращений к системе DNS.

Вообще говоря, SLA меняет сам принцип перераспре­деления трафика в DNS-сети, построенной по принципу anycast-облака. Главной целью построения сети ста­новится не минимизация времени ответа резолверу, а максимизация количества обрабатываемых запросов в единицу времени при соблюдении условий SLA.

И в завершение раздела совсем чуть-чуть коснемся понятия «инцидент». Согласно ГОСТ Р 53114-2008 [24], инцидентом информационной безопасности считается «любое событие, которое может нарушить деятельность или информационную безопасность». Нарушение инфор­мационной безопасности оставим в стороне и остановимся только на снижении уровня обслуживания. Деградация сервиса ниже уровня, определенного в SLA, не является в общем случае нарушением деятельности. Поэтому должен быть определен уровень предоставления сервиса, ниже которого ситуация будет определяться как «инцидент», и для этого случая необходимо прописать порядок действий. Соответствующие параметры должны быть указаны как для всей системы в целом, так и для «букв», отдельных узлов, серверов, а также каналов сервиса и управления.

Рис. 2  Anycast облака зоны .RU.

«Интернет изнутри». DNS и anycast: решения и проблемы

Суха теория, мой друг…

Теперь мы снова вернемся к примеру организации anycast-DNS-сети домена .ru. Домен поддерживает пять anycast-облаков. Отдельное облако для каждого географи­ческого региона показано на рисунке 2.

Таким образом, домен .ru поддерживает 35 авторитетных серверов, сгруппированных в 20 узлов, распределенных по пяти anycast-облакам.

Из названия облаков понятно, что используется принцип построения anycast-облаков по географическому признаку, т.е. geocast.

В среднем на всю систему при стационарных условиях (в отсутствие атак) приходится 5-6 миллиардов запросов в сутки. В ситуации DGA-атаки система способна обрабаты­вать 8-9 миллиардов запросов в сутки.

По узлам в среднем при стационарных условиях наблюда­ются показатели представленные на рисунке 3.

При размещении узлов системы DNS применяются следу­ющие общие принципы:

  1. Вынесение узлов в географически разнесенные локации (максимально приближенные к наиболее активным пользователям, применяется для глобаль­ных узлов).
  2. Максимальная концентрация локальных российских провайдеров в точке размещения узла (применяет­ся для узлов на территории РФ).
  3. Наличие свободных емкостей и удобство взаимо­действия с площадкой (применяется для локальных узлов).
  4. Размещение узлов в сетях провайдеров, которые могут обеспечить защиту от DDoS-атак, «очистку» трафика на своих каналах.

 

Максимальное приближение узлов к сетям конечных пользователей предполагает размещение узла либо на узлах Internet eXchange (IX), либо в сетях национальных провайдеров, например, «Ростелекома», либо в сетях глобальных провайдеров, например, LEVEL3.

Размещение на узлах IX позволяет организовать обмен трафиком с большим количеством региональных провайде­ров «последней мили».

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

Сети глобальных провайдеров позволяют встать на «тру­бе», по которой ходит мировой интернет-трафик. На своей «трубе» только сами эти провайдеры могут обеспечить защиту от DDoS-атак, т.к. необходимые решения для такой пропускной способности чрезвычайно дороги.

 

«Интернет изнутри». DNS и anycast: решения и проблемы

Подводя черту…

Тема реализации сервиса DNS на основе технологии anycast обширна. Охватить все аспекты и нюансы в одном материале невозможно. Остались за бортом вопросы организации сети резолверов на anycast-адресах, реализа­ция DNS в сетях CDN и многое другое.

Технология anycast позволяет решить многие проблемы и задачи DNS. Но она также порождает новые задачи и проблемы.

Реализация DNS-облаков требует глубокого анализа DNS-статистики, продуманных инженерных решений и высокой квалификации обслуживающего персонала.

Тем не менее, на данный момент anycast – это наиболее стабильное и надежное решение для построения высо­конагруженных DNS-сервисов, к которым предъявляются высокие требования по устойчивости и надежности.
Ссылки

  1. В Орегоне и Франкфурте в сети Amazon нет серверов, поддерживающих домен .RU, но там в AWS установле­ны на виртуальных машинах сервера доменных имен, которые можно опросить.
  2. https://tools.ietf.org/html/rfc5001
  3. https://tools.ietf.org/html/rfc1546
  4. https://www.ietf.org/rfc/rfc3258.txt
  5. https://tools.ietf.org/html/rfc1997; https://tools.ietf.org/html/rfc3765
  6. http://c.root-servers.org/october21.txt
  7. Для обозначения имен серверов, поддерживающих корень системы DNS, принята нотация типа A.ROOT-SERVERS.NET.Более подробно смотри http://root-servers.org/
  8. https://www.sans.org/reading-room/whitepapers/dns/secure-root-dns-servers-991
  9. https://www.icann.org/en/system/files/files/factsheet-dns-attack-08mar07-en.pdf
  10. https://www.rfc-editor.org/rfc/dfrfc/rfc1546.txt.pdf
  11. https://tools.ietf.org/html/rfc3258
  12. http://www.root-servers.org/news/events-of-20151130.txt
  13. https://dyn.com/blog/dyn-statement-on-10212016-ddos-attack/
  14. https://dyn.com/blog/dyn-analysis-summary-of-friday-october-21-attack/
  15. https://blog.radware.com/security/2016/11/insight-into-mirais-source-code/
  16. https://threatpost.com/dns-based-amplification-attacks-key-on-home-routers/105220/
  17. https://www.isc.org/downloads/bind/
  18. https://www.nlnetlabs.nl/projects/nsd/
  19. https://atlas.ripe.net/
  20. https://tools.ietf.org/html/rfc1034#section-4.3.5; https://tools.ietf.org/html/rfc5936
  21. http://hello.nexusguard.com/hubfs/Threat_Report_Q4_2015_1.25.16.pdf?t=1456951275492
  22. https://newgtlds.icann.org/sites/default/files/agreements/agreement-approved-31jul17-en.pdf
  23. https://blog.kissmetrics.com/loading-time/
  24. http://tdocs.su/22073

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •