<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Navalny Team</title>
    <description>The latest articles on DEV Community by Navalny Team (@navalnyteam).</description>
    <link>https://dev.to/navalnyteam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1160299%2F86499c01-f483-4948-a510-a9a1624738df.jpeg</url>
      <title>DEV Community: Navalny Team</title>
      <link>https://dev.to/navalnyteam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/navalnyteam"/>
    <language>en</language>
    <item>
      <title>Как мы делали приложение «Фотон-2024»</title>
      <dc:creator>Navalny Team</dc:creator>
      <pubDate>Tue, 09 Apr 2024 12:58:49 +0000</pubDate>
      <link>https://dev.to/navalnyteam/kak-my-dielali-prilozhieniie--2ba0</link>
      <guid>https://dev.to/navalnyteam/kak-my-dielali-prilozhieniie--2ba0</guid>
      <description>&lt;p&gt;В рамках кампании против Путина на президентских выборах в России в 2024 году IT-отдел команды Навального разработал приложение под Android и iOS, которое помогало  случайным образом выбирать любого другого кандидата. Для этого приложение использовало аппаратный генератор случайных чисел, основанный на квантовом эффекте. Эту идею предложил Алексей Навальный. &lt;/p&gt;

&lt;p&gt;Задача разработки приложения включала в себя требования непосредственного подключения к аппаратному генератору в офисе ФБК, устойчивости приложения к нагрузкам и блокировкам и обеспечения приватности пользователя. В этой статье мы раскрываем некоторые технические подробности реализации.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s2rt76g17dwypz0e30r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5s2rt76g17dwypz0e30r.png" alt="Основные экраны приложения" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Выбор устройства и покупка квантового генератора
&lt;/h2&gt;

&lt;p&gt;Алексей темой случайности озаботился еще во время изучения языка Python. Когда он столкнулся с функцией random, то заинтересовался, как работает случайность в скриптах, которые он писал во время обучения. Откуда конкретно берется случайное число? &lt;/p&gt;

&lt;p&gt;В 2019 году он узнал о том, что компьютерная случайность не есть истинная случайность, что это псевдослучайность. Когда выполняется random.random() в скрипте, случайное число не рождается во Вселенной из ничего, а основано на простой математике — на так называемых &lt;a href="https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%85%D1%80%D1%8C_%D0%9C%D0%B5%D1%80%D1%81%D0%B5%D0%BD%D0%BD%D0%B0" rel="noopener noreferrer"&gt;вихрях Мерсенна&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Изучение природы случайности Алексей продолжил и в заключении. Чтение биографии Эйнштейна и подробное знакомство с квантовой физикой дало ему идею, откуда можно брать истинную случайность — из фотонов, частиц света.&lt;/p&gt;

&lt;p&gt;В начале XX века Эйнштейн и Бор начали знаменитый спор о том, являются ли случайные процессы в квантовом мире лишь кажущимися, случайными, или же они истинно случайные. Этот спор с Бором многие знают по фразе Эйнштейна «Бог не играет в кости!». Так Эйнштейн выразил позицию, что истинной случайности нет, а есть просто скрытые параметры, которые и создают кажущуюся случайность в квантовых процессах. Через полвека после спора наука смогла проверить экспериментально через &lt;a href="https://ru.wikipedia.org/wiki/%D0%9D%D0%B5%D1%80%D0%B0%D0%B2%D0%B5%D0%BD%D1%81%D1%82%D0%B2%D0%B0_%D0%91%D0%B5%D0%BB%D0%BB%D0%B0" rel="noopener noreferrer"&gt;неравенства Белла&lt;/a&gt;, кто же прав, — и прав оказался Бор. Его интерпретация квантовой механики, называемая копенгагенской, до сих пор &lt;a href="https://arxiv.org/pdf/1301.1069.pdf" rel="noopener noreferrer"&gt;главенствует&lt;/a&gt; в науке.&lt;/p&gt;

&lt;p&gt;Когда в конце сентября 2023 возник &lt;a href="https://meduza.io/feature/2023/10/02/kats-prizval-hodorkovskogo-i-komandu-navalnogo-ob-edinitsya-protiv-putina-pered-vyborami-2024-goda-i-tut-nachalos" rel="noopener noreferrer"&gt;спор о стратегии голосования&lt;/a&gt; на президентских выборах, Алексей вспомнил идею о случайности, создаваемой фотонами, и предложил переложить моральную ответственность выбора «любого другого кандидата», за которого можно было бы проголосовать в рамках кампании против Путина, на генератор истинно случайных чисел. Так родилась идея приложения «Фотон», где реальный фотон будет определять случайного кандидата.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0y3o3hwqy5hj9ewt8vfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0y3o3hwqy5hj9ewt8vfg.png" alt="Письмо Алексея с идеей приложения" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Что важно: Алексея не устраивал простой псевдорандом, ему нужен был реальный фотон, летящий и делающий выбор для каждого конкретного человека.&lt;/p&gt;

&lt;p&gt;От идеи получать истинную случайность по &lt;a href="https://aws.amazon.com/marketplace/pp/prodview-246kyrfjo3bag" rel="noopener noreferrer"&gt;API в AWS&lt;/a&gt;, где случайность брали бы у австралийских физиков, сделавших лазерную установку, и получали бы энтропию из квантовых флуктуаций вакуума, он отказался.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pdwrqhqwfsy3fflu2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pdwrqhqwfsy3fflu2a.png" alt="Письмо Навального о персональном фотоне" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Для надежности мы решили использовать две установки, основную и резервную. Обе от ID Quantique, обе на квантовых эффектах, но на разных. Одна использует &lt;a href="https://ru.wikipedia.org/wiki/%D0%94%D1%80%D0%BE%D0%B1%D0%BE%D0%B2%D0%BE%D0%B9_%D1%88%D1%83%D0%BC" rel="noopener noreferrer"&gt;дробовой шум&lt;/a&gt; при облучении слабым источником света CMOS-матрицы, что вызывает флуктуации количества детектируемых квантов света каждой из ячеек матрицы. Эта установка, &lt;a href="https://marketing.idquantique.com/acton/attachment/11868/f-9a58efcf-5169-45ba-8a1c-ceea3761581f/1/-/-/-/-/Quantis%20QRNG%20PCIe%20New%20Generation_Brochure.pdf" rel="noopener noreferrer"&gt;Quantis QRNG PCIe&lt;/a&gt;, дает порядка 40 Мбит/с энтропии. Вторая, &lt;a href="https://marketing.idquantique.com/acton/attachment/11868/f-021f/1/-/-/-/-/Quantis%20QRNG_Brochure.pdf" rel="noopener noreferrer"&gt;Quantis QRNG USB&lt;/a&gt;, подключаемая по USB и содержащая полупрозрачное зеркало, на которое направляется поток одиночных фотонов, выдает около 4 Мбит/с энтропии. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw39gjb4fneb2nsyq4ae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpw39gjb4fneb2nsyq4ae.png" alt="Изобаржение квантового генератора" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Квантовый генератор случайных чисел с полупрозрачным зеркалом работает следующим образом. Источник раз за разом испускает одиночный квант света. Тот налетает на полупрозрачное зеркало, через которое проходит 50% света, а 50% отражается. И, поскольку фотон неделим (слава Планку и Эйнштейну), он либо пролетает через зеркало, либо отражается. Детекторы определяют, куда попал фотон, и так генерируется случайный выбор, 0 или 1. Для компенсации неравнозначности нуля и единицы в случае, если зеркало имеет не идеально точную 50-процентную пропускную способность, используется постобработка по &lt;a href="https://babel.hathitrust.org/cgi/pt?id=osu.32435030295547&amp;amp;view=image&amp;amp;seq=48" rel="noopener noreferrer"&gt;алгоритму Джона фон Неймана&lt;/a&gt;. С ее помощью определенные выше биты группируются по два, что в четыре раза уменьшает получаемую энтропию, но делает ее unbiased.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfnyypsppzxb6fx4y0q0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfnyypsppzxb6fx4y0q0.png" alt="Схема работы квантового генератора случайных чисел" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Схема работы квантового генератора случайных чисел&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Физическое подключение и первоначальная настройка
&lt;/h2&gt;

&lt;p&gt;Вместе с устройством, помимо руководств по эксплуатации, поставляются исходники драйверов, системные требования (по большей части с упором в программную часть) и библиотека на C.&lt;/p&gt;

&lt;p&gt;Так как драйвер генератора требовал конкретные версии ядра Linux и системных пакетов, мы развернули виртуальную машину с CentOS 7 как самой стабильной из перечисленных в документации поддерживаемых операционных систем.&lt;/p&gt;

&lt;p&gt;Сам генератор был установлен в офисный сервер. Доступ к нему пробросили в виртуальную машину через гипервизор — систему управления виртуальными машинами. Предварительно установили на хост-систему драйвер для корректного отображения устройства и выполнения инструкций проброса. &lt;/p&gt;

&lt;p&gt;После определения генератора в системе скомпилировали драйвер. Заморозили обновления для ядра и используемых драйвером системных пакетов, чтобы случайно не сбить работу системы обновлениями. Только после этого можно было передать разработчикам доступ к виртуальной машине.&lt;/p&gt;

&lt;p&gt;Ввиду того, что документация, технические характеристики, исходный код драйвера — защищенная NDA собственность компании-производителя, в сети отсутствует подробная информация о генераторе, а также темы с решением проблем на форумах. Любые вопросы, касающиеся генератора и его ПО, можно задать только официальным представителям техподдержки.&lt;/p&gt;

&lt;p&gt;В комплекте, помимо самого устройства, находился сертификат, подтверждающий подлинность генератора и результаты проверки работоспособности конкретного устройства.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbju8o3xqx91bmk3l17l9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbju8o3xqx91bmk3l17l9.png" alt="Сертификат квантового генератора" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Архитектура приложения и алгоритм работы
&lt;/h2&gt;

&lt;p&gt;В связи с тем, что пользователю приложения необходимо было подключаться к квантовому генератору, размещенному в офисе ФБК, без сетевого соединения на стороне приложения было никак не обойтись. А значит, Роскомнадзор имел бы все шансы идентифицировать пользователя и попытаться заблокировать адреса, по которым он обращался к генератору при помощи СОРМ и ТСПУ. Мы решили построить архитектуру приложения, исходя из устойчивости к потенциальным блокировкам, нагрузкам от большого количества запросов и сохранения приватности пользователя. &lt;/p&gt;

&lt;p&gt;Приложение должно было быть реализовано на двух платформах (Android и iOS), а также работать на планшетах — выбор пал на Flutter. В будущем плюсами данного выбора станут скорость и гибкость в разработке, но из-за отсутствия достаточного количества библиотек некоторые решения пришлось писать вручную. В нашем случае это была кастомная библиотека DNS over HTTPS (DoH) для работы по протоколу &lt;a href="https://datatracker.ietf.org/doc/html/rfc8484" rel="noopener noreferrer"&gt;RFC 8484&lt;/a&gt;. Вместо стандартного сетевого соединения клиент генерировал случайную строку из 20 символов a-z0-9 и через DoH запрашивал один поддомен дискавери-домена (скажем, &lt;code&gt;w4a1s27c81syputinvor.photon.navalny-team.org&lt;/code&gt;) через случайный публичный резолвер, например 1.1.1.1 от Cloudflare или 8.8.8.8 от Google. В качестве фолбэка было добавлено еще несколько альтернативных, чтобы Роскомнадзор не решался блокировать любой из них под угрозой сломать множество приложений российского сегмента интернета.&lt;/p&gt;

&lt;p&gt;Приложение проверяло, чтобы ответ сервера состоял ровно из двух записей TXT: с префиксами «N» для имени кандидата и «D» — для его описания в utf-8. Необходимо было, чтобы записи были минимально возможного размера, чтобы ответ влез в ограничения ответа DNS — 512 байт. Разгоняться с контентом было нельзя, и поэтому приложение не выдавало длинных биографий кандидатов или их фотографий, тем более что особого значения это не имело. Если вы читаете эту статью вскоре после ее публикации, возможно, сервер еще работает и вы можете сгенерировать себе еще кандидатов командой &lt;code&gt;host -t txt w4a1s27c81syputinvor.photon.navalny-team.org&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zlrcq441nel2ngrjeic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zlrcq441nel2ngrjeic.png" alt="Схема архитектуры приложения ФОТОН-2024" width="800" height="636"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Схема архитектуры приложения «Фотон-2024»&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Клиентская библиотека генератора случайных чисел написана на C и представляет собой довольно простой интерфейс: перечисление подключенных устройств, получение версий, открытие-закрытие сессии и, собственно, запрос на получение случайных чисел.&lt;/p&gt;

&lt;p&gt;Сервер HW RNG, к которому был подключен генератор, при запуске устанавливал TCP-соединение с DNS-сервером (по отдельному внутреннему порту) и без остановки лил туда случайные числа. Поскольку сервер считывал данные из сокета только по мере поступления запросов от пользователей, рано или поздно backpressure от сервера заставлял клиент заблокироваться. Энтропию из буфера брали в порядке &lt;a href="https://ru.wikipedia.org/wiki/LIFO" rel="noopener noreferrer"&gt;LIFO&lt;/a&gt;, чтобы для пользователей брались «свежие» фотоны.&lt;/p&gt;

&lt;p&gt;DNS-сервер реализовывал основную логику бэкенда. При запуске он считывал JSON-файл с кандидатами с бакета GCS и обновлял его в фоне каждые 10 секунд на случай изменений. Сервер считывал данные от HW RNG и писал их в буфер фиксированного размера на случай поступления спайков клиентских запросов. Размер буфера можно сделать таким, сколько памяти не жалко — хоть гигабайт.&lt;/p&gt;

&lt;p&gt;Сервер получал запрос с утвержденным адресом нашего дискавери, брал нужное количество байт энтропии и делал выбор кандидата в соответствии с текущим конфигом, полученным с GCS. Ответ упаковывался в TXT-записи DNS.&lt;/p&gt;

&lt;p&gt;Чтобы сделать работу системы максимально надежной, было реализовано несколько аварийных режимов:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Если по каким-то причинам энтропии в буфере было бы недостаточно (например, сломался сервер HW RNG или пропал интернет в офисе ФБК), DNS-сервер сгенерировал бы случайное число из /dev/urandom. Пользователь бы об этом не узнал, но администраторы получили бы оповещение. К слову сказать, этого так ни разу в продакшене и не случилось — все случайные числа были сгенерированы настоящими фотонами.&lt;/li&gt;
&lt;li&gt;Если бы у пользователя оборвалось соединение, отключился интернет или приложение было бы заблокировано Роскомнадзором, на такой случай в него была заложена функция локального рандома для выбора кандидата из списка, которое приложение в фоновом режиме получало с GCS.&lt;/li&gt;
&lt;li&gt;На случай, если бы свежеустановленное приложение так ни разу и не смогло обновить список кандидатов и DNS-сервер не отвечал, в нем еще был захардкожен список с кандидатами на дату сборки приложения.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Если приложению не удавалось подключиться к квантовому генератору в офисе ФБК и оно было вынуждено делать локальную генерацию, то оно честно в этом признавалось: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjclhmbk7bd398wox3c2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjclhmbk7bd398wox3c2.png" alt="Экран сбой подключения к Фотону" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Для хранения данных в приложении использовались защищенные хранилища — Keychain (iOS) и KeyStore (Android).&lt;/p&gt;

