К содержанию
Тимур Шакирбеков.
← все тексты

Утекла ссылка на прокси, а легло всё, что делило с ней адрес

Тимур Шакирбеков 10 мин Заметки

6 сентября в 13:10 по Москве у меня разом легли три сервиса: Telegram-прокси, VPN и SSH на входной ВМ в Yandex Cloud. Перезагрузка не помогла. Закрытие порта прокси в группе безопасности не помогло. Помог новый IP-адрес: SSH ожил через 18 минут после его назначения. Итого пять часов простоя, из них 75 минут на починку и три с лишним часа на то, чтобы понять, что чинить.

Серверы не взломаны. Утекла сама ссылка на прокси, и тысяча чужих Telegram-сессий в час пошла через неё ещё утром 5 сентября. Ссылка на MTProto-прокси — это пароль: у кого она есть, у того и сервис. Пароль был один на троих, адрес один на всё, и когда пароль стал публичным, адрес умер вместе со всем, что на нём жило.

Дальше разбор с позиции безопасника, которого стоило позвать до 13 августа, а не после 6 сентября: что утекло и куда, почему легло всё сразу, где я ошибся при проектировании и где при диагностике, и что теперь стоит между семьёй и незнакомцами.

5 часовбез прокси, VPN и SSH — с 13:10 до 18:10 МСК 6 сентября

≈1 000чужих сессий в час через прокси с утра 5 сентября, по журналу mtg

7 700оборванных TLS-рукопожатий за десять минут в момент обрыва, по журналу xray

0парольных входов на обе ВМ с 9 августа — серверы чисты

01Ссылка на прокси — это пароль, и он был один на троих

13 августа я поднял для семьи MTProto-прокси. Схема на двух ВМ: выходная в Германии, на ней mtg, и входная в Yandex Cloud с русским адресом, которая по DNAT перекидывает порт 443 на выход. Снаружи это выглядит как HTTPS к microsoft.com — режим FakeTLS, чтобы оператор не видел ни Telegram, ни прокси. Через ту же входную ВМ ходил VPN на xray и мой SSH.

Ссылка вида t.me/proxy?server=…&port=…&secret=… — это адрес и пароль в одной строке. В ней нет ни логина, ни привязки к устройству, ни срока. Кто её открыл, тот подключён, и отозвать её точечно нельзя: секрет один, менять его — значит менять всем. В терминах безопасности это bearer credential, и обращаться с ней надо как с паролем, который нельзя сменить. Я обращался как со ссылкой: выдал одну на троих — себе, жене и брату, — и три недели через неё ходили три человека.

Модель угроз я тогда не писал, а она короткая. В Telegram живут боты-агрегаторы, которые вычёсывают ссылки на прокси из любых чатов, где состоят, и складывают их в публичные списки. Одна пересылка «в семейный чат» равна публикации. Утром 5 сентября через прокси пошла примерно тысяча чужих сессий в час, 85% из них — к дата-центру DC2, где живут в основном российские аккаунты. Цифры из журнала mtg на выходной ВМ после включения подробного лога.

Взлом серверов я исключил первым, потому что это самая дорогая версия. Журнал входов на обеих ВМ с 9 августа: только мой ключ, с Mac напрямую или через VPN, парольных входов ноль, чужих ключей и cron-задач нет. Публикацию в коде исключил вторым: репозитории приватные, поиск по коду GitHub по секрету и имени хоста пуст, в iCloud и Obsidian встречается только имя хоста. Сканеры исключил третьим: 13 адресов стучат в порт прокси на выходной ВМ напрямую, в обход входа, и все без секрета — фронтинг их отбрасывает. Секрет по сети не извлекается.

Осталась пересылка. И тут главный аргумент, который нашёлся в ядре входной ВМ: 31 707 записей «conntrack: table full», все до одной датированы ночью 13 августа. В ту ночь на том же имени и порту ещё висел старый прокси, и его уже кто-то долбил. Два прокси на одном адресе, две утечки, оба раза серверы чисты. гипотеза Общее звено — канал раздачи: ссылка уходила людям в Telegram, а Telegram читают не только люди.

