Анализ метаданных: как восстановить ваш круг общения, не читая переписки
Пользователь изучает контент на смартфоне.
Когда шифрование — это только половина дела
В 2016 году я впервые настроил OTR поверх XMPP и чувствовал себя Джеймсом Бондом. Ещё бы — никто не читает мои сообщения, даже админы сервера! Прошло почти 10 лет, а мы до сих пор носимся с E2EE как с серебряной пулей. Signal, Matrix, WhatsApp — везде сквозное шифрование. И везде одна и та же иллюзия: если текст зашифрован, значит, меня не видно.
Нет.
Представьте, что вы заперли входную дверь на сейфовый замок, а окна оставили открытыми. И ещё повесили на фасад огромное табло: «Хозяин дома, сейчас переписывается с тремя людьми, двое из них в Берлине, один спит». Примерно так работает метаданная модель современных мессенджеров.
Signal не хранит контакты пользователей. Это правда. Не хранит содержимое чатов — тоже правда. Но вот что остаётся: временная метка последнего подключения. «Приблизительная», как они говорят. И знаете что? Даже этого хватает, чтобы восстановить паттерны вашей жизни с точностью, от которой становится не по себе.
Кто с кем общается? Как часто? В какое время суток? С каких устройств? Где находятся участники переписки? На все эти вопросы метаданные отвечают, не расшифровывая ни единого сообщения. Вы можете обсуждать планы революции в абсолютно защищённом чате, но если сервер фиксирует, что каждую среду в 23:00 вы обмениваетесь пакетами с одними и теми же пятью аккаунтами — содержимое уже не так важно.
Я называю это «портрет без расшифровки». И он убивает приватность быстрее, чем любой взломанный ключ.
Смешно другое: мы, технари, прекрасно это знаем. Но продолжаем рекомендовать Signal как эталон приватности, потому что «ну он же не хранит контакты». А то, что метаданные сливаются в реальном времени — ну, это уже мелочи. До тех пор, пока не становится поздно.
Кто, когда и откуда: портрет пользователя без расшифровки
В 2013 году Эдвард Сноуден сформулировал простую мысль: если вы знаете, кому я звоню и когда — вам не нужно слушать разговор. Десять лет спустя мы всё ещё делаем вид, что это не про нас.
Метаданные — это не просто «техническая информация». Это поведенческий слепок. Кто кому пишет в три часа ночи. Кто появляется в сети строго с 9 до 18 по будням, а на выходных пропадает. У кого два устройства, одно из которых никогда не покидает определённый радиус. Содержимое сообщений? Да кому оно нужно.
Возьмём типичного пользователя Signal. Допустим, Алиса. Сервер Signal знает о ней до обидного много: когда она последний раз была онлайн, с каких IP-адресов подключалась, каким клиентом пользуется (iOS, Android, десктоп). Да, Signal не хранит её контакты — но он видит, что аккаунт Алисы отправил зашифрованное сообщение аккаунту Боба. Размер пакета, время отправки, факт доставки. Повторите это тысячу раз — и у вас график социальных связей, который не снился ни одному психотерапевту.
Особый шик — анализ частоты. Если два аккаунта обмениваются сообщениями каждую ночь с 23:00 до 01:00, а днём молчат — поздравляю, вы только что идентифицировали романтического партнёра, не прочитав ни строчки. Если группа из пяти человек активизируется каждый четверг в 20:00 — возможно, это игровая сессия в D&D. А может, и нет. Но корреляция уже построена.
С устройствами ещё веселее. Утром сообщения уходят с IP-адреса домашнего провайдера, днём — из сети офиса, вечером — с мобильного. Три точки на карте, и вот у вас уже есть дом, работа и примерный маршрут. Включили VPN? Отлично, теперь вы просто «человек, который прячется», — само по себе метаданные.
Я как-то ради эксперимента поднял Matrix-сервер для десятка друзей и через неделю уже мог сказать, кто с кем в ссоре, просто глядя на задержки между сообщениями. Мгновенные ответы — близкие отношения. Паузы по 40 минут — вежливое избегание. Тишина после 22:00 — человек ложится спать. Содержимое чатов было зашифровано. Это не помогло.
Ирония в том, что мы сами генерируем эти данные с энтузиазмом, достойным лучшего применения. Уведомления о прочтении, статусы «печатает», индикаторы онлайна — всё это метаданные, которые мы добровольно отдаём. Signal по умолчанию показывает, когда вы были в сети последний раз. Отключить можно. Догадайтесь, сколько пользователей это делают.
Как Signal стал жертвой собственной архитектуры
Signal хранит о вас ровно одну вещь: временную метку последнего подключения. Ни контактов, ни истории чатов, ни групп, в которых вы состоите. Даже номер телефона, который вы использовали при регистрации, не лежит на серверах в открытом виде — он хешируется и используется только для проверки при входе. Звучит как рай для параноика, правда?
Но дьявол, как обычно, в деталях. Или, точнее, в том, чего Signal не делает.
Сервер Signal — минималист до аскетизма. Он не пытается скрывать метаданные, потому что у него их тупо нет. Нет — значит нечего скрывать. Логика железная: если мы не храним социальный граф, мы не можем его выдать. Проблема в том, что социальный граф всё равно существует. Он просто живёт не на сервере, а в сетевом трафике.
Когда вы отправляете сообщение другу, ваш клиент шлёт запрос на сервер Signal. Сервер видит: клиент А хочет доставить сообщение клиенту Б. Он выполняет доставку и тут же забывает об этом. Никаких логов, никаких записей. Но что, если я сижу между вами и сервером? Или между сервером и вашим другом? Я вижу пакеты. Я вижу, что устройство с IP-адресом Х отправило зашифрованный блоб на Signal-сервер, а через 200 миллисекунд сервер отстучался к устройству с IP-адресом Y.
И вот тут начинается магия. Я не знаю, что в сообщении. Не знаю, от кого оно и кому. Но я вижу паттерн. Вижу его сотни раз за день. И я могу с высокой точностью сказать: эти два устройства общаются.
Signal сам загнал себя в ловушку собственной архитектуры. Отказавшись от хранения метаданных, они решили проблему ордеров из суда — им действительно нечего показать следователю. Но они не решили проблему глобального пассивного наблюдателя, который слушает трафик на уровне провайдера. Более того, минималистичный подход сделал атаку даже проще: раз сервер не хранит никакого мусора, весь анализ сводится к чистой корреляции пакетов во времени.
Забавно, что команда Signal это понимает. Они даже экспериментировали с технологией Sealed Sender, где отправитель остаётся анонимным для сервера. Но это защищает только от самого сервера как активного наблюдателя. От пассивного сниффера трафика это не спасает — IP-адреса всё равно светятся.
Мой любимый пример: представьте журналиста, который общается с информатором через Signal. FBI не может прочитать их переписку. Но может увидеть, что устройство журналиста каждую ночь в 2:14 отправляет сообщение на сервер Signal, после чего сервер немедленно пишет на устройство информатора. Через неделю такой слежки у них есть паттерн. Через месяц — доказательство связи.
И да, та самая временная метка последнего подключения, которую Signal честно хранит? Она добавляет последний штрих к портрету. Вы были в сети в 2:13. Сообщение ушло в 2:14. Собеседник получил его и прочитал в 2:15. Криптография бессильна против хронологии.
Matrix: зашифрованные сообщения и прозрачные серверы
С Signal хотя бы понятно — один центральный сервер, одна точка отказа, одна корпорация под прицелом. С Matrix всё одновременно и лучше, и чудовищно хуже. Протокол построен на федерации: вы можете поднять свой сервер, пригласить друзей и радоваться жизни. Криптографически тут полный порядок — Olm для initial key exchange, Megolm для групповых чатов, всё по красоте. Сообщения лежат на сервере в зашифрованном виде, ключи только у участников. Хоть админу на почту их пересылай — не прочитает.
Я ставил synapse у себя на VPS за 5 евро. Настроил шифрование, проверил fingerprint'ы ключей, убедился что всё работает. И знаете что? Через неделю я увидел, как мой маленький домашний сервер радостно обменивается метаданными с matrix.org, с каким-то французским инстансом, с парой немецких. Федерация работает так: когда вы заходите в комнату, где есть участники с других серверов, ваш homeserver начинает стучаться к их homeserver'ам. И каждое такое рукопожатие оставляет след.
Вот реальный пример из логов моего сервера за сутки: 3400 запросов на /send, 1200 на /sync, 450 событий присоединения к комнатам. В каждом — временные метки, ID пользователей, хэши комнат. Содержимого нет, оно зашифровано. Но кому нужно содержимое, когда видно, что пользователь @alex:myserver.ru состоял в комнате #crypto-talk:matrix.org, писал туда каждые 40 минут с 9 утра до 11 вечера, а 15 марта резко перестал и перешёл в комнату #urgent-chat:private-server.de с двумя участниками из Германии?
Смешно то, что Matrix позиционирует себя как децентрализованную альтернативу. Но на практике федерация создаёт распределённую систему наблюдения. Каждый сервер в цепочке видит свой кусок метаданных. Сервер А знает, что пользователь Х состоит в комнате Y. Сервер Б видит, когда Х был последний раз онлайн. Сервер В логирует IP-адреса при подключении. Сложить пазл — дело техники и пары ордеров.
А теперь вишенка на торте: даже если вы шифруете всё, включая названия комнат (что мало кто делает), сам факт существования зашифрованной комнаты с пятью участниками на серверах трёх юрисдикций — это уже метаданное. И оно живёт вечно. Реплицируется. Бэкапится. Ждёт своего часа.
Уроки истории: XMPP и Jami как забытые пророки
Пока мы тут обсуждаем Signal и Matrix, самое время вспомнить парня, который пришёл на вечеринку за десять лет до всех и тихо курил в углу. XMPP с расширением OTR (Off-the-Record) — это примерно 2004 год. До первого коммита Signal Protocol оставалось лет восемь. До Matrix — вообще вечность.
OTR делал ровно то, о чём мы мечтаем сегодня: сквозное шифрование, perfect forward secrecy, денiability — возможность отрицать авторство сообщения даже при наличии ключей. И главное — никаких центральных серверов с логами метаданных. XMPP-серверы по определению федеративны. Хочешь — подними свой за пять минут на Prosody. Не хочешь — иди на любой публичный. Никто не заставлял скармливать номер телефона и сливать граф контактов корпорации.
Я пробовал настроить OTR поверх Pidgin в 2010-м. Это заняло часа четыре, три перекура и пару матерных тирад в адрес GPG-ключей. Работало? Да. Было удобно? Нет. Каждый новый контакт требовал ритуальных плясок с верификацией отпечатков. Синхронизация между десктопом и телефоном? Забудьте. Групповые чаты с шифрованием? Технически возможно, на практике — боль.
Jami (бывший Ring) пошёл ещё дальше. Распределённая DHT-сеть, никаких серверов вообще, сквозное шифрование из коробки, прямая передача аудио/видео между пирами. В теории — анархистская мечта. На практике я поставил Jami в 2019-м, добавил трёх друзей. Двое не смогли найти друг друга в сети, у третьего отваливался звук при звонках. Через неделю мы вернулись в Telegram.
И вот тут самое смешное: XMPP и Jami архитектурно решили проблему метаданных задолго до того, как мы вообще начали о ней беспокоиться. Федерация вместо централизации. Опциональность серверов вместо обязательного хостинга. Отсутствие привязки к телефонному номеру. Но они проиграли не криптографически — они проиграли UX-битву.
Signal победил, потому что «оно просто работает». Зарегистрировался по SMS — и через минуту уже пишешь. Matrix пытается усидеть на двух стульях: федерация плюс удобство, но метаданные сливает по полной. А OTR и Jami остались нишевыми игрушками для параноиков.
Индустрия этот урок проигнорировала. Каждые пять лет кто-то пишет новый мессенджер с «абсолютной приватностью», встраивает туда Signal Protocol и садится в лужу метаданных. XMPP с OTR мог бы стать стандартом, если бы не требовал от пользователя знаний криптографии на уровне «сгенерируй ключ, проверь отпечаток, не потеряй приватный ключ, иначе переписка умрёт навсегда». Люди не хотят быть собственными админами — они хотят кнопку «начать чат».
Спорное решение? Да. Но факт остаётся фактом: технологии для реальной анонимности существуют почти двадцать лет. Просто мы до сих пор выбираем удобство.
Почему мы продолжаем игнорировать метаданные
Есть у меня теория. Большинство разработчиков, внедряющих E2EE в свои чаты, учатся по туториалам. А туториалы — они как инструкция к шкафу из IKEA: собрал, стоит, радуешься. То, что шкаф прозрачный и все видят твои носки — это уже не проблема инструкции.
Статьи о внедрении шифрования в чаты нацелены на простое понимание и практическое применение без углубленного разбора математических аспектов криптографии. И это правильный подход для массового adoption'а — никто не хочет читать 40 страниц про Double Ratchet перед тем, как написать «привет». Но есть побочный эффект: у разработчика формируется ложное ощущение, что если сообщение зашифровано — приватность достигнута. Замок на двери есть, значит, в дом никто не войдёт. А то, что GPS-трекер на машине показывает все твои перемещения — ну так это же не в дом зашли, правда?
Это системная ошибка восприятия. Шифрование контента воспринимается как полная приватность, а метаданные остаются в слепой зоне. Не потому что кто-то злой. Просто архитектурно метаданные нужны для работы сервиса — как иначе доставить сообщение, если не знать, кому и на какое устройство? И вот этот технический долг маскируется под «нужную функциональность».
Смешно другое. Мы обсуждаем угрозу метаданных уже лет пятнадцать. XMPP с OTR умел прятать содержимое сообщений ещё когда Facebook был закрытой сетью для гарвардских студентов. Jami вообще построили децентрализованную DHT-сеть без серверов — никаких метаданных на центральном узле просто потому, что нет центрального узла. И что? Где Jami в массовом использовании? Правильно, в разделе «нишевые решения для параноиков».
Анализ метаданных, кстати, даёт картину поинтереснее содержимого чатов. Содержимое — это «встретимся в 7». Метаданные — это «человек А пишет человеку Б каждый вечер между 22:00 и 2:00, используя iPhone, находясь в радиусе 500 метров от определённой вышки сотовой связи». Что из этого интереснее для профилирования? То-то же.
Signal хранит только приблизительную временную метку последнего подключения — молодцы, минимизировали. Но IP-адрес при доставке сообщения всё равно проходит через их серверы. Matrix хранит зашифрованные сообщения на серверах, но граф социальных связей — кто в каких комнатах состоит — лежит открыто. И это не баг, это фича. Federation без этого не работает.
Мы игнорируем метаданные не по злому умыслу. Мы игнорируем их потому, что признание проблемы означает признание того, что текущие «безопасные» решения — не совсем безопасные. А переписывать архитектуру с нуля никто не хочет. Проще сказать «ну, метаданные — это сложная проблема, мы над ней работаем» и продолжать мерить adoption rate.
Что делать прямо сейчас: практические шаги к реальной приватности
Ладно, хватит теории. Вы уже поняли, что ваши метаданные текут рекой. Вопрос — что с этим делать, кроме как уйти в лес и общаться дымом костра.
Первое и самое болезненное: перестаньте использовать один идентификатор везде. Ваш номер телефона в Signal — это якорь, который связывает все ваши коммуникации в единый граф. Заведите отдельную SIM-карту для приватных чатов. Да, это неудобно. Да, это стоит 300-400 рублей в месяц. Но это единственный способ разорвать связь между вашей личностью и вашим аккаунтом в Signal. И нет, виртуальные номера за 50 рублей не работают — Signal их банит за пару дней.
Второе: настройте федеративный сервер Matrix правильно. Если вы уже используете Matrix, не сидите на matrix.org, где админ видит вообще всё. Поднимите свой сервер на дешёвом VPS за 500 рублей в месяц. Конфигурация Synapse занимает час, включая настройку SSL через Let's Encrypt. Но дальше — важнее: отключите federation на уровне комнат, где это возможно. Да, вы потеряете часть функциональности. Но ваши метаданные не будут реплицироваться на десятки чужих серверов.
Третье: используйте Tor или VPN, но с умом. Если вы подключаетесь к Signal через Tor, вы скрываете свой IP. Но Signal всё равно знает ваш номер телефона и время последнего подключения. Это как надеть маску, но оставить на груди бейджик с именем. Работает только в связке с отдельным номером.
Четвёртое, и самое контринтуитивное: пишите меньше. Серьёзно. Каждое сообщение — это событие с временной меткой. Каждое «ок» и «понял» строит паттерн вашей активности. Групповые чаты — это вообще катастрофа: один человек написал, а метаданные утекли про всех участников. Используйте исчезающие сообщения везде, где можно. В Signal ставьте таймер на неделю, не больше. В Matrix это сложнее, но тоже настраивается.
Пятое: диверсифицируйте каналы. Не кладите все яйца в одну корзину. Signal для быстрых переговоров, Matrix для рабочих групп, Jami для совсем чувствительных тем (он реально P2P, без серверов). Да, три приложения вместо одного. Такова цена.
И главное — примите факт: абсолютной приватности не существует. Вы не уходите от слежки полностью, вы просто поднимаете стоимость анализа ваших метаданных. Делаете его экономически невыгодным. Если за вами охотятся спецслужбы целенаправленно — эти советы не помогут. Но если вы хотите не попадать в автоматические системы профилирования и массового сбора — этого арсенала достаточно.
Смешно, но лучшая защита метаданных — это быть скучным. Никаких звонков в три часа ночи, никаких резких всплесков активности, никаких чатов на сто человек. Просто скучная, предсказуемая рутина. Алгоритмы отсеивают скучных первыми.