&lt;p&gt;Для отправки запроса в «фотонную пушку» по нажатию кнопки в приложении и получения ответа нужны были считанные миллисекунды: пользователь дольше любовался красивой анимацией, реализованной отделом дизайна. &lt;/p&gt;

&lt;p&gt;Бот «Умного голосования» для мессенджеров аналогично обращался к DNS серверу, получал «квантового кандидата», и ответ в нем был мгновенным.&lt;/p&gt;

&lt;h2&gt;
  
  
  Заключение
&lt;/h2&gt;

&lt;p&gt;Для контроля работы и сбора статистики были организованы дашборды в Grafana. Записывались запросы к квантовому генератору и состояние буфера энтропии. Был подключен Firebase c инструментарием Google Analytics на стороне приложения.&lt;/p&gt;

&lt;p&gt;«Фотонная пушка» сработала более 650 тысяч раз.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07lhj3064cnwrptq6wzj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07lhj3064cnwrptq6wzj.png" alt="График распределения запросов к квантовому генератору из приложения и телеграм-бота&amp;lt;br&amp;gt;
" width="800" height="356"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;График распределения запросов к квантовому генератору из приложения и телеграм-бота&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Приложением воспользовались более 70 тысяч человек. Оно попало в топы рейтингов сторов в своей категории. Роскомнадзор даже &lt;a href="https://t.me/news_sirena/25646" rel="noopener noreferrer"&gt;ограничил доступ к сайту Google Play Market&lt;/a&gt; в день выпуска.&lt;/p&gt;

&lt;p&gt;Задача сделать приложение, которое подключалось бы к квантовому генератору и выдавало бы один результат, звучит просто. Но в условиях ограничений интернета в России она вынуждает разработчиков продумывать в своей архитектуре дополнительные меры безопасности и дополнительный функционал для борьбы с репрессивными органами, которые не только ограничивают свободу, но и ломают российский интернет. Нашим долгом было воплотить идею Алексея Навального и продолжить борьбу с Путиным.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Все это стало возможным только благодаря вашей помощи. Поддержать нашу работу можно по ссылке: &lt;a href="https://donate.fbk.info/it" rel="noopener noreferrer"&gt;https://donate.fbk.info/it&lt;/a&gt;. Чтобы сделать пожертвования еще безопаснее, мы даже добавили на сайт &lt;a href="https://donate.fbk.info/#crypto" rel="noopener noreferrer"&gt;функцию генерации одноразового биткоин-адреса&lt;/a&gt; и обязательное смешивание всех полученных средств через миксер.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>flutter</category>
      <category>devops</category>
      <category>digitalresistance</category>
    </item>
    <item>
      <title>Security of Navalny's underground resistance on the Dark Web</title>
      <dc:creator>Navalny Team</dc:creator>
      <pubDate>Wed, 25 Oct 2023 10:53:25 +0000</pubDate>
      <link>https://dev.to/navalnyteam/security-of-navalnys-underground-resistance-on-the-dark-web-1lga</link>
      <guid>https://dev.to/navalnyteam/security-of-navalnys-underground-resistance-on-the-dark-web-1lga</guid>
      <description>&lt;p&gt;In 2017, Navalny's team started an underground resistance in Russia. Initially serving as pre-election hubs, they later evolved into regional political centers. This network of these centers posed a significant threat to Putin, leading to a relentless escalation of repression tactics, including raids, account freezes, employee arrests, physical assaults, and menacing threats. In 2021, the authorities falsely concocted an extremism case, ultimately forcing the shutdown of those centers, all purportedly in the name of safeguarding those involved.&lt;/p&gt;

&lt;p&gt;In December 2022, our team relaunched Navalny's resistance movement, but this time in a form of an underground organization. Our primary objective was to create a secure platform for online communication and collaboration among coordinators and activists.&lt;/p&gt;

&lt;p&gt;In developing our security system, we avoided relying on security through obscurity. By sharing the information in this article, we are not increasing the risks but, instead, providing experts with an opportunity to evaluate our security measures and assess their relevance and depth.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the system
&lt;/h2&gt;

&lt;p&gt;The website of Navalny's underground resistance provides each user with a personal account. Activists sign up based on their professional and geographical affiliations. The platform offers participants assignments tailored to their specialties and interests, providing them a possibility for direct communication with coordinators. Users earn points for completing assignments, with that achieving specified levels, and then can purchase avatars as rewards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6hi9nm57ur4fcs2k0mq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe6hi9nm57ur4fcs2k0mq.jpeg" alt="Personal account interface screen" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In August 2023, the platform underwent a significant update, introducing a messenger feature that facilitates anonymous communication among participants while they are working on assignments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threat and attacker modeling
&lt;/h2&gt;

&lt;p&gt;Our system development commenced with threat modeling, where we outlined the objectives that potential attackers might pursue. We were acutely aware of the risks faced by those in Russia who support our cause, and we prioritized their safety above everything else. We identified the primary threat as the potential exposure of the activists' identities. Additionally, we acknowledged secondary threats, which encompass denial of user access to the service, jeopardizing confidential projects and plans, compromising the integrity of our service's software, and moving laterally to other services after a potential compromise.&lt;/p&gt;

&lt;p&gt;During the second phase, we profiled potential intruders, identifying who might act as our adversaries — primarily, corrupt law enforcement agencies or special services, and Internet censorship enforcement entities. We then assessed their capabilities for attaining their objectives. We considered four primary attack vectors: targeting our systems through hacking, conducting searches on activists, compromising our employees through bribery, infiltration, or threats, and the most straightforward approach: encountering a "Comrade Major" in an online chat room.&lt;/p&gt;

&lt;p&gt;Threat and attacker modeling serve as the bedrock of information security. Our priorities often meant we had to make product decisions that could negatively impact user experience and retention. For instance, we couldn't create a user-friendly mobile app with a clever workaround for evading censorship, equipped with notifications to improve user retention, like the ones in the “Smart Voting” app. That limitation arose from the concern that such an app would become easy to discover if someone were to search the phone of an activist.&lt;/p&gt;

&lt;p&gt;Once we pinpointed the threats that demanded our attention, we initiated planning of a layered security system comprising multiple security perimeters. With each additional barrier we erected — such as authentication or a firewall — we asked ourselves, "Alright, but what if these defenses are bypassed? What potential actions could an attacker take afterwards?" Our goal was to ensure that any breach would fall short of facilitating a successful attack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tor
&lt;/h2&gt;

&lt;p&gt;One pivotal decision we made was hosting the website on the dark web. Standard web browsers not only expose a wealth of user information, including device metadata, IP addresses, but also leave behind extensive traces on the user's device, like browsing history and caches. We made the deliberate choice to exclusively employ the Tor browser to access our system, as it minimizes these risks and takes numerous other measures to safeguard users.&lt;/p&gt;

&lt;p&gt;This approach complicates the process of implicating a user in the organization's activities in the event of device seizure. While it might be evident that the Tor application is installed on a device, it would remain unclear what purpose it served. It's worth noting an interesting tidbit: Edward Snowden used Tor to communicate with journalists when disclosing classified information about the NSA. As a side note, Tor is being developed by a nonprofit organization, so if you can, consider supporting our fellow colleagues financially — &lt;a href="https://donate.torproject.org/" rel="noopener noreferrer"&gt;donate.torproject.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tor browser can also serve as a means to evade Roskomnadzor's (the Russia’s Media Supervision Agency, or simply saying the main censorship body of the country) surveillance. With the widespread deployment of the DPI (Deep Packet Inspection) equipment by most ISPs in Russia, concealing access to HTTPS websites has become considerably more challenging. Mainstream browsers still lack the ECH (Encrypted Client Hello) protocol support, and while Roskomnadzor may not discern the data exchanged between the user and the site, it can track plenty of metadata, e.g. which user has accessed which domains. Consequently, we opted to host the site on the .onion domain, rendering it inaccessible through regular browsers. This ensures that users cannot inadvertently stumble upon the website and register that fact in DPI logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal data
&lt;/h2&gt;

&lt;p&gt;To sign up within the system, an activist is not required to disclose any personally identifying information. We only identify activists through their chosen pseudonyms, without any attempts to uncover their true identities. Every activist is assigned a reputation, quantified in points. These points accrue as supporters successfully complete tasks, raising their trustworthiness. As a result, more confidential and significant assignments can be delegated to them. So if a "Comrade Major" seeks access to classified projects, they must first undertake simpler tasks, such as distributing flyers or creating protest graffiti. Let’s give them a chance to finally do something useful!&lt;/p&gt;

&lt;p&gt;To sign up for the system, a participant is required to create a pseudonym (username), a suitably complex password, and provide a brief description of their professional skills in an open format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvnodaoksahsbs4zmr5r.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvnodaoksahsbs4zmr5r.jpeg" alt="Sign up interface screen" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actual names, email addresses, and phone numbers are not collected (except for an email address for the first contact, which is then erased from the database). All registrations undergo an extra level of review, following which users gain access to the system's complete functionality. The moderation process serves as a safeguard against excessive registration attempts. Given that Tor users remain anonymous, Tor shields malicious users who could inundate the system with automated bot submissions and disruptive messages from us. To ensure minimal disruption to the site's operation, our moderators scrutinize and filter out irrelevant or spam registrations. They also categorize supporters based on their professional interests (such as software engineers, designers, attorneys, etc.) before granting them access to the site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69xei5k4g8xp31rzmcgg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69xei5k4g8xp31rzmcgg.jpeg" alt="Moderation awaiting interface screen" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Insider risks
&lt;/h2&gt;

&lt;p&gt;Insiders refer to our staff members, including coordinators, moderators, software engineers, system administrators, and so on. They possess additional access to the system, which could potentially be exploited by attackers. While we have confidence in our employees, we still implement precautions in case they are compromised. This is because an employee might not only willingly become an attacker (due to ideological reasons or bribery) but could also fall victim to hacking (remember that phishing remains a threat) or be coerced into cooperation, possibly through pressure on their family members in Russia.&lt;/p&gt;

&lt;p&gt;To safeguard against insider threats, we take a few measures. Firstly, we adhere to the principle of least privilege, ensuring that employees only have access essential for their immediate responsibilities. For instance, software engineers can access the code repository but not the servers, while testers can access the testing environment but not the production environment. Secondly, we employ multiple security layers to shield against insider threats. For example, even if system administrators were to dump the database or exfiltrate files from the downloaded file storage, they would be unable to decrypt them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encryption
&lt;/h2&gt;

&lt;p&gt;We apply encryption to protect all sensitive database fields and uploaded files. Our solution involves using symmetric encryption with authentication (AEAD), which serves as a protection against tampering with the encrypted content. Importantly, the encryption keys are not retained within the application itself but are securely stored in Google's Cloud KMS (Key Management System). Additionally, we employ envelope encryption, that entails encrypting each file with its unique ephemeral key, that is in turn wrapped by KMS.&lt;/p&gt;

&lt;p&gt;Cloud KMS keys are not exportable and are stored within a separate Google Cloud project. Access to this project is restricted to a select group of highly trusted administrators. Permission for encryption and decryption using these keys is exclusively granted to service accounts linked to workload identities of services that need to interact with the database.&lt;/p&gt;

&lt;p&gt;This encryption approach minimizes the security perimeter of the data processed by the service. For instance, even if an administrator accesses the database, they won't be able to see the plaintext. The same holds true for backups. Furthermore, even systems responsible for creating backups do not need to decrypt the data. Everything is securely backed up directly in the encrypted state, and in order to compromise the data, one would also need to acquire access to the KMS keys, significantly raising the difficulty level of any potential data compromise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attacks on the application
&lt;/h2&gt;

&lt;p&gt;If the application itself is compromised due to a technical vulnerability, an attacker can potentially access everything within the application's purview. It is the system's most valuable asset, and a successful attack could yield significant damage. To mitigate this risk, we implement two key strategies. Firstly, we refrain from storing any personal data of our users, ensuring that even in the event of data exfiltration, it would be exceptionally challenging to identify supporters. Secondly, we make concerted efforts to minimize the attacker's ability to establish a foothold within the system.&lt;/p&gt;

&lt;p&gt;As our servers run on Google Kubernetes Engine (GKE), they consist of virtual machines that undergo regular updates and are frequently replaced by fresh ones. We employ Google's Container-optimized OS (COS) as the base image, known for its security posture. When it comes to service authentication, we avoid using exported JSON keys of service accounts, which can be susceptible to theft and long-term misuse. Instead, we rely on GKE Workload Identity, which furnishes applications with temporary tokens that have a brief lifespan, typically lasting only a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;The entire infrastructure is segregated into two distinct environments: trusted and untrusted. The untrusted environment, devoid of sensitive data, is primarily dedicated to development and testing purposes. Conversely, the trusted environment encompasses all components with access to protected data.&lt;/p&gt;

&lt;p&gt;The application code and containers are built by specialized secure virtual machines known as "runners." The runners operate in an isolated environment separate from other projects and engineers. Access to the project where the runners operate is restricted to a limited number of trusted engineers, and even then, direct access is only permitted in the event of runner failures. Service accounts associated with these machines hold administrative access to the production environment. This enables adoption of the gitops approach, resulting in meticulously documenting a comprehensive history of all production changes in both git logs and Google Cloud audit logs. Such dual audit setup allows for retrospective tracing of potential attacks.&lt;/p&gt;

&lt;p&gt;We use the untrusted environment for building code from unprotected GitLab branches that are not considered secure. These branches are open for any developer to commit changes for review or deployment to test servers. Even if a developer were to introduce something malicious that compromises the build server, it would not grant them access to the production environment. Following a review by another team member and the subsequent merging of the branch into the primary production branch, the code undergoes build and deployment within the trusted environment, dedicated to production.&lt;/p&gt;

&lt;p&gt;To improve cost-efficiency and achieve better server utilization, we use Kubernetes. For our build system, we've developed an in-house solution, allowing virtual machines with GitLab runners to run only when they are needed. The runner management system itself runs in the trusted environment, bolstering our overall security measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  DoS attacks
&lt;/h2&gt;

&lt;p&gt;When the system was launched, the team anticipated that, unlike in the open Internet, attackers would find it costly to carry out DoS attacks within the Tor network. However, attackers wasted no time, and our monitoring systems quickly detected a significant surge in server load. In the beginning, we were prepared to filter traffic only at the HTTP level, and initially it was sufficient. However, attackers switched tactics to more sophisticated ones, exploiting numerous ways to overwhelm our Tor client.&lt;/p&gt;

&lt;p&gt;To provide some context, it's essential to understand how onion sites work. Unlike in regular Internet, where clients directly connect to servers, in Tor, both clients and servers establish connections with specialized introduction nodes. Those nodes act as intermediaries to introduce clients and servers to each other. For data transfer, after being introduced, both parties connect to rendezvous nodes through secure tunnels. The rendezvous servers then consolidate both tunnels into a single circuit, facilitating transmission of regular HTTP traffic between the clients and the servers.&lt;/p&gt;

&lt;p&gt;In our case, the attackers flooded us with a massive influx of connection requests, effectively forcing our server to initiate numerous connections with rendezvous servers, which involved computationally intensive asymmetric cryptography. Notably, they never even attempted to transmit any data through these established tunnels, and the attack never reached the HTTP servers.&lt;/p&gt;