02Первый симптом я принял за здоровье

5 сентября в 11:05 я спросил у Claude, почему под прокси не грузится BotFather. Сессия включила подробный лог на mtg, за первые десять минут насчитала 71 чужой поток и написала: прокси здоров. Формально так и было. Он отлично работал. На тысячу незнакомцев.

Это ошибка наблюдения, а не модели. Проверка отвечала на вопрос «работает ли сервис», а нужный вопрос был «чей трафик через него идёт». У прокси на троих есть точный профиль нормы: три адреса, десяток сессий, российские операторы. Всё, что на это не похоже, — инцидент, даже если сервис отвечает. Сигнал лежал в логе за 26 часов до падения, а читать его было нечем: ни порога, ни тревоги.

03Легло всё, потому что адрес был один

6 сентября в 13:10 симптом сменился. TCP-рукопожатие проходило, дальше тишина: ни VPN, ни прокси, ни SSH. За десять минут xray на входной ВМ насчитал 7 700 оборванных TLS-рукопожатий, исходящих пакетов стало втрое больше входящих, ядро писало «too many orphaned sockets»: ВМ отвечала в пустоту. Настоящие сессии через прокси кончились в ту же минуту.

Схема до инцидента: у прокси, VPN и SSH один публичный адрес на входной ВМ Красным — то, чего в схеме не должно было быть. Всё остальное работало как задумано, в этом и проблема.

У инцидента один корень, и по-английски он называется blast radius. Прокси, VPN и SSH делили публичный адрес, и адрес стал единицей отказа. Флуд шёл на порт прокси, а платформа не знает про порты, она знает адрес. Хуже того, на том же адресе жил канал починки: SSH умер вместе с сервисами, и на ВМ было не попасть даже для диагностики.

Дальше по порядку, что не помогло. Перезагрузка ВМ в 15:33: нет. Закрытие порта 443 в группе безопасности: нет, рукопожатие всё так же проходило, а данные пропадали. гипотеза Группа безопасности стоит после того места, где платформа Yandex Cloud перестала доставлять полезную нагрузку на адрес; изнутри ВМ этого не доказать, и это тикет в поддержку. Что помогло: новый адрес и новое имя. Через 18 минут после переезда SSH ожил, VPN и прокси следом.

Старое имя я оставил жить на мёртвом адресе. Пусть тысяча незнакомцев долбит пустоту, а не новую ВМ.

04Диагноз в горячке был неверным

В момент падения версия была такой: таблица соединений на ВМ переполнилась, лимит всего 8 192 записи, а флуд на десятки тысяч. Звучало убедительно, лимит подняли до 262 144, стало спокойнее. Причину это не тронуло.

Через два вечера с логами картина другая. 6 сентября таблица на ВМ не переполнялась ни разу, потерь на сетевой карте ноль, процессор занят на 0,5%. Все записи о переполнении, те самые 31 707, датированы 13 августа. ВМ была здорова, данные пропадали до неё. И «рост нагрузки в десять раз» после 14:00, до 13 600 соединений в час, оказался не новыми людьми, а ретраями: ни одного ClientHello, ни одной живой сессии. Тысяча клиентов стучалась в закрытую дверь.

После 13:00 через прокси не прошла ни одна настоящая сессия Сессии, дошедшие до Telegram, по журналу mtg на выходной ВМ. Соединений в те же часы было по 9–13 тысяч, все пустые.

Урок, который безопасники знают наизусть и всё равно на него наступают: гипотеза, которая сходится с симптомом, и починка, после которой «стало лучше», — самая дорогая разновидность ошибки, потому что она закрывает расследование. Сначала хронология с датами из логов, потом гипотеза. Лог с датами дешевле любой версии.

05Пять слабых мест были в проекте, а не в коде

Ни одна строка конфигурации не была сломана. Сломан был проект: пять решений в нём я принял 13 августа за час, не задав себе вопрос «а что, если ссылка станет публичной».