&lt;p&gt;Standard defense mechanisms against DoS attacks, such as identifying the sources and temporarily blocking them, are unfeasible within the Tor network because we lack any means to identify the clients. Consequently, we developed a specialized solution. The key challenge was that a typical onion server could not scale efficiently. When an onion server is launched, it connects to the Tor network and publishes a service descriptor that points exclusively to itself. If one were to initiate a second instance of the same server, it would overwrite the descriptor of the first instance, rendering them unable to function at the same time.&lt;/p&gt;

&lt;p&gt;To tackle this issue, we employed onionbalance, a third-party tool that enabled us to deploy multiple onion servers at once, each operating on its unique, randomly generated onion address. Subsequently, onionbalance retrieved their descriptors from the network, consolidated them into a unified descriptor, and then published that combined descriptor as the primary onion site's descriptor. This approach effectively distributed the traffic load across the servers, enabling them to handle traffic surges.&lt;/p&gt;

&lt;p&gt;Here's an overview of our solution's architecture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts5v3q9y8qw29om8gv2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts5v3q9y8qw29om8gv2g.png" alt="Architecture screen" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tor-balancer serves as a wrapper around onionbalance, interacting with our cluster to obtain a list of healthy and active Tor server instances. It then creates a configuration for onionbalance and runs the balancer. If the collection of active instances change, for instance, if some instances go offline or new ones come online, the configuration is automatically regenerated, and onionbalance is restarted.&lt;/p&gt;

&lt;p&gt;Meanwhile, Tor-frontend wraps a standard onion server. It generates a random onion address, starts an onion server at that address, waits until it successfully registers itslef and becomes accessible on the Tor network, and subsequently starts responding to HTTP requests with its designated onion address. This HTTP interface is what allows tor-balancer to discover which individual onion addresses should be merged to construct the final descriptor. This way, we evenly distribute the load across multiple onion addresses using "discovery" descriptors, preventing any single address from being overloaded by an attacker and causing denial of service.&lt;/p&gt;

&lt;p&gt;The client initiates a connection with the server once, which is typically a slow and resource-intensive operation. Afterward, within that same connection or circuit, it can establish numerous logical connections, which are faster and more resource-efficient. To counteract potential attacks, we enforce a rule: if a client establishes an excessive number of connections within its circuit, we either terminate the circuit entirely or impose rate limits using ingress-nginx. This strategy allows our system to effectively counteract such attacks.&lt;/p&gt;

&lt;p&gt;The second layer of defense involves relinquishing server privacy. Since we are not a dark market and take pride in openly declaring ownership of our service, there's no point for the server to establish a triple-wrapped connection to a rendezvous node. Instead, we utilize a Tor option that enables our server to form a direct connection. This significant adjustment has led to a substantial reduction in the amount of asymmetric cryptography performed on the server, significantly reducing its workload. Client privacy remains unaffected, and the server's operations become more efficient. As a result, we have successfully thwarted any further DoS attacks on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coordinators
&lt;/h2&gt;

&lt;p&gt;Within this system, any participant has the capability to send a message to a coordinator and receive a response. For instance, they can report the completion of an assignment or ask a question.&lt;/p&gt;

&lt;p&gt;To facilitate the coordinators' responsibilities, we employ a dedicated administrative panel built on the Django framework. Its functionality proves more than sufficient for efficiently managing sign-up requests, assigning tasks, assessing their completion, and engaging in private chats with activists. Moderators are not privy to users' real usernames; instead, they are assigned impersonal sequential numbers to enable another level of pseudonymization. All administrators are mandated to employ two-factor authentication, and their access is restricted by job role, with access exclusively allowed through a VPN. We also maintain audit logs to enable tracking of which staff member utilized which access.&lt;/p&gt;

&lt;p&gt;Team coordinators were tasked with distributing and grading assigned tasks, supervising execution and maintaining communication with the activists through private chats. This indirect process necessitated human resources and raised the issue of delayed feedback. To address it, we decided to launch public group chats based on the platform, allowing supporters to interact directly with each other within a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chats
&lt;/h2&gt;

&lt;p&gt;In terms of both functionality and design, the chat interface closely resembles the interface of a messenger app like Telegram. Users can seamlessly switch between chats, read, compose, and delete messages, respond to messages from others, and clear message histories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqegh5mcv6cb3fee0s8l.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqegh5mcv6cb3fee0s8l.jpeg" alt="Chat interface screen" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our chats run on top of websockets over the Tor network. Every chat message is encrypted at rest with Cloud KMS. To prevent an excessive number of requests to KMS, the system incorporates a local cache in the application's memory for plaintext messages.&lt;/p&gt;

&lt;p&gt;Users have the option to manually delete chat messages, and messages are also automatically deleted after a certain period of time.&lt;/p&gt;

&lt;p&gt;To safeguard chat rooms against message spam, the system enforces a limit on the number of messages a user can send within a given time frame. Once this limit is reached, further messages will not be accepted. Additionally, we conducted comprehensive load testing of the chats with various scenarios to ensure that the server can withstand the anticipated load.&lt;/p&gt;

&lt;p&gt;We've implemented measures to safeguard chat users from potential metadata-based identification. The concern here is that attackers with access to SORM (the police system for traffic supervision) can detect when users access Tor. While they may not discern the specific activities users engage in, concealing their presence becomes quite challenging. Attackers could enter a popular chat room within the system, send bulky messages of a certain size, and exploit SORM data to identify users across Russia who received messages of the same size at the same time. Although this identification process may yield noisy results and somewhat fuzzy identification, repeated attempts could eventually allow them to reliably ascertain which Russian users were present in the chat room during that time. To substantially complicate such an attack, we introduced randomness in both the message sizes delivered to users and the time intervals between these messages. This deliberate variation obscures the signal, reducing it to a level beneath the noise, thereby making identification through metadata exceedingly difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  Anonymity
&lt;/h2&gt;

&lt;p&gt;The deepest level of our defense is anonymity. Even if all the abovementioned security measures were to fail—servers get compromised, coordinators are compromised, and administrators face threats—the only thing an attacker would obtain is solely a record of anonymous-to-anonymous communication that doesn't disclose any personally identifying information.&lt;/p&gt;

&lt;p&gt;However, even without any security breaches, publicly accessible chat rooms are susceptible to spammers, provocateurs, and other malicious individuals. To mitigate those risks, we implement some protective measures.&lt;/p&gt;

&lt;p&gt;To begin with, each chat room is allocated a moderator who can see slightly more than a regular user. The moderator has access to both the merged feed, where all messages subject to moderation are routed to, and a violations feed, which contains reports from other users regarding rule violations. Within these administrative chats, the moderator holds the ability to delete messages and impose temporary or permanent bans on users. Importantly, the moderator need not be an administrator with access to the admin panel over VPN; they could be an ordinary user signed in within their personal account, albeit endowed with extra privileges.&lt;/p&gt;

&lt;p&gt;Furthermore, to thwart any attempts by an individual like "Comrade Major" to amass enough data to indirectly identify a user, we've instituted an additional mandatory layer of pseudonymization. Within a chat room, each user is allocated a randomly generated alias distinct from the one they use for their primary sign-in—this is the alias visible to other participants. The usernames of the activists that they use when logging into their accounts remain secret and are not displayed anywhere. We've prearranged a selection of adjective-noun combinations to ensure that all participants sport amusing and unique aliases. Consequently, users encounter each other as "Spotted Hippogryph" or "Cute Cat." Users also have the option to change their alias to another randomly generated one if desired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxx675o0n84a6vlga6eut.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxx675o0n84a6vlga6eut.jpeg" alt="Username random generator interface screen" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Fedor bot, being constant present in the chat room, serves as a reminder to participants about safety protocols. For instance, it advises them not to disclose any personal information about their real lives and encourages them to regularly rotate their nicknames to sever ties with their past online identities. Functioning much like a regular chat participant, the bot selects a random message from its knowledge base and shares it within the chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  File uploads
&lt;/h2&gt;

&lt;p&gt;The messenger doesn't just facilitate exchange of short messages; it also allows image uploading. We've taken measures to ensure that the metadata associated with the images uploaded to a shared chat room is automatically stripped off, preventing anyone from ascertaining details such as the creator, creation date, and location.&lt;/p&gt;

&lt;p&gt;To accomplish this, we opted for exiftool as our solution for metadata removal. It supports the broadest range of formats and is easy to use. However, it's worth noting that exiftool relies on numerous codecs written in C, a language that makes it easy to introduce vulnerabilities enabling remote code execution.&lt;/p&gt;

&lt;p&gt;To mitigate the risk of a compromised exiftool affecting the entire application, we've isolated it as a separate microservice within a sandboxed environment. This setup ensures that if a malicious file is encountered, hackers won’t be able to breach the primary service or establish a foothold on the server, thereby preventing interception of other users' files. This microservice runs within Google's serverless Cloud Functions execution environment, which limits the lifespan of an instance and restricts its access to the database and other microservices at the network level.&lt;/p&gt;

&lt;p&gt;During the initial day of the chat rooms’ launch, our security measures were put to the test when malicious testers attempted to shell our system with a genuine zip bomb disguised as an image containing millions of empty pixels. A zip bomb, in this context, refers to an archive filled with billions of zeroes that have been compressed to an extraordinarily compact size by a compression algorithm. If a recipient attempts to decompress it, they would rapidly deplete their available memory or storage, or even both.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_decompression_bomb_check&lt;br&gt;
    raise DecompressionBombError(&lt;br&gt;
PIL.Image.DecompressionBombError: Image size (50625000000 pixels) exceeds limit of *N* pixels, could be decompression bomb DOS attack.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, the bomb was defused as our library's security measures kicked in. However, even if it had exploded, it would not have caused any harm to the primary service thanks to the isolation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We've developed a unique tool that empowers supporters and activists in Russia to challenge the regime more efficiently while maintaining secure communication and minimizing the risk of being exposed. This endeavor was made possible through generous donations from our supporters, and we express our heartfelt gratitude to them! You can also become a part of the underground resistance and lend your support right away:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patreon of the underground resistance:&lt;/strong&gt; &lt;a href="https://www.patreon.com/shtab_navalny" rel="noopener noreferrer"&gt;https://www.patreon.com/shtab_navalny&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can donate company shares to us via the DonateStock website. It's quick and convenient, and the site sometimes doubles the sum of donation:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://donatestock.com/rikolto-ltd" rel="noopener noreferrer"&gt;https://donatestock.com/rikolto-ltd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ACF crypto wallets:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitcoin&lt;/strong&gt;&lt;br&gt;
3QzYvaRFY6bakFBW4YBRrzmwzTnfZcaA6E&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ethereum&lt;/strong&gt;&lt;br&gt;
0x314aC71aEB2feC4D60Cc50Eb46e64980a27F2680&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monero&lt;/strong&gt;&lt;br&gt;
42e1hkdsTHUUWSM24jVgLTH4MDJPMbNS1XDt7rK36dTBSKweohz9FSWKAAoqHLN9nSVgocnSnkR2AaLMWtsrmAoQGPdWSE1&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zcash (Z-address)&lt;/strong&gt;&lt;br&gt;
zs1l8ztrqpk0qyn2hyte3x9m568taz64jyc90ppfskylqgawxw7r3gq453yn6hk9swq2l0dq9yal0a&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;USDT (ВЕР-20)&lt;/strong&gt;&lt;br&gt;
0x9A4B20a7909Af03dd8B4f28A419840F9715E1F73&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benevity is a corporate donation software used by over 900 companies: Apple, Google, Twitter, Facebook and others. If you work for a large company, your corporate website probably has an Employee Giving section. Type Anti-Corruption Foundation in the search box there and enter the donation amount. The advantage of Benevity is that sometimes corporations will multiply the amount of donations made through it by several times.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>darkweb</category>
      <category>tor</category>
      <category>security</category>
    </item>
    <item>
      <title>Безопасность Штабов Навального в Dark Web</title>
      <dc:creator>Navalny Team</dc:creator>
      <pubDate>Wed, 25 Oct 2023 08:50:00 +0000</pubDate>
      <link>https://dev.to/navalnyteam/biezopasnost-shtabov-navalnogho-v-dark-web-3739</link>
      <guid>https://dev.to/navalnyteam/biezopasnost-shtabov-navalnogho-v-dark-web-3739</guid>
      <description>&lt;p&gt;В 2017 году команда Навального открыла штабы по всей России. Сначала они были предвыборными, а затем стали региональными политическими центрами. Опасная для Путина, сеть штабов подвергалась непрерывным и усиливающимся репрессиям: обыски, аресты счетов и сотрудников, физическое насилие, угрозы. В 2021 году власти выдумали дело об экстремизме, и штабы пришлось закрыть — для защиты всех участников.&lt;/p&gt;

&lt;p&gt;В декабре 2022 года наша команда возобновила работу штабов Навального — теперь в виде подпольной организации. Нужно было разработать средства для коммуникации и коллаборации координаторов и активистов в онлайне. Осознавая риски для сторонников и активистов, находящихся в России, мы подошли к вопросу обеспечения их безопасности максимально серьёзно. Мы строим нашу систему безопасности, не полагаясь на принцип security via obscurity, поэтому, рассказывая о ней, мы не подвергаем ее значительным дополнительным рискам, а напротив — даем возможность специалистам понять уровень ее безопасности и дать свою оценку качества нашей работы.&lt;/p&gt;

&lt;h2&gt;
  
  
  Описание системы
&lt;/h2&gt;

&lt;p&gt;Сайт Штабов Навального представляет из себя личный кабинет. Активисты могут зарегистрироваться в нем по профессиональному и территориальному признаку. На базе платформы публикуются задачи, которые назначаются в соответствии со специальностью и интересами участников, имеется возможность связи с координатором. Пользователь может заработать баллы за выполненные задачи, достигнуть определенных уровней и, например, приобрести за это аватары. В августе 2023 года на базе платформы вышло большое обновление: запущен мессенджер, обеспечивающий анонимную коммуникацию участников в рамках задачи. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fknvwmfctszds4o7rq83n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fknvwmfctszds4o7rq83n.jpeg" alt="Интерфейс главное страницы с заданиями сайта Штабов" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Моделирование угроз и нарушителей
&lt;/h2&gt;

&lt;p&gt;Разработку системы мы начали с моделирования угроз — определения целей, которые могут ставить перед собой злоумышленники. Как главную угрозу мы определили идентификацию участников штабов. Вторичные угрозы — блокировка доступа пользователей к сервису, компрометация секретных проектов и планов, компрометация программного обеспечения нашего сервиса и получение через него доступа к другим сервисам.&lt;/p&gt;

&lt;p&gt;Вторым этапом мы произвели моделирование нарушителя — прикинули, кто может быть нашим злоумышленником (очевидно, это сотрудники коррумпированных правоохранительных органов и спецслужб, органов обеспечения цензуры в интернете), и какие у них есть возможности по достижению их целей. Мы рассматривали четыре основных вектора атак: на серверы (хакерство), на активистов (обыски), на сотрудников (внедрение, подкуп, угрозы) и самое простое: «товарищ майор» в чате.&lt;/p&gt;

&lt;p&gt;Моделирование угроз и нарушителей — это фундамент обеспечения информационной безопасности. Поставив безопасность активистов во главу угла, мы были вынуждены часто принимать продуктовые решения в ущерб юзабилити, удержанию пользователей и т.д. Например, мы не могли позволить себе сделать удобное приложение для телефона с крутым обходом блокировок, &lt;a href="https://dev.to/navalnyteam/rkn-protiv-prilozhieniia-navalnyi-borba-za-dostupnost-2gg6"&gt;как в Умном голосовании&lt;/a&gt;, с уведомлениями, возвращающими неактивных пользователей, — ведь при досмотре телефона это приложение будет легко найти.&lt;/p&gt;

&lt;p&gt;Когда мы определили, с какими угрозами надо бороться, мы начали планировать эшелонированную систему безопасности с несколькими периметрами защиты. Каждый раз, когда мы возводили очередную стену: «тут у нас аутентификация», «тут у нас файрвол», — мы думали: «Хорошо, а что будет, если эта защита будет взломана? Что сможет сделать злоумышленник?» — и придумывали, как сделать, чтобы этого было недостаточно для успешной атаки.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tor
&lt;/h2&gt;

&lt;p&gt;Одним из ключевых решений стало размещение сайта в dark web. Обычные браузеры не только раскрывают много информации о пользователе, например метаданные с типом и именем устройства, IP-адрес пользователя, но и оставляют много следов на устройстве — историю посещений, кэши. Нами было принято решение для подключения к штабам использовать исключительно браузер Tor, который ничего из этого не делает и предпринимает еще много других мер для защиты пользователей. Доказать причастность пользователя к деятельности организации, в случае изъятия устройства, таким образом проблематично — видно, что приложение Tor установлено, но для чего оно использовалось — непонятно. И тут на ум приходит интересный факт: именно Tor использовал Эдвард Сноуден для коммуникации с журналистами при сливе секретных данных АНБ. Кстати говоря, Tor разрабатывает некоммерческая организация, и если у вас есть возможность, поддержите коллег финансово — &lt;a href="https://donate.torproject.org/" rel="noopener noreferrer"&gt;donate.torproject.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;С помощью данного браузера можно спрятаться и от Роскомнадзора. С момента введения повсеместного DPI на большинстве провайдеров в России сохранить в тайне доступ к сайтам на HTTPS стало гораздо сложнее. В популярных браузерах до сих пор отсутствует возможность использования протокола ECH, и, хотя Роскомнадзор не знает, какая именно информация передавалась между пользователем и сайтом, он видит, какой пользователь на какие домены обращался. Поэтому нами было принято решение разместить сайт на onion-сервере, обратиться к которому из обычного браузера нельзя. Таким образом пользователи даже случайно не смогут зайти на сайт и «засветиться» в логах DPI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Персональные данные
&lt;/h2&gt;

&lt;p&gt;Для того чтобы зарегистрироваться в системе, активисту не нужно предоставлять свои личные данные. Мы видим активистов только под их псевдонимами, не зная и не пытаясь узнать их реальные личности. У каждого активиста есть репутация, которая измеряется в баллах. Баллы выдаются по мере выполнения заданий и делают активиста более доверенным — ему можно поручать более секретные и серьёзные задания. Таким образом, если «товарищ майор» захочет узнать больше о секретных проектах, ему придется выполнять больше простых заданий — расклеивать листовки и рисовать протестные граффити. Пусть наконец сделает что-нибудь полезное!&lt;/p&gt;

&lt;p&gt;Для регистрации в системе штабов участнику необходимо придумать свой псевдоним (логин), достаточный по сложности пароль и коротко описать свои профессиональные навыки в свободной форме.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d2xaismkw2cjj0gvseu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d2xaismkw2cjj0gvseu.jpeg" alt="Страница регистрации сайта Штабов" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Реальных имён, электронных почт и телефонов не требуется. Все регистрации проходят дополнительную модерацию, после которой пользователю открывается доступ к полному функционалу системы. Модерация также защищает от флуда регистрациями. Поскольку в Tor клиенты анонимны, это ровно так же защищает от нас и самих злоумышленников, которые могут ботами заполнить миллионы анкет, а потом заспамить систему накрученными сообщениями. Чтобы это не повлияло на работу сайта, модераторы проверяют анкеты, отсеивая мусорные, размечают активистов по их профессиональным интересам (программисты, дизайнеры, юристы и т.д.) и только после этого пропускают их на сайт.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxpjx61vp3cysc1yzam2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxpjx61vp3cysc1yzam2.jpeg" alt="Страница экрана ожидания модерации сайта Штабов" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Поэтому, пожалуйста, отнеситесь с пониманием к тому, что нам нужно время на проверку ваших анкет. Мы ставим цель — 1-3 суток, но в случае атак оно может и затянуться.&lt;/p&gt;

&lt;h2&gt;
  
  
  Риски от инсайдеров
&lt;/h2&gt;

&lt;p&gt;Инсайдеры — это сотрудники штабов: координаторы, модераторы, программисты, системные администраторы и т.д. У них по роду деятельности есть дополнительный доступ к системе, которым могут воспользоваться злоумышленники. Мы доверяем нашим сотрудникам, но всё равно предпринимаем меры на случай их компрометации — ведь сотрудник может не только стать злоумышленником по своей воле (по идейным соображениям или быть подкупленным), но и быть взломанным (фишинг никто не отменял) или принужденным к сотрудничеству,  например, через давление на родственников.&lt;/p&gt;

&lt;p&gt;Для того чтобы защититься от угроз со стороны инсайдеров, мы предпринимаем специальные меры. Во-первых, мы всегда руководствуемся принципом минимальных привилегий — у наших сотрудников нет лишнего доступа, который не нужен им для выполнения прямых обязанностей. Например, у программистов есть доступ к репозиторию с кодом, но нет доступа к серверам. У тестеров есть доступ к тестовому окружению, но нет доступа к продакшну. Во-вторых, мы используем несколько периметров и для защиты от угроз инсайдеров. Скажем, даже если системные администраторы сделают дамп базы данных или скопируют все файлы из хранилища загруженных файлов, они не смогут их расшифровать.&lt;/p&gt;

&lt;h2&gt;
  
  
  Шифрование
&lt;/h2&gt;

&lt;p&gt;Все чувствительные поля базы данных и все загружаемые на сервер файлы зашифрованы. Мы используем симметричное шифрование с аутентификацией (AEAD), защищающее также от подмены зашифрованного содержимого. Ключи шифрования хранятся не в приложении, а в облачной системе управления ключами Cloud KMS от Google. Файлы шифруются при помощи envelope encryption — каждый файл шифруется своим эфемерным ключом, который уже шифруется KMS.&lt;/p&gt;

&lt;p&gt;У ключей Cloud KMS запрещён экспорт. Они хранятся в отдельном проекте Google Cloud, доступ к которому есть только у самых доверенных администраторов. Доступ к шифрованию и расшифрованию этими ключами выдан только сервис-аккаунтам, связанным с workload identity сервисов, которые должны работать с базой данных.&lt;/p&gt;

&lt;p&gt;Такой подход к шифрованию минимизирует периметр защиты данных. Например, даже если администраторы будут делать запросы к базе данных, они не смогут увидеть содержимое. То же самое касается и бэкапов. Более того, даже системы, делающие бэкапы, не должны расшифровывать данные. Всё бэкапится в зашифрованном виде, и для того, чтобы украсть данные, надо ещё и получить доступ к ключам KMS, что сильно усложняет задачу компрометации данных.&lt;/p&gt;

&lt;h2&gt;
  
  
  Атаки на приложение
&lt;/h2&gt;

&lt;p&gt;Если будет скомпрометировано само приложение через какую-нибудь техническую уязвимость, злоумышленник может получить доступ ко всему, к чему имеет доступ приложение. Это самый ценный актив системы, и успешная атака способна нанести очень большой ущерб. Чтобы его минимизировать, мы во-первых, не храним никаких персональных данных пользователей, чтобы даже в случае перехвата всех данных было максимально сложно идентифицировать активистов, а во-вторых мы стараемся минимизировать возможности злоумышленника закрепиться в системе.&lt;/p&gt;

&lt;p&gt;Поскольку серверы работают на GKE, они являются виртуальными машинами, которые периодически обновляются и заменяются новыми. В качестве базового образа используется COS (Container-optimized OS) от Google, представляющий из себя защищенную Linux-систему. Для аутентификации сервисов мы не используем экспортируемые JSON-ключи сервис-аккаунтов, которые можно украсть и использовать длительное время. Вместо этого применяется GKE Workload Identity, которая дает приложениям только временные токены со сроком жизни несколько минут.&lt;/p&gt;

&lt;h2&gt;
  
  
  Деплой
&lt;/h2&gt;

&lt;p&gt;Вся инфраструктура разделена на две части — доверенную и недоверенную. В недоверенной работает тестовое окружение, в котором нет никаких секретных данных. Оно используется для разработки и тестирования. В доверенной напротив — работает всё, у чего есть доступ к защищаемым данным.&lt;/p&gt;

&lt;p&gt;Сборкой кода приложения и контейнеров, занимаются специальные защищенные виртуальные машины (раннеры), работающие в изолированной от других проектов и инженеров среде. Доступ к проекту, в котором работают эти раннеры, есть у ограниченного количества доверенных инженеров, и то только на случай их поломки. У сервис-аккаунтов этих машин есть административный доступ к продакшну, что позволяет использовать подход gitops, в котором история всех изменений продакшна ведется в двух местах — в логах git и в аудит-логах Google Cloud, что позволит если не предотвратить атаки полностью, то хотя бы проследить их ретроактивно.&lt;/p&gt;

&lt;p&gt;Мы используем недоверенную среду для сборки кода из незащищенных веток GitLab. Это ветки, куда любой разработчик может делать свои коммиты для ревью или выкатки на тестовые серверы. Даже если разработчик закоммитит что-то вредоносное, что скомпрометирует сервер сборки, это не даст ему никакого доступа к продакшну. После ревью другим сотрудником и мержа ветки в основную продакшн-ветку, код собирается уже в доверенной среде и деплоится в прод.&lt;/p&gt;

&lt;p&gt;Для экономного расходования средств и достижения плотной загрузки серверов мы используем Kubernetes, а для системы сборки — собственное решение включения виртуальных машин раннеров только в тот момент, когда они нужны. Система управления раннерами также работает в защищенной среде.&lt;/p&gt;

&lt;h2&gt;
  
  
  DoS-атаки
&lt;/h2&gt;

&lt;p&gt;При запуске системы штабов команда рассчитывала, что, в отличие от открытого интернета, в Tor злоумышленникам будет накладно устраивать DoS-атаки. Но атакующие не заставили себя долго ждать, и наш мониторинг вскоре зафиксировал резкое увеличение нагрузки на серверы. Мы были готовы к фильтрации трафика на уровне HTTP, и поначалу этого было достаточно, но злоумышленники стали поступать хитрее — они создавали множество маршрутов и нагружали наш клиент Tor.&lt;/p&gt;

&lt;p&gt;Здесь надо немного объяснить, как работают onion-сайты. В отличие от обычного интернета, где клиенты подключаются к серверам напрямую, в Tor и клиенты, и серверы, подключаются к специальным узлам дискавери, которые "знакомят" их друг с другом, а после этого для передачи данных и те, и другие подключаются к узлам рандеву, устанавливают туннели с обеих сторон, и сервер рандеву замыкает их в единую цепь, по которой потом уже будет ходить обычный HTTP.&lt;/p&gt;

&lt;p&gt;В нашем случае злоумышленники отправляли огромное количество запросов на установку соединений, вынуждая наш сервер заниматься установкой соединений с серверами рандеву и сопутствующей дорогостоящей асимметричной криптографией. Далее они даже и не пытались ничего отправлять по этим туннелям, и атака даже не доходила до HTTP.&lt;/p&gt;

&lt;p&gt;Обычные средства защиты от DoS-атак типа определения источников и их временной блокировки в Tor невозможны, поскольку мы никак не можем идентифицировать клиентов. С этой целью было разработано специальное решение. Дело в том, что обычный onion-сервер не умеет масштабироваться. Когда запускается Tor, он подключается к сети и публикует дескриптор сервиса, указывающий на него единственного. Если запустить второй инстанс того же сервера, он затрет дескрипторы первого, и они вместе работать не смогут.&lt;/p&gt;

&lt;p&gt;В качестве решения проблемы мы используем onion balance - сторонний инструмент, который позволяет запустить несколько onion-серверов (каждый из которых работает на своём случайном onion-адресе), а затем загрузить из сети их дескрипторы, объединить в единый дескриптор и опубликовать уже в качестве дескриптора основного onion-сайта. Это позволяет распределять нагрузку на серверы и выдерживать пропорционально больший трафик.&lt;/p&gt;

&lt;p&gt;Так выглядит архитектура нашего решения:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnwk4oh63z604l6prcak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnwk4oh63z604l6prcak.png" alt="Архитектура сайта Штабов" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tor-balancer - это обёртка над onionbalance, которая обращается в наш кластер, получает список здоровых и активных инстансов тор-сервера, генерирует конфиг для onionbalance и запускает его. Если набор активных инстансов меняется (например, какой-то отключился, или новый включился), то конфиг регенерируется, и onionbalance перезапускается.&lt;/p&gt;

&lt;p&gt;Tor-frontend управляет обычным onion-сервером. Он генерирует случайный onion-адрес, запускает onion-сервер на этом адресе, ждёт, пока он успешно зарегистрируется и станет доступным в сети тор, а потом начинает отвечать на HTTP-запросы собственным onion-адресом. Именно обращаясь к этому HTTP, tor-balancer может узнать, какие индивидуальные onion-адреса надо использовать для компиляции общего большого дескриптора.&lt;/p&gt;

&lt;p&gt;Клиент устанавливает маршрут (circuit) с сервером один раз. Обычно это медленная и «дорогая» операция с точки зрения ресурсозатратности, а дальше может устанавливать любое количество логических соединений в рамках одного circuit — это уже быстро и дешево. Для борьбы с атаками настроено правило: если какой-то клиент внутри своего circuit установил большое количество соединений, такой circuit либо разрывается совсем или замедляется rate limit’ом на ingress-nginx. Это позволяет эффективно бороться с атаками. &lt;/p&gt;

&lt;p&gt;Таким образом мы распределяем нагрузку между onion-адресами с помощью «дискавери» дескрипторов и не даем злоумышленнику нагрузить один конкретный адрес и завалить систему.&lt;/p&gt;

&lt;p&gt;Вторым уровнем защиты от атак был отказ от конфиденциальности сервера. Поскольку у нас не дарк маркет и нам не надо прятать сервер (мы и так с гордостью говорим, чей он), серверу нет никакой нужды устанавливать тройное соединение с точкой рандеву. Вместо этого мы используем опцию Tor, которая позволяет нашему серверу устанавливать прямое соединение. Это позволило нам резко сократить объем асимметричной криптографии, который надо делать на сервере, и в несколько раз сократить нагрузку на сервер. Конфиденциальность клиентов при этом никак не страдает, а серверу — легче.&lt;/p&gt;

&lt;p&gt;Больше успешных DoS-атак на сервер не было.&lt;/p&gt;

&lt;h2&gt;
  
  
  Координаторы
&lt;/h2&gt;

&lt;p&gt;В системе штабов любой участник может написать сообщение координатору и получить ответ. Например, он может сообщить о выполненном задании или задать вопрос.&lt;/p&gt;

&lt;p&gt;Для работы координаторов мы используем специальную административную панель на базе фреймворка Django. Его функционала более чем достаточно для удобного разбора заявок на регистрацию, постановки задач и оценки их выполнения и общения с активистами в личном чате. Модераторы не видят реальных логинов пользователей, но, чтобы они могли как-то идентифицировать их, модераторы видят пользователей под еще одним уровнем псевдонимов — для них пользователи обозначены обезличенными порядковыми номерами. Для всех администраторов включено принудительное правило двухфакторной аутентификации, действует разграничение доступа по направлениям работы, и доступ включен только из-под служебного VPN. Ведется журнал действий, чтобы всегда можно было установить, какой сотрудник каким доступом пользовался.  &lt;/p&gt;

&lt;p&gt;Координаторы команды ставят задачи, следят за их исполнением, оценивают, поддерживают связь в личном чате с пользователем. Это требует человеческих ресурсов и создает проблему отсутствия быстрой обратной связи. Поэтому на базе платформы было решено запустить публичные групповые чаты для взаимодействия активистов друг с другом напрямую в рамках задачи. &lt;/p&gt;

&lt;h2&gt;
  
  
  Чаты
&lt;/h2&gt;

&lt;p&gt;По функционалу и дизайну, интерфейс чатов приближен к ленте мессенджера типа Telegram. В нем можно переключаться между чатами, читать, писать и удалять сообщения, отвечать на чужие сообщения и чистить историю.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlljhrbpfqfq1akhevop.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftlljhrbpfqfq1akhevop.jpeg" alt="Интерфейс страницы чатов сайта Штабов" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Чаты работают поверх вебсокетов внутри Tor. Каждое сообщение чата зашифровано при помощи Cloud KMS, и чтобы избежать избыточного количества запросов к KMS, в системе реализован локальный кеш расшифрованных сообщений в памяти приложения.&lt;/p&gt;

&lt;p&gt;Сообщения в чате можно удалять вручную, а по прошествии времени они удаляются автоматически.&lt;/p&gt;

&lt;p&gt;Для защиты чатов от спама сообщениями, в системе настроено ограничение на количество отправляемых сообщений в единицу времени, после которого сообщения перестанут приниматься. Мы также проводили нагрузочное тестирование чатов различными сценариями, чтобы убедиться, что сервер выдерживает расчетную нагрузку.&lt;/p&gt;

&lt;p&gt;Мы предприняли меры по защите пользователей чата от их идентификации по метаданным. Дело в том, что злоумышленники, имеющие доступ к СОРМ, видят, когда пользователи пользуются тором. Они не знают, что именно пользователи там делают, но сам факт скрыть довольно сложно. Они могут подключиться к популярному чату в системе штабов, отправить какое-то большое сообщение заведомо известной длины и по данным СОРМ посмотреть, какие из пользователей по всей России в тот же самый момент получили сообщение той же самой длины. Сигнал зашумлен, идентификация будет нечеткой, но после нескольких таких сообщений они смогут достоверно выяснить, кто из россиян сидел в это время в чате. Чтобы сильно затруднить возможность такой атаки, мы рандомизируем размер сообщений, отправляемых пользователям, и задержки времени между ними, чтобы размыть сигнал и сделать его ниже уровня шума.&lt;/p&gt;

&lt;h2&gt;
  
  
  Анонимность
&lt;/h2&gt;

&lt;p&gt;Самый глубокий уровень нашей обороны — это анонимность. Даже если все предыдущие уровни падут — серверы будут взломаны, координаторы куплены, а админы запытаны, — все, что получит злоумышленник, — это историю общения анонимов с анонимами, прямо не раскрывающую никаких идентифицирующих данных.&lt;/p&gt;

&lt;p&gt;Но даже без всякого взлома, общедоступные чаты также подразумевают наличие в них спамеров, провокаторов и прочих злоумышленников. Поэтому мы предпринимаем соответствующие меры защиты.&lt;/p&gt;

&lt;p&gt;Во-первых, за каждым чатом закрепляется модератор. Он видит чуть больше, чем обычный пользователь. Общую ленту, в которую падает поток всех сообщений, которые он модерирует, и ленту нарушений — жалобы от других пользователей. В этих административных чатах модератор имеет функционал удаления сообщений и блокировки пользователей - на определенное время или насовсем. При этом модератором не обязательно должен быть администратор с доступом в отдельную панель. Это обычный пользователь, зарегистрированный в личном кабинете, только с повышенными привилегиями.&lt;/p&gt;

&lt;p&gt;А во-вторых, чтобы «товарищ майор» не мог, долгое время наблюдая за чатом, собрать достаточно информации на пользователя, чтобы идентифицировать его по косвенным данным, мы ввели еще один принудительный уровень псевдонимизации. Каждому пользователю в чате назначается случайное имя, отличное от того, которое он использует для основного входа в систему — именно его и видят другие участники. Имена пользователей, с помощью которых участники штабов входят в личный кабинет, нигде не фигурируют. Мы заранее подготовили комбинации из прилагательных и существительных, чтобы покрыть всех участников забавными и уникальными именами. «Пятнистый Гиппогриф» или «Милый Кот» — такими видят пользователи друг друга. Доступна функция смены имени на другое, но тоже случайное. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes03y77hgufh4z0e4h6h.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fes03y77hgufh4z0e4h6h.jpeg" alt="Страница смены именип ользователя сайта Штабов" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Бот Федор, постоянно присутствующий в чате, напоминает участникам о правилах безопасности - например не рассказывать ничего про свою реальную жизнь или регулярно менять свой ник, чтобы разорвать связь с собой прошлым. Он выглядит, как обычный участник чата, берет случайное сообщение из своей базы знаний и отправляет в чат.&lt;/p&gt;

&lt;h2&gt;
  
  
  Загрузка файлов
&lt;/h2&gt;

&lt;p&gt;Мессенджер — это не только обмен короткими сообщениями, но и загрузка изображений. Мы позаботились о том, чтобы их метаданные автоматически очищались при загрузке в общий чат, и чтобы никто не мог узнать, кем, когда и где они были созданы.&lt;/p&gt;

&lt;p&gt;В качестве решения для очистки метаданных был выбран exiftool. Он поддерживает наибольшее количество форматов и прост в использовании. Однако важно обратить внимание на то, что exiftool использует множество кодеков, написанных на С — языке, на котором очень легко написать уязвимый код, дающий возможность удаленного исполнения кода злоумышленником.&lt;/p&gt;

&lt;p&gt;Чтобы скомпрометированный exiftool не привел к компрометации всего приложения, мы запускаем его отдельным микросервисом в изолированной песочнице, чтобы при загрузке вредоносного файла, хакер не мог бы получить доступ к основному сервису либо закрепиться на сервере и перехватывать файлы других пользователей. Мы запускаем этот микросервис в бессерверной среде исполнения Cloud Functions от Google, благодаря которой он живет короткое время и на уровне сети не имеет доступа к базе данных и другим микросервисам.&lt;/p&gt;

&lt;p&gt;В первый день работы чатов террористы тестеры подбросили нам настоящую zip-бомбу в виде картинки из миллионов пустых пикселей. Zip-бомба — это архив на миллиарды нулей которые сжали компрессором до очень компактного размера. Если получатель пытается его распаковать, у него просто напросто кончится или память, или диск, или и то, и другое. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;_decompression_bomb_check&lt;br&gt;
    raise DecompressionBombError(&lt;br&gt;
PIL.Image.DecompressionBombError: Image size (50625000000 pixels) exceeds limit of *N* pixels, could be decompression bomb DOS attack.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;К счастью, бомба так и не разорвалась - сработала защита в библиотеке. Но даже если бы она сработала, основному сервису это бы никак не повредило.&lt;/p&gt;

&lt;h2&gt;
  
  
  Заключение
&lt;/h2&gt;

&lt;p&gt;Мы создали уникальный инструмент, дающий возможность сторонникам и активистам в России более эффективно бороться с режимом, поддерживая связь между собой и не боясь быть раскрытыми. А оплачено все это за счет пожертвований наших активистов, за что им огромное спасибо! &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Поддержать работу IT-отдела Команды Навального:&lt;/strong&gt; &lt;a href="https://donate.fbk.info/it" rel="noopener noreferrer"&gt;https://donate.fbk.info/it&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Вы тоже можете присоединиться и поддержать Штабы:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Патреон Штабов:&lt;/strong&gt; &lt;a href="https://www.patreon.com/shtab_navalny" rel="noopener noreferrer"&gt;https://www.patreon.com/shtab_navalny&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Вы можете пожертвовать нам акции компаний через сайт DonateStock. Это быстро и удобно, к тому же площадка иногда удваивает сумму.&lt;/strong&gt; &lt;a href="https://donatestock.com/rikolto-ltd" rel="noopener noreferrer"&gt;https://donatestock.com/rikolto-ltd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Криптокошельки ФБК (ACF):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitcoin&lt;/strong&gt;&lt;br&gt;
3QzYvaRFY6bakFBW4YBRrzmwzTnfZcaA6E&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ethereum&lt;/strong&gt;&lt;br&gt;
0x314aC71aEB2feC4D60Cc50Eb46e64980a27F2680&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monero&lt;/strong&gt;&lt;br&gt;
42e1hkdsTHUUWSM24jVgLTH4MDJPMbNS1XDt7rK36dTBSKweohz9FSWKAAoqHLN9nSVgocnSnkR2AaLMWtsrmAoQGPdWSE1&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zcash (Z-адрес)&lt;/strong&gt;&lt;br&gt;
zs1l8ztrqpk0qyn2hyte3x9m568taz64jyc90ppfskylqgawxw7r3gq453yn6hk9swq2l0dq9yal0a&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;USDT (ВЕР-20)&lt;/strong&gt;&lt;br&gt;
0x9A4B20a7909Af03dd8B4f28A419840F9715E1F73&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Вы можете оформить корпоративное пожертвование, чтобы помочь Штабам Навального работать. Это можно сделать через платформу Benevity.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Benevity — программа для корпоративных пожертвований, которую используют более 900 компаний: Apple, Google, Twitter, Facebook и другие. Если вы работаете в крупной компании, скорее всего, на вашем корпоративном сайте есть раздел Employee Giving. Там в поисковой строке вбейте Anti-Corruption Foundation и введите сумму. Плюс системы Benevity в том, что иногда корпорации в несколько раз увеличивают размер сделанных через нее пожертвований.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>История защиты Умного голосования от DDoS-атак</title>
      <dc:creator>Navalny Team</dc:creator>
      <pubDate>Thu, 14 Sep 2023 12:49:41 +0000</pubDate>
      <link>https://dev.to/navalnyteam/istoriia-zashchity-umnogho-gholosovaniia-ot-ddos-atak-118h</link>
      <guid>https://dev.to/navalnyteam/istoriia-zashchity-umnogho-gholosovaniia-ot-ddos-atak-118h</guid>
      <description>&lt;p&gt;С самого начала своего существования Умное голосование каждый год подвергалось DDoS-атакам — в период со дня публикации рекомендаций до дня выборов. Первую атаку мы зафиксировали в 2019 году, аккурат за неделю до голосования. Разумеется, мы ее ждали. К тому времени на сайте уже была развернута защита от атак, и она с честью приняла на себя удар и так же с честью упала. Пожалуй, самая масштабная атака произошла в этом году, 2022-м, и с ней мы успешно справились. Миллиарды запросов к сайту и тысячи заблокированных адресов за сутки — такова была цена доступности Умного голосования на московских муниципальных выборах. В посте мы рассказываем об истории Умного голосования и опыте нашей команды по борьбе с DDoS: о методах атак, архитектуре и технологиях по защите.&lt;/p&gt;

&lt;p&gt;Чтобы понять некоторые из принятых технических решений, необходимо ненадолго заглянуть в прошлое. История Умного голосования восходит к 2018 году, когда Алексей Навальный впервые выдвинул идею консолидированного протестного голосования. К тому времени в России уже несколько лет работала система интернет-цензуры, осуществляемая Роскомнадзором. РКН рассылал списки заблокированных сайтов провайдерам, и те были обязаны блокировать к ним доступ.&lt;/p&gt;

&lt;p&gt;Разумеется, команда Навального понимала, что попытки заблокировать сайт будут предприняты примерно сразу после его открытия, а значит, нужны были такие решения по хостингу, какие РКН на том этапе технически не мог заблокировать. В то время на провайдерах еще не было массово установлено оборудование DPI, и блокировки осуществлялись в лучшем случае по IP-адресу. Соответственно, сайт нужно было размещать на IP-адресах, общих с другими важными сайтами, чтобы РКН не смог его заблокировать, не сломав пол-интернета. В ретроспективе это решение оказалось совершенно правильным, и сайт так никогда и не был заблокирован по IP.&lt;/p&gt;

&lt;p&gt;Итак, в начале 2019 года был запущен сайт на домене vote2019.appspot.com. Домен &lt;a href="http://appspot.com/" rel="noopener noreferrer"&gt;appspot.com&lt;/a&gt; принадлежит Google, и в нем автоматически создаются поддомены для всех проектов, использующих App Engine. Все сайты в &lt;a href="http://appspot.com/" rel="noopener noreferrer"&gt;appspot.com&lt;/a&gt; доступны по одним и тем же IP-адресам. Мы не рискнули тогда запускаться на отдельном домене для сайта, чтобы имя сайта прямо кричало, что оно работает на общей площадке и блокировать его нельзя.&lt;/p&gt;

&lt;p&gt;В то время уже существовали коммерческие системы защиты от DDoS, например, в России был популярен Qrator. Но именно тот факт, что фронтенд приложения должен был работать на Google App Engine, не позволял нам использовать готовые решения. Если бы мы спрятали сайт за одним из них, то сервис защиты от DDoS выделил бы сайту отдельный IP-адрес, и он был бы немедленно заблокирован Роскомнадзором.&lt;/p&gt;

&lt;p&gt;Достоинством App Engine является отличная масштабируемость — пока на сайт нагрузки нет, будет запущено всего 1-2 инстанса приложения. А если приедет большая нагрузка, то в течение нескольких секунд App Engine сможет поднять тысячи инстансов нашего приложения и переварить нагрузку. Учитывая все это, мы приняли решение строить собственную систему защиты от DDoS на базе App Engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Архитектура
&lt;/h2&gt;

&lt;p&gt;Чтобы не разориться на App Engine, мы решили не запускать на нем тяжеловесное Умное голосование целиком. Вместо этого мы стали гонять там легковесный кеширующий прокси-сервер на Go, который проверяет трафик на признаки атаки и либо отбивает запросы, либо отдает ответы из кеша, либо проксирует их в основное приложение. Go в первую очередь был выбран из-за того, что он компилируемый — в результате приложение и запускается быстро, и ресурсов тратит мало, что очень важно для быстрого масштабирования при росте нагрузки и для экономии денег соответственно.&lt;/p&gt;

&lt;p&gt;Поскольку во время атаки каждый инстанс прокси-сервера видит только малую долю всего трафика, принимать локальные решения о том, кого блокировать, а кого нет, качественно не получится — без полноты информации хороших решений, как известно, не принять. Поэтому был придуман отдельный бэкенд-сервис — «координатор», который собирает статистику со всех проксей, находит паттерны в трафике и посылает обратно нашу «политику партии» — кого мы баним, а кого нет.&lt;/p&gt;

&lt;p&gt;Координатор также предоставляет базовые административные функции — показ статистики, мониторинг, ручное управление политикой банов и т. д. Координатор записывает свое состояние и всю телеметрию в базу данных для того, чтобы ему не были страшны перезапуски.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmna6jr60hze99jo9c7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmna6jr60hze99jo9c7x.png" alt="Жирным выделен data plane — путь запросов пользователей (ну и, разумеется, DDoS). Нежирным — все остальное, то есть control и management plane.&amp;lt;br&amp;gt;
" width="800" height="637"&gt;&lt;/a&gt;&lt;em&gt;Жирным выделен data plane — путь запросов пользователей (ну и, разумеется, DDoS). Нежирным — все остальное, то есть control и management plane.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Анализ трафика
&lt;/h2&gt;

&lt;p&gt;Все прокси Front Shield ведут локальный реестр обслуженных запросов и раз в 2 секунды отправляют его координатору в HTTP-запросе. В ответ координатор возвращает текущий бан-лист — список правил, по которым должны баниться запросы.&lt;/p&gt;

&lt;p&gt;На стороне координатора все запросы анализируются, и если по каким-то IP-адресам обнаруживается подозрительная активность, то они попадают в бан на сутки. Анализ трафика делается асинхронно с приемом данных от инстансов прокси, поэтому решения могут чуть-чуть отставать от реального времени. На практике, если какой-то IP-адрес начинает резко слать много запросов, в бан он попадает в среднем через 5 секунд (2 секунды на доставку отчетов о трафике координатору, 1 секунда на анализ, 2 секунды на доставку бан-листов обратно на фронтенд).&lt;/p&gt;

&lt;h2&gt;
  
  
  Крещение огнем
&lt;/h2&gt;

&lt;p&gt;Итак, остается около недели до голосования 2019 года. Приходит алерт от мониторинга, что сайт Умного голосования недоступен. Мы смотрим в консоль Front Shield и видим небольшой и очень короткий всплеск трафика. Было даже странно, что система не справилась даже с такой скромной нагрузкой. Начинаем разбираться, и все быстро встает на свои места — консоль самого App Engine показывает 20 тысяч запросов в секунду. Просто инстансы Front Shield приняли все эти запросы и массово упали от нехватки памяти. App Engine увидел нагрузку и быстро добавил инстансов, но атакующие, видимо, убедились, что в силах положить сайт, и быстро остановили атаку, рассчитывая устроить то же самое в день голосования.&lt;/p&gt;

&lt;p&gt;Так началась борьба меча и щита. На каждую проблему, обнаруженную нападающими, мы придумывали решения. В данном случае была реализована техника load shedding, которая анализирует загрузку процесса и, если она приближается к своему пределу, начинает возвращать ошибки на раннем этапе обработки запроса, не дожидаясь падения. Это позволяет избежать каскадных аварий, когда падения одних инстансов увеличивают нагрузку на оставшиеся и дальше все разваливается, как домино.&lt;/p&gt;

&lt;p&gt;В день голосования 2019 года все прошло довольно спокойно — было несколько атак без всяких последствий. Леонид Волков тогда постил графики Front Shield у себя в соцсетях.&lt;/p&gt;

&lt;h2&gt;
  
  
  Выборы 2020
&lt;/h2&gt;

&lt;p&gt;После повсеместного внедрения ТСПУ на провайдерах особого смысла держать сайт Умного голосования живым не было. Именно поэтому наша команда выпустила дополнительные инструменты, такие как приложение под Android и iOS и &lt;a href="https://t.me/smartvotebot" rel="noopener noreferrer"&gt;телеграм-бот&lt;/a&gt;, в которых можно было узнать рекомендуемых кандидатов. Подробнее о технологиях для обхода блокировок, примененных в нашем приложении, можно почитать в нашем &lt;a href="https://dev.to/navalnyteam/rkn-protiv-prilozhieniia-navalnyi-borba-za-dostupnost-2gg6"&gt;другом нашем посте&lt;/a&gt;. Поскольку в мобильном приложении пользователям не надо запоминать доменное имя и оно не является брендом, мы могли позволить себе менять домены раз в минуту, и DDoS-атаки просто не успевали сфокусироваться на сервере, как он уже менялся.&lt;/p&gt;

&lt;p&gt;Веб-сайт же, разумеется, мы могли бы перенести на другой домен (не в &lt;a href="http://appspot.com/" rel="noopener noreferrer"&gt;appspot.com&lt;/a&gt;), но, во-первых, особого смысла с точки зрения блокировок в этом не было — любой сайт был бы во внесудебном порядке успешно заблокирован РКН, как только стал бы хоть немного заметен, во-вторых, скорее всего, если бы мы даже и закрылись за CloudFlare или Google Cloud Armor, как показывает практика, во время больших атак процентов 10 трафика все равно пролезает в бэкенд, и нам бы все равно приходилось тратить ресурсы на его обработку и загрузку CPU. Система, которая «знает» трафик, «знает» паттерны поведения пользователей, может быть гораздо более точной в обнаружении ботов и может защитить бэкенд гораздо эффективнее.&lt;/p&gt;

&lt;p&gt;Так и вышло: DDoS-атак на бэкенд приложения практически не было, а атаки на сайт мы успешно отбили — ничего особенно выдающегося в тот год не было.&lt;/p&gt;

&lt;h2&gt;
  
  
  Выборы 2021
&lt;/h2&gt;

&lt;p&gt;В этот год были очень крупные и важные выборы — избирались депутаты Госдумы и мы понимали, что атаки на Умное голосование достигнут беспрецедентных масштабов. Поэтому мы сделали еще одно крупное обновление — добавили еще один слой блокировок перед прокси Front Shield. У App Engine есть встроенный файрвол, который можно настраивать через API. Он позволяет вообще не платить за отбивание запросов с забаненных адресов — они даже не доходят до приложения. У этого решения есть один минус — жесткое ограничение на число правил файрвола: их всего 1000. Нам надо было придумать, как использовать их максимально эффективно. Мы заметили, что не все боты одинаково производительны — некоторые могут слать во много раз больше трафика, чем большинство других. Поэтому мы научили координатор собирать статистику: с каких IP-адресов идет больше всего трафика, который мы определяем как DDoS, те и заносить в файрвол. Но как только адрес попадал в файрвол, мы тут же «теряли» его из мониторинга — узнать, продолжает ли он отправлять запросы, а если да, то в каком количестве, становилось невозможно. Поэтому был реализован алгоритм, который со временем «забывает» старые грехи IP-адресов и замещает их в таблице новыми, самыми «злыми» на данный момент. Если разбаненный адрес продолжит слать трафик, то он быстро вернется в бан.&lt;/p&gt;

&lt;p&gt;В неделю перед голосованием, когда мы опубликовали рекомендации, злоумышленники не просто начали заливать Front Shield огромным трафиком, но и стали действовать креативно. Они искали изъяны в системе и били так, чтобы пробить все слои кеширования при помощи рандомизации и достать до бэкенда. У нас во время голосования (а оно в этот раз было трехдневным) дежурили команды разработчиков и бэкенда, и Front Shield. Какие-то атаки мы отражали, дорабатывая код Front Shield прямо на лету, — скажем, делали нормализацию запросов или регулировали параметры анализа статистики. Например, одним из паттернов атаки было использование какого-то гигантского ботнета, где каждый из IP-адресов слал относительно мало трафика, но суммарно выходило очень много, и нам пришлось увеличить интервал сбора статистики в памяти координатора, чтобы обнаруживать этих ботов на основании более длительного времени. Какие-то ошибки приходилось исправлять прямо на бэкенде. Например, мы обнаружили, что поиск адреса «а а а а а а а а а а а а а а а а а а а а а а» был очень дорогим, и при помощи небольшого исправления алгоритма быстро справились с проблемой.&lt;/p&gt;

&lt;p&gt;Надо отметить, что в основном атаки шли на бэкенд приложения, потому что сайт был к тому времени уже заблокирован, и его важность была сильно ниже, чем у приложения.&lt;/p&gt;

&lt;h2&gt;
  
  
  Выборы 2022
&lt;/h2&gt;

&lt;p&gt;Все началось с осени 2021 года. Кремль начал под ноль зачищать информационное пространство, и под нож попали социальные сети. Пожалуй, Instagram стал той их роковой ошибкой, в результате которой клиенты VPN прописались в телефонах у огромного количества даже технически не подкованных россиян, и внезапно оказалось, что важность сайта Умного голосования снова возросла.&lt;/p&gt;

&lt;p&gt;Вечером 10 сентября 2022 года, аккурат перед ключевым днем голосования, на сайт была запущена огромная DDoS-атака, которая продлилась более суток. Она продолжилась и после выборов, поэтому мы были вынуждены после окончания голосования совсем отключить Front Shield, чтобы не расходовать ресурсы зря. Миллиарды запросов к сайту и тысячи заблокированных адресов за сутки — такова была цена доступности Умного голосования на московских муниципальных выборах.&lt;/p&gt;

&lt;p&gt;К сожалению, из-за принципа работы файрвола App Engine мы так никогда и не узнаем, сколько трафика пришло на сайт, но во время кратковременных сбоев, о которых мы напишем ниже, на какое-то время мы переставали обновлять файрвол, и в пиках прокси обрабатывала до 250 тысяч запросов в секунду, а отдаваемый сервисом трафик достигал 100 гигабит в секунду. Скорее всего, реальный масштаб атаки был в несколько раз больше.&lt;/p&gt;

&lt;p&gt;Один из обычных методов борьбы с DDoS — территориальные ограничения. Например, если нас не интересует трафик из Южной Америки, то можно его сразу блокировать, а не пытаться даже обслуживать. В случае же Умного голосования так делать было нельзя, потому что в условиях блокировок всем пользователям из России приходилось пользоваться VPN, и страна, которую мы видели на фронтенде, была какой угодно, но только не Россией.&lt;/p&gt;

&lt;p&gt;Одной ошибкой, которую мы совершили, была отдача неверных заголовков кеширования. Дело в том, что перед тем, как запросы достигают приложения на App Engine, они обрабатываются Google Frontend, который имеет свой собственный слой кеширования. Если приложение своими заголовками Cache-Control позволяет кешировать ответы, то Google Frontend это запомнит и будет в будущем отдавать их из кэша. Приложение даже не догадывалось, что у нас есть такие гигантские источники запросов и не могло занести их в файрвол.&lt;/p&gt;

&lt;p&gt;Это продолжалось в течение нескольких часов. Поменяв заголовок Cache-Control с «public, max-age=120» на «private, max-age=120», мы решили проблему, и боты быстро улетели в бан. &lt;/p&gt;

&lt;p&gt;Был еще ночной «тест» со стороны нападающих накануне основной атаки в день голосования. Количество забаненных запросов держалось на уровне 20-30k rps, но иногда пробы достигали и 250 тысяч. Напомним, что мы считаем трафик уже после файрвола, то есть сколько там было до него — мы не знаем, но, скорее всего, в несколько раз больше.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpxjmotfaeegenaciu4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzpxjmotfaeegenaciu4p.png" alt="Requests graph" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Анализируя логи, мы поняли, что они отыскали один из эндпоинтов, на который у нас не была включена нормализация, и рандомизированными запросами смогли на несколько минут уложить бэкенд. Мы поспешно добавили в правила нормализацию для этого эндпоинта.&lt;/p&gt;

&lt;p&gt;В день голосования атака усилилась. Front Shield без остановки блокировал не менее 40 тысяч запросов в секунду (опять же, это то, что прошло через файрвол), а ко второй половине дня голосования трафик дорос до 100 тысяч запросов в секунду.&lt;/p&gt;

&lt;p&gt;Нам пришлось несколько раз добавлять памяти координатору из-за огромного количества данных, которые он должен был держать и обрабатывать. В мирное время eму нужно около 50 мегабайт, во время прошлых DDoS-атак он мог вырасти до гигабайта, а в этот раз, особенно под конец дня, ему понадобилось больше 20 гигов.&lt;/p&gt;

&lt;p&gt;В какой-то момент мы заметили, что координатор сломался. Оказалось, что он уже 45 минут не отвечает ни на какие запросы и находится в жестком дауне. Мы быстро обнаружили причину — из-за большого числа операций записи binlog базы данных переполнил диск, и все записи остановились. Как только мы решили эту проблему, координатор «проснулся» и принял первые за 45 минут отчеты от проксей — 200 тысяч запросов в секунду. Скорее всего, на протяжении этих 45 минут трафик на прокси плавно нарастал, поскольку никто не обновлял файрвол, и дорос до 200 тысяч.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8a4sd06cyr4uair0tdt1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8a4sd06cyr4uair0tdt1.png" alt="Requests graph - 2" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Причудливый узор во время пика трафика — это артефакт мониторинга, возникший из-за билинейной интерполяции точек и большого пропуска. Хотя уж больно он похож на кривую сложности &lt;a href="https://dfwk.ru/Dwarf_Fortress_Wiki:%D0%9E%D0%B1_%D0%B8%D0%B3%D1%80%D0%B5" rel="noopener noreferrer"&gt;Dwarf Fortress&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Когда голосование близилось к концу, App Engine показывал, что за последние сутки было обслужено более 2,4 миллиарда запросов, и это отражало только то, что прошло через файрвол и смогло добраться до прокси. Оценочно можно предположить, что трафика было в несколько раз больше. Скорее всего, около 10 миллиардов запросов за сутки.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vpuhn3d0yk2wyos36dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vpuhn3d0yk2wyos36dj.png" alt="Requests graph - 3" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Таким образом, нас защитило несколько слоев: файрвол отбивал запросы от самых крупных ботов, прокси Front Shield отбивала «длинный хвост» с более мелких, далее прокси из локального кэша отдавала часть ответов на популярные запросы, и все остальное уже шло в бэкенд. На бэкенде запросы встречала «батарея» nginx с дисковым кешем, ну и дальше уже само приложение. Такая многослойная котлета позволила нам сохранять устойчивость сервиса на протяжении всего времени работы сайта.&lt;/p&gt;

&lt;p&gt;За один только день голосования в бан-лист Front Shield было внесено более 30 тысяч IP-адресов. Злоумышленникам не удалось достичь своей цели от слова совсем. Все системы функционировали штатно — мы держали нагрузку, и сайт отлично работал, быстро и надежно. Также работали телеграм-бот и приложение, которые были полностью изолированы от сайта.&lt;/p&gt;

&lt;p&gt;А у нас в трекере висят тикеты — вынести все захардкоженные настройки в файлы конфигурации, написать документацию и выложить исходники Front Shield в общий доступ. Надеемся, у нас до них дойдут руки :)&lt;/p&gt;

&lt;p&gt;Вся эта работа была бы невозможна без вашей поддержки. Огромное спасибо!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Поддержать работу IT-отдела можно здесь:&lt;/strong&gt; &lt;a href="https://donate.fbk.info/it" rel="noopener noreferrer"&gt;https://donate.fbk.info/it&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Этот пост был опубликован на портале Habr 14 сентября 2022 года, а на следующий день скрыт администрацией сайта. В поддержке сослались на особый порядок блокировки «в отношении материалов от организаций, признанных экстремистскими» и на «инициирование политических дискуссий». Мы выступаем против ограничения свободы распространения информации. Habr мы рассматривали как площадку для обмена опытом и для отчета о работе нашей технической команды.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ddos</category>
      <category>network</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>РКН против приложения «Навальный»: борьба за доступность</title>
      <dc:creator>Navalny Team</dc:creator>
      <pubDate>Thu, 14 Sep 2023 10:53:24 +0000</pubDate>
      <link>https://dev.to/navalnyteam/rkn-protiv-prilozhieniia-navalnyi-borba-za-dostupnost-2gg6</link>
      <guid>https://dev.to/navalnyteam/rkn-protiv-prilozhieniia-navalnyi-borba-za-dostupnost-2gg6</guid>
      <description>&lt;p&gt;2021 год в России запомнится беспрецедентной волной судебных и внесудебных блокировок ресурсов средствами DPI. 26 июля Роскомнадзор &lt;a href="https://t.me/leonid_volkov/2684" rel="noopener noreferrer"&gt;заблокировал&lt;/a&gt; множество наших ресурсов: блог Навального &lt;a href="//navalny.com"&gt;navalny.com&lt;/a&gt;, сайт сети региональных штабов &lt;a href="//shtab.navalny.com"&gt;shtab.navalny.com&lt;/a&gt;, сайт Фонда борьбы с коррупцией &lt;a href="//fbk.info"&gt;fbk.info&lt;/a&gt; и другие. Под блокировки попали даже сайты проектов «РосЯма» и «РосЖКХ». Все перечисленные ресурсы были заблокированы на основании требования Генеральной прокуратуры РФ как содержащие призывы к массовым беспорядкам, осуществлению экстремистской деятельности, участию в массовых (публичных) мероприятиях, проводимых с нарушением установленного порядка, и информационные материалы организаций, деятельность которых признана нежелательной. Сайт проекта «&lt;a href="https://votesmart.appspot.com/" rel="noopener noreferrer"&gt;Умное голосование&lt;/a&gt;» заблокировали за неделю до выборов — 6 сентября. С конца августа РКН развернул настоящую войну с приложением «Навальный» и чуть не сломал весь российский интернет.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;В этом посте мы расскажем о противостоянии, которое развернулось между нашей командой и РКН летом — осенью 2021 года: о технологиях по обходу блокировок, о собственной системе мониторинга, о том, как нам удалось «обучить» РКН регулярным выражениям. Расскажем, как РКН был вынужден пойти на крайние меры, попытавшись заблокировать публичные DNS в России, и каких результатов нам удалось достичь.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Введение
&lt;/h2&gt;

&lt;p&gt;Наша команда рассматривала сценарий блокировок заранее. Еще в 2020 году было решено использовать мобильное приложение как основной инструмент доставки до пользователей постов в блоге и рекомендаций «Умного голосования».&lt;/p&gt;

&lt;p&gt;С момента введения повсеместного DPI в России за доступность сайтов стало бороться все сложнее. Дело в том, что протокол TLS не предусматривает шифрование изначального «рукопожатия» между клиентом и сервером. Когда во всем мире обнаружился дефицит IPv4-адресов, виртуальный хостинг (когда несколько разных доменов работают на одном IPv4-адресе) пришлось широко использовать и в TLS. Клиент во время рукопожатия передает доменное имя сайта (SNI — Server Name Indication), а сервер в ответ отправляет сертификат для этого домена. Этим и пользуются разработчики DPI, позволяя различать трафик, идущий на один и тот же адрес, по SNI и блокируя только тот, что им нужно. Во время разработки стандарта ESNI (Encrypted SNI, позволяющего шифровать заголовок SNI) обнаружились неустранимые проблемы, и &lt;a href="https://blog.cloudflare.com/encrypted-client-hello/" rel="noopener noreferrer"&gt;на замену ESNI пришел протокол ECH&lt;/a&gt; (Encrypted Client Hello), в котором шифруется все рукопожатие со стороны клиента. &lt;/p&gt;

&lt;p&gt;Стандарт ECH еще не стал всеобщим. В &lt;a href="https://www.ietf.org/" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; он находится в фазе активной разработки в статусе draft. Последнее обновление &lt;a href="https://dev.to%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%20%D1%81%20%D0%BE%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC%20%D1%81%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82%D0%B0"&gt;документа с описанием стандарта&lt;/a&gt; было как раз в августе 2021 года. Следовательно, поддержки этого протокола на конечных клиентах (браузерах) не предусматривалось. Мы понимали, что успешно скрыть домен в HTTPS-трафике от РКН нам не удастся. Поддержка доступности web-сайта стала весьма проблематичной задачей. &lt;/p&gt;

&lt;p&gt;Когда требование Генпрокуратуры о блокировке было исполнено, сетевое сообщество начало организовывать прокси до заблокированных ресурсов команды Навального, однако на практике это оказалось неэффективным. Любой адрес, замеченный РКН, рано или поздно попадал под внесудебную блокировку и моментально становился недоступным. Было понятно, что любые публично распространенные прокси, вне зависимости от доменного имени, будут успешно заблокированы. &lt;/p&gt;

&lt;p&gt;После вступления блокировок в силу мы первым делом провели простой эксперимент: переключили домены наших ресурсов на IP-адреса AppEngine. Были возможны три варианта: либо блокировка полностью отключилась бы (если айпишники AppEngine находились в белом списке у РКН), либо весь AppEngine в российском сегменте интернета оказался бы заблокированным, либо осталась бы только блокировка по DPI. Результаты теста подтвердили наши ожидания — доступность не возросла. Надо отметить, что РКН хорошо подготовился и начиная еще с 2016 года явно обеспечил покрытие DPI на большинстве провайдеров России, в том числе DPI «по сигнатурам» (он же ТСПУ).&lt;/p&gt;

&lt;h2&gt;
  
  
  Система мониторинга
&lt;/h2&gt;

&lt;p&gt;Здесь стоит рассказать о средствах мониторинга, с помощью которых мы проверяли доступность наши ресурсов.&lt;/p&gt;

&lt;p&gt;Блокировки через «технические средства противодействия угрозам» (ТСПУ) нельзя отследить традиционными методами, с помощью реестра РКН или так называемых «&lt;a href="https://vigruzki.rkn.gov.ru/auto-delta/" rel="noopener noreferrer"&gt;Дельт&lt;/a&gt;». Нет никакого подлинного списка ресурсов, которые блокировались на уровне ТСПУ. Блокировки приобрели не подотчетный и непрозрачный характер. Поэтому, чтобы отслеживать работоспособность ресурсов, пришлось разработать систему отслеживания на уровне провайдеров РФ. &lt;/p&gt;

&lt;p&gt;Для реализации такой системы мы приобрели комплекты Raspberry Pi 3B. Наши читатели наверняка знают, что мы фанаты «Малинок», и в этот раз выбор снова пал на них. Эти микрокомпьютеры обладают полноценной Linux-системой на борту, а также оборудованы сетевой картой с портом RJ45, дешевы и просты в обслуживании.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0lbyxxykctwt97rga5j.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh0lbyxxykctwt97rga5j.jpeg" alt="Модель RPi" width="800" height="600"&gt;&lt;/a&gt;&lt;em&gt;Модель RPi&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Мы подготовили комплекты Pi для волонтеров, которые согласились установить у себя эти импровизированные «зонды». В каждом из них была скомпилирована ОС на базе Ubuntu 20.04 — так, чтобы волонтеру было достаточно просто подключить Raspberry Pi в сеть. Малинки совершали попытки обращения к нужным ресурсам и отслеживали статус, отсылая его нам.&lt;/p&gt;

&lt;p&gt;Для безопасности мы скрыли весь служебный трафик Pi в VPN-сеть. Оставили только GET-запросы и скачивание пакетов при обновлении.&lt;/p&gt;

&lt;p&gt;Мы постарались охватить своей сетью провайдеров по всей стране. В первую очередь, конечно, нас интересовали провайдеры с ТСПУ, но в связи с тем, что нет никаких официальных публичных списков провайдеров с этим «черным ящиком» на борту, мы пытались придерживаться самых крупных — большой тройки, Ростелекома, Дом.ру и подобных. Сеть составляли где-то 50% провайдеров с ТСПУ и 50% без. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6tu5uyg69ck7hrnsqss.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6tu5uyg69ck7hrnsqss.jpg" alt="Пример download показателей обращения к ресурсу системы мониторинга" width="800" height="496"&gt;&lt;/a&gt;&lt;em&gt;Пример download показателей обращения к ресурсу системы мониторинга&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Для отправки запросов, хранения полученных данных и алертов мы воспользовались Zabbix. Чтобы отслеживать блокировки сайтов, использовалась встроенная функция «веб-агента» и кастомные скрипты, исполняемые на зондах.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1stzc5b1pzs4n04kz63n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1stzc5b1pzs4n04kz63n.jpg" alt="Дашборд со сканерами системы мониторинга доступности" width="800" height="177"&gt;&lt;/a&gt;&lt;em&gt;Дашборд со сканерами системы мониторинга доступности&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Для обработки и вывода данных использовалась Grafana. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuq2kdlz5199perm73ja5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuq2kdlz5199perm73ja5.jpg" alt="Дашборд с гистограммой системы мониторинга доступности | Grafana" width="800" height="400"&gt;&lt;/a&gt;&lt;em&gt;Дашборд с гистограммой системы мониторинга доступности | Grafana&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;В дополнение был написан API-микросервис, которому мы дали имя «Navalny Hello». Его основной задачей было выдавать по любому домену информацию о блокировке. Сервис работал на основе Pi-сканеров и выдавал скоринг для каждого запрашиваемого адреса. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawt2z1lubm89xx0be6yh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawt2z1lubm89xx0be6yh.jpeg" alt="_Пример ответа сервиса «Navalny Hello» по запросу доступности ya.ru_" width="800" height="123"&gt;&lt;/a&gt;&lt;em&gt;Пример ответа сервиса «Navalny Hello» по запросу доступности ya.ru&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Требования к приложению
&lt;/h2&gt;

&lt;p&gt;В приложении «Навальный» важнее всего было обеспечить доступность блога и проекта «Умное голосование». Мы публикуем свои рекомендации по голосованию за три дня до выборов, чтобы власти не могли снять кандидатов, за которых мы советуем отдать голос. При этом основная функция приложения — поиск кандидата по адресу (пользователь вбивает свой адрес и получает конкретную рекомендацию). Таким образом, залить список кандидатов прямо в приложение через стандартное обновление было проблематично, — тем более что обновление в Google Play и Apple Store могут рассматривать от нескольких суток до нескольких недель, и такого запаса времени у нас просто не было. &lt;/p&gt;

&lt;p&gt;Учитывая необходимость постоянной синхронизации приложения с адресами нашего бэкенда, мы выделили в основных требованиях несколько пунктов:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;защита от блокировки IP-адресов;&lt;/li&gt;
&lt;li&gt;защита от блокировки доменных имен;&lt;/li&gt;
&lt;li&gt;обход DPI-средств провайдеров.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Был подготовлен специальный протокол, который поддерживал технологии DoH-резолвинга и SNI-фейкинга. С помощью закодированного дискавери, представляющего собой JSON-структуру с электронной подписью для защиты от replay-атак, мы смогли «научить» приложение обнаруживать через публичные DNS актуальные адреса бэкенда для обновления контента. Когда РКН банил наш адрес, мы создавали новый, обновляли дискавери, контролировали значение TTL записи, чтобы избежать ненужного кэширования, и таким образом перед очередным запросом пользователя сообщали для него новый маршрут обращения. К моменту блокировки сайтов приложение работало в Google Play и Apple Store с данной версией протокола.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ротация «на опережение»
&lt;/h2&gt;

&lt;p&gt;В «мирное время» секретные механизмы предусмотрительно не были включены. Специалисты РКН не совершали никаких дополнительных действий после блокировок сайтов и только 20 августа &lt;a href="https://t.me/teamnavalny/7957" rel="noopener noreferrer"&gt;перешли в наступление&lt;/a&gt; и предприняли первые попытки заблокировать адреса приложения. Чтобы не раскрывать все наши возможности до дня выборов, мы решили поиграть в «догонялки» с РКН — обновляя дискавери и доставляя пользователю необходимые адреса. &lt;/p&gt;

&lt;p&gt;По первым наблюдениям, РКН осуществлял мониторинг чуть ли не вручную. Мы запустили скрипт, который генерил доменные адреса третьего уровня, например 1np13q836n.rkngov.com, готовил для них необходимый бекенд и отдавал в дискавери. Согласно нашему мониторингу, каждый новый адрес третьего уровня попадал в реестр и разливался в качестве правила по провайдерам в течение 13 минут. Когда в РКН удостоверились, что мы осуществляем ротацию доменов исключительно третьего уровня, они наконец решились блокировать всю вторую зону целиком. &lt;/p&gt;

&lt;p&gt;Мы вернулись к варианту хостинга на AppEngine. Каждый проект в AppEngine автоматически получает служебное доменное имя, соответствующее идентификатору проекта. Скажем, проект navalnyapp был доступен на домене navalnyapp.appspot.com. Однако в документации на AppEngine мы обнаружили, что сайты получают и другие служебные домены, например &amp;lt;версия&amp;gt;-dot-&amp;lt;проект&amp;gt;.appspot.com. Если в качестве версии указать любую строку, для которой даже нет версии приложения, то осуществляется fallback на основную версию. В итоге адрес для ротации в дискавери был заменен на *-dot-navalnyapp.appspot.com. Основная задумка заключалась в том, что в данном случае нам не обязательно было «заранее готовить» новый адрес. Достаточно было дописать перед «dot» любое слово, и такие адреса моментально мапились на наш проект. РКН стал получать на своих сканерах «адреса-приветы» от нашей команды — &lt;code&gt;putinprivet-dot-navalnyapp.appspot.com&lt;/code&gt;, &lt;code&gt;putinvor-dot-navalnyapp.appspot.com&lt;/code&gt;, &lt;code&gt;123putinuhodi-dot-navalnyapp.appspot.com&lt;/code&gt;, 321putin… и т.д.&lt;/p&gt;

&lt;p&gt;Вы можете проверить это сами: придумайте любой аналогичный адрес, вбейте его в браузер — и обнаружите на корневом адресе блог Навального. Впрочем, сейчас все эти адреса заблокированы. &lt;/p&gt;

&lt;p&gt;Подобным образом мы могли осуществлять ротацию в любом объеме и в любое время. На сканерах своего мониторинга мы мгновенно увидели 100% доступность, и РКН встал перед выбором: либо обучить свой блокирующий софт регуляркам, либо заблокировать всю зону &lt;a href="http://appspot.com/" rel="noopener noreferrer"&gt;appspot.com&lt;/a&gt; целиком.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft18gmn4t8yhyeuck3nat.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft18gmn4t8yhyeuck3nat.jpg" alt="Дашборд с показателями доступности приложения при ротации служебных доменов -dot-navalnyapp.appspot.com&amp;lt;br&amp;gt;
" width="800" height="415"&gt;&lt;/a&gt;&lt;em&gt;Дашборд с показателями доступности приложения при ротации служебных доменов -dot-navalnyapp.appspot.com&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Интересно заметить, что на любой «нестандартный» ход РКН реагировал с предсказуемой задержкой. Если мы что-то меняли в будни, условно говоря, с 9 до 17, то реакция следовала в течение часа. А если дожидались вечера (лучше, конечно, вечера пятницы), то 100% доступность сохранялась до 9 утра следующего рабочего дня. Видимо, у РКН была дежурная смена юных падаванов, которые делали какие-то совсем простые вещи, и настоящие специалисты, доступные только в рабочее время.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Пока РКН «учился в регулярки», мы смогли выиграть время и апгрейднуть скрипт ротации наших адресов. В связи с тем, что любые из них блокировались сразу по второй зоне целиком, мы написали обновление. Скрипт заблаговременно и массово регистрировал домены второго уровня у одного из хостеров. Затем регистрировал их в CloudFlare, добавлял в качестве кастомного домена к нашему проекту в AppEngine (это было сделано для того, чтобы исключить блокировки на тех провайдерах, которые не умели в DPI), ждал выпуска сертификата гуглом и каждые n минут подсовывал эти домены приложению, предварительно проверяя через наш вышеупомянутый сервис «Navalny Hello», не заблокированы ли они. Таким образом мы могли переиспользовать адрес, если РКН со временем внезапно решил бы его «разблокировать». Благодаря непрерывному мониторингу, ускоряя или замедляя скрипт, мы могли определить, за какое время РКН замечал новые адреса второго уровня. В очередной раз на сканеры нашего противника посыпались «адреса-приветы» самых дешевых доменных зон, например: &lt;code&gt;www.roskomnadzoruhodi.website&lt;/code&gt;, &lt;code&gt;www.svobodypoltzakluchennym.xyz&lt;/code&gt;, &lt;code&gt;www.rknidiotdohni.fun&lt;/code&gt;, &lt;code&gt;www.privetput1nu.online&lt;/code&gt;, &lt;code&gt;www.rknprivet.club&lt;/code&gt; и т.д.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Вы можете проверить — эти адреса и сейчас заблокированы у провайдеров с ТСПУ.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CDN вступают в борьбу
&lt;/h2&gt;

&lt;p&gt;Мы в очередной раз выиграли время. Но предварительная покупка доменов, пускай даже в самых дешевых доменных зонах, в долгосрочной перспективе и в больших объемах требует затрат, а от идентификации адреса до распространения блокировки на провайдерах, согласно нашим сканерам, стало проходить не больше минуты. Так что мы решили обратиться за адресами к известным CDN-провайдерам, таким как Bunny, Fastly, Amazon.&lt;/p&gt;

&lt;p&gt;Идея заключалась в том, что РКН не решится целиком блокировать доменную зону второго уровня, предоставляемую публично известными CDN-провайдерами, и мы сможем относительно дешево проксировать трафик на бэкенд с их помощью через дискавери приложения. Пошаманив с настройками кэширования, мы запустили скрипт ротации доменов с CDN от Bunny.&lt;/p&gt;

&lt;p&gt;К моменту, когда мы израсходовали более 6000 подобных адресов, РКН также провел несколько тестов и все-таки решился на полную блокировку b-cdn.net на ТСПУ. Практически сразу мы получили письмо от основателя Bunny о том, что они вынуждены приостановить действие нашей учетной записи, поскольку это негативно сказывается на доступности их сети. Вероятнее всего, блокировкой РКН был задеты крупные пользователи Bunny в России. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsc5i6iqov3l7hta28ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsc5i6iqov3l7hta28ik.png" alt="Письмо от основателя Bunny c объяснением причин блокировки аккаунта" width="800" height="300"&gt;&lt;/a&gt;&lt;em&gt;Письмо от основателя Bunny c объяснением причин блокировки аккаунта&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;В качестве резервного варианта мы переключили ротацию на Fastly CDN. Это работало нормально, и на этот раз РКН уже не решался блокировать весь второй уровень более известного CDN. Но из-за ограничений по количеству создаваемых зон на аккаунт (мы не всегда могли освобождать старые зоны, и из-за багов в приложении в некоторых случаях приходилось их «копить», чтобы устройства, получившие старую запись дискавери, могли их использовать неограниченно долго) в конечном счете мы перешли на адреса Amazon. Довольно легко получилось арендовать на старте квоту со значением около 10 тысяч адресов в доменной зоне cloudfront.net. &lt;/p&gt;

&lt;p&gt;На этот раз мы наконец создали очевидную проблему для РКН. Адреса пачками и довольно быстро готовились по ранее опробованному скрипту. Наши сканеры зафиксировали рост доступности.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j5f77b8kae3qgfq4rpo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j5f77b8kae3qgfq4rpo.jpg" alt="Доступность адресов CloudFront при использовании в ротации приложения «Навальный»&amp;lt;br&amp;gt;
" width="800" height="403"&gt;&lt;/a&gt;&lt;em&gt;Доступность адресов CloudFront при использовании в ротации приложения «Навальный»&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS под угрозой. Domain Fronting, DOH-резолвинг и NewNode
&lt;/h2&gt;

&lt;p&gt;РКН оставалось разве что блокировать Amazon целиком. И в этом случае у нашего приложения в запасе еще оставался секретный механизм SNI-фейкинга. Именно в этот момент в РКН впервые задумались о запрете на использование публичных систем доменных имен и начали готовить российских провайдеров к отключению Google и CloudFlare DNS, рассылая соответствующие письма с требованиями.&lt;/p&gt;

&lt;p&gt;В РКН даже провели тесты кратковременной блокировки DNS, что и зафиксировал наш мониторинг и пользователи российского сегмента интернета:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9cqtx83e0w0t80rnwin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9cqtx83e0w0t80rnwin.png" alt="https://twitter.com/ShieldNav/status/1435692644676603906?" width="800" height="922"&gt;&lt;/a&gt;&lt;em&gt;&lt;a href="https://twitter.com/ShieldNav/status/1435692644676603906?" rel="noopener noreferrer"&gt;https://twitter.com/ShieldNav/status/1435692644676603906?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Мы были готовы и к такому развитию событий. Все это время параллельно работали над дополнительными обновлениями по обходу блокировок для нашего приложения. Мы полагали, что  на один день забанить Tor ради большой цели для РКН, в принципе, не будет проблемой. Конечно, у этого был бы медийный эффект, но, вероятнее всего, кроме гиков, этого бы почти никто не заметил. Так что идею использовать Tor мы отложили. Была подготовлена имплементация технологии Domain Fronting в качестве дополнительного инструментария, которым мы могли аналогичным образом управлять на стороне клиента через дискавери. А также DOH-резолвинга на случай полной блокировки DNS в России и решения проблемы обновления самого дискавери. &lt;/p&gt;

&lt;p&gt;Идея была проста. Вышеупомянутый &lt;a href="http://navalnyapp.appspot.com/" rel="noopener noreferrer"&gt;navalnyapp.appspot.com&lt;/a&gt;, (а вообще говоря, любой &lt;code&gt;*.appspot.com&lt;/code&gt;) можно фронтить в любой &lt;code&gt;${garbage}.appspot.com&lt;/code&gt;. Мы также нашли возможность фронтинга еще через пару популярных ресурсов, которые РКН вряд ли решился бы полностью отключить в России (мы намеренно не хотели бы раскрывать их в этом посте). Добавили этот функционал в приложение. А в качестве DoH-резолвинга расширили параметры нашего дискавери до получения записей с нескольких storage-провайдеров, таких как Google Cloud Storage и Amazon S3, на случай блокировки Google и Cloudflare DNS.&lt;/p&gt;

&lt;p&gt;Помимо всего прочего, в приложении закладывались и альтернативные, весьма экспериментальные способы обхода блокировок, включая использование механизмов P2P-обмена данными. В конце августа  нам удалось сделать экспериментальную сборку приложения с внедренным &lt;a href="https://github.com/clostra/newnode" rel="noopener noreferrer"&gt;SDK под названием NewNode&lt;/a&gt;. NewNode, а также экспериментальный мессенджер FireSide — продолжение исследовательских работ, которую ведет команда, известная другим инновационным мессенджером FireChat. Они же разработчики известного протокола BitTorrent. По задумке, эта штука должна обеспечивать связность даже при полном отключении интернета —  просто передавая данные от клиента к клиенту через встроенные в мобильные телефоны модули беспроводной связи Bluetooth и Wi-Fi. SDK NewNode специально создан, чтоб научить мобильные приложения использовать для передачи данных встроенные механизмы BitTorrent, &lt;a href="https://en.wikipedia.org/wiki/LEDBAT" rel="noopener noreferrer"&gt;LEDBAT&lt;/a&gt; и передачу данных от устройства к устройству (Device-to-Device Communications —  D2D). Эта тема, пожалуй, заслуживает отдельной статьи, но если коротко объяснять принцип работы, то для разработчика SDK выглядит как прокси, который использует собственный транспорт для передачи данных: сильно переделанный DHT в качестве транспорта, D2D для организации каналов в случае недоступности интернет-ресурса и LEDBAT, который оркеструет все доступные способы коммуникации, выбирая самый эффективный в данный момент времени.&lt;/p&gt;

&lt;p&gt;В постановлении РКН о блокировке публичных DNS для провайдеров предполагалась также блокировка DNS-over-UDP. Именно этот сервис использует библиотека NewNode, что только укрепляет нас в мысли о направленности данных действий исключительно против нашего приложения. Примерно в то же время &lt;a href="https://github.com/TeamNewPipe/NewPipe/issues/7114" rel="noopener noreferrer"&gt;была замечена&lt;/a&gt; и блокировка приложения &lt;a href="https://newpipe.net/" rel="noopener noreferrer"&gt;NewPipe&lt;/a&gt; в части YouTube-клиента по TLS-отпечаткам. РКН, по всей видимости, проводил предварительные тесты (или перепутал NewNode или NewPipe? :))&lt;/p&gt;

&lt;p&gt;Последняя сборка приложения «Навальный» содержит NewNode и потенциально будет работать (в крупных городах с большой плотностью населения) даже при полном отключении интернета.&lt;/p&gt;

&lt;h2&gt;
  
  
  Заключение
&lt;/h2&gt;

&lt;p&gt;Паралельно с ежеминутными блокировками, РКН продолжал отправлять запросы в Apple и Google с требованиями удалить приложение «Навальный». Письмами дело не ограничилось — представителей Apple и Google &lt;a href="https://meduza.io/news/2021/09/15/k-nim-ochen-mnogo-voprosov-sovet-federatsii-vyzval-predstaviteley-google-i-apple-na-zasedanie-komissii-po-zaschite-suvereniteta" rel="noopener noreferrer"&gt;вызвали&lt;/a&gt; в Совет Федерации на заседание комиссии по защите суверенитета: неисполнение требований РКН было воспринято как иностранное вмешательство в выборы. В московский офис Google незадолго до выборов &lt;a href="https://www.bbc.com/russian/news-58547764" rel="noopener noreferrer"&gt;приходили силовики&lt;/a&gt;. Дошло и до прямого шантажа — по данным издания Bloomberg, российским сотрудникам Google &lt;a href="https://www.bloomberg.com/news/articles/2021-09-16/russia-targets-google-apple-in-crackdown-before-elections" rel="noopener noreferrer"&gt;угрожали тюрьмой&lt;/a&gt;, если компания не исполнит требования властей. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0btziqg2urz63bpkkfve.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0btziqg2urz63bpkkfve.jpeg" alt="Письмо от РКН с запросом удаления приложения «Навальный» в App Store service&amp;lt;br&amp;gt;
" width="800" height="444"&gt;&lt;/a&gt;&lt;em&gt;Письмо от РКН с запросом удаления приложения «Навальный» в App Store service&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Само собой, все эти процессы усложняли ревью любых наших обновлений. Рассмотрение зависало на несколько дней. Последние обновления, c domain-fronting и DoH-резолвингом, мы отправили 10 сентября. Очевидно, РКН рассматривал два сценария: либо приложение удастся удалить, либо придется ломать половину российского интернета, отключив публичные DNS. К счастью для РКН, им удалось добиться первого сценария. В конце концов, после почти недельного ожидания, наши обновления были подтверждены магазинами приложений, но одновременно с этим их моментально &lt;a href="https://t.me/leonid_volkov/2819" rel="noopener noreferrer"&gt;удалили из магазинов&lt;/a&gt;. Это случилось утром 17 сентября, в первый день выборов. А в ночь на 18 сентября Павел Дуров, сославшись на действия Apple и Google, &lt;a href="https://t.me/durov_russia/32" rel="noopener noreferrer"&gt;заблокировал&lt;/a&gt; &lt;a href="https://t.me/smartvotebot" rel="noopener noreferrer"&gt;телеграм-бота&lt;/a&gt; «Умного голосования». &lt;/p&gt;

&lt;p&gt;Наша команда распространяла списки с рекомендациями кандидатов через &lt;a href="https://github.com/smartvotedocs/votesmart2021" rel="noopener noreferrer"&gt;репозиторий в Github&lt;/a&gt;, &lt;a href="https://docs.google.com/document/u/2/d/e/2PACX-1vSe2exjjq0o246AaIiUGPN48SAevbeOke09ZvMrwqcfVDk5Lz-MnHy3temxMSOBJY3Kfo4pjvgNbPIS/pub" rel="noopener noreferrer"&gt;Google Docs&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=OVPorDqxE28" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; и &lt;a href="https://github.com/smartvotedocs/votesmart2021/releases/tag/android-app" rel="noopener noreferrer"&gt;APK-сборку Android&lt;/a&gt; c последними алгоритмами обхода блокировок. Аккурат перед днем голосования мы успели закинуть в магазины приложений и последнее обновление с обычным PDF-файлом, где содержался список рекомендованных кандидатов. Так что те немногие пользователи, которые все-таки успели обновить или загрузить сборку, могли потрясти телефон и посмотреть в PDF список кандидатов даже без активного подключения к интернету.&lt;/p&gt;

&lt;p&gt;В РКН понимают, что, как только будет принят стандарт ECH и его реализация доедет до серверов крупных сервисов и в популярные браузеры, бороться с непокорными сайтами станет намного сложнее. DPI придется полагаться исключительно на фингерпринтинг со всеми вытекающими ложноположительными и ложноотрицательными проблемами. Иными словами, им придется или поломать весь интернет, или сдаться. Поэтому на следующий день после выборов Министерство цифрового развития, связи и массовых коммуникаций РФ разместило для общественного обсуждения &lt;a href="https://regulation.gov.ru/projects#npa=108513" rel="noopener noreferrer"&gt;проект&lt;/a&gt; федерального закона, устанавливающего запрет на использование на территории РФ протоколов шифрования, которые позволяют скрыть имя (идентификатор) интернет-страницы или сайта. Нет никаких сомнений, что это происходит для «легализации» борьбы с новыми методами обхода блокировок, подобными тем, над которыми работала наша команда в этом году. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Такие законы с каждым днем делают российский сегмент интернета все хуже — менее безопасным и менее приватным. Наша задача — отстоять его.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Вся эта работа была бы невозможна без вашей поддержки. Огромное спасибо!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Поддержать работу IT-отдела можно здесь:&lt;/strong&gt; &lt;a href="https://donate.fbk.info/it" rel="noopener noreferrer"&gt;https://donate.fbk.info/it&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Этот пост был опубликован на портале Habr и в 2022 году скрыт администрацией сайта. В поддержке сослались на особый порядок блокировки «в отношении материалов от организаций, признанных экстремистскими» и на «инициирование политических дискуссий». Мы выступаем против ограничения свободы распространения информации. Habr мы рассматривали как площадку для обмена опытом и для отчета о работе нашей технической команды.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ios</category>
      <category>android</category>
      <category>devops</category>
      <category>network</category>
    </item>
  </channel>
</rss>