Пять слабых мест в проекте и чем каждое закрыто Слева то, что было 13 августа, справа то, что стоит с 7 сентября. Две позиции справа ещё за мной, о них ниже.

Один секрет на троих. Утечка неатрибутируема и не отзывается по одному. Теперь у каждого свой секрет и свой порт: пять отдельных экземпляров mtg на выходной ВМ, утечка одной ссылки видна по имени и закрывается остановкой одного экземпляра.

Порт прокси открыт без лимитов. DNAT покорно тащил на выход всё, что пришло. Теперь на входе не больше 64 соединений с одного адреса и 50 новых в секунду на порт, лишнее получает сброс, а не молчание. Плюс размыкатель: при флуде свыше 600 соединений в минуту три минуты подряд он закрывает порт и сам открывает обратно, когда стихнет.

Один адрес на прокси, VPN и SSH. VPN-ссылки теперь содержат имя, а не IP, поэтому адрес для VPN можно сменить через DNS, не трогая телефоны. Telegram-ссылки, наоборот, привязаны к IP по моей же просьбе спрятать домен, и при следующей смене адреса их придётся переиздать. Это цена скрытого домена, и я её принял осознанно.

О падении узнал от семьи. Теперь сторож на выходной ВМ раз в минуту считает живые сессии по экземплярам и гасит тот, где их больше 40. На входной — самопроверки: сервис, таблица соединений, сертификаты, диск. Снаружи каждые две минуты проверка входа, как его видит телефон. Тревоги приходят в Telegram от моего же бота.

Плана Б не было. Ни запасного адреса, ни настроенного CLI облака, ни процедуры: первый час 6 сентября ушёл на yc init и поиск нужной ВМ. CLI теперь настроен, процедура переезда записана. Запасной адрес и TTL 300 на DNS-записи по-прежнему за мной: на момент публикации TTL стоит 21 600, и при следующем переезде телефоны будут помнить старый адрес шесть часов.

06Защита сначала била по своим

Вторая половина истории, которую в отчётах обычно опускают: новые лимиты первым делом отрезали меня и брата.

Первую версию лимитов я поставил жёсткой: не больше 8 соединений с одного адреса. Telegram на компьютере открывает больше. Лишние получали сброс, клиент начинал переподключаться — 741 попытка за десять секунд, — это пробивало лимит частоты, размыкатель принимал мой собственный шторм за атаку и закрывал порт. Замкнутый круг: порт закрыт, клиент долбит, авто-возврат не наступает. Лечится тем, что размыкатель считает только соединения, прошедшие лимиты.

Через день брат написал, что его прокси недоступен. Размыкатель отрезал его порт на час из-за семиминутного всплеска слепого сканера: 2 000–5 000 соединений в минуту на «знаменитый» облачный порт, при этом с его секретом не подключился никто. Старый размыкатель резал по первому всплеску и не умел открывать обратно. Переписал: три минуты выше порога, потом закрытие, потом автоматический возврат.

Это налог на любой новый контроль — false positive. Защита, которая срабатывает на своих, первой же и отключается, поэтому настраивать её надо на реальном трафике, а не на той атаке, которую только что пережил.

07Что осталось незакрытым

Кто переслал ссылку, я так и не знаю. Реальные адреса чужих клиентов сгорели вместе с NAT: входная ВМ подменяла источник, в логе mtg все они выглядят как один адрес, а таблица соединений входа сгорела при перезагрузке. В дюжине прокси-каналов и списках на GitHub моего имени нет. «Переслали в чат» — лучшая версия, а не улика. Спрошу у жены и брата.

Что именно Yandex Cloud сделал с адресом 6 сентября с 13:10 до 18:00, изнутри не видно. Это тикет, и он ещё не написан.

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

как ссылаться

Тимур Шакирбеков, «Утекла ссылка, легло всё», shkrbkv.ru, 07.09.2026 — https://shkrbkv.ru/notes/proxy-leak/
Ссылка на семейный Telegram-прокси утекла: тысяча чужих сессий в час и пять часов без VPN и SSH. Что утекло, почему легло всё и что я спроектировал бы иначе.