Перейти к основному содержимому

Как Ростелеком мне инфраструктуру ломал

··933 слов·5 минут

Как Ростелеком мне инфраструктуру ломал.

Пару дней назад в мой Telegram-канал с уведомлениями от Prometheus начали сыпаться постоянные предупреждения: один из серверов якобы прилёг поспать и не отвечает.

Проверка по SSH показала, что сервер жив. Более того, часть сайтов на этой же машине спокойно открывалась снаружи. Например:

  • rhvoice.hu;
  • storage.cyrmax.ru.

То есть сервер не умер, сеть не отвалилась полностью, сайты доступны, но Prometheus из домашней сети почему-то стабильно считает, что всё плохо.

А дальше началось любимое админское развлечение: “оно вроде работает, но не у меня, не всегда и не так”.

Первая версия: nftables

Первая мысль была простая: что-то сломалось в nftables.

Фаервол был временно выключен.

Не помогло.

Проблема сохранилась.

Вторая версия: node_exporter

Вторая идея: может быть, сломался сам node_exporter. Например, после обновления.

Я начал проверять подключение к целевому серверу с других машин.

Результат:

  • подключения с других серверов проходят успешно;
  • node_exporter отвечает;
  • Prometheus такой же версии на другой машине с таким же конфигом работает;
  • проблема воспроизводится только из домашней сети.

То есть сам сервер, node_exporter и конфиг Prometheus, скорее всего, были ни при чём.

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

На этом моя компетенция сказала “ну всё, брат, дальше сам”, и я пошёл за помощью к Gemini.

Что проверяли дальше

С инструкциями от искусственного интеллекта было сделано следующее.

1. Явные правила фаервола

Были добавлены конкретные правила для фаерволов на обоих концах.

Не помогло.

2. openssl s_client без полезной нагрузки

Подключение проверялось через:

openssl s_client

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

3. openssl s_client с HTTP-запросом

Потом через openssl s_client была отправлена полезная нагрузка, повторяющая структуру GET-запроса, который делает Prometheus при опросе метрик.

Результат: подключение зависает ровно там же, где и при проверке через curl.

4. Проверка на MTUD Blackhole

Была проверка на MTUD Blackhole.

Результат отрицательный: проблем с MTU по пути следования пакетов не видно.

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

5. tcpdump на обоих концах

Самое интересное показал tcpdump.

Сниффинг трафика на клиентской и серверной стороне дал наводящие на мысли результаты.

Что показал tcpdump

Сервер и клиент:

  • обмениваются пакетами;
  • корректно устанавливают TCP-соединение;
  • успешно проходят TLS handshake;
  • доходят до момента обмена первыми порциями полезных данных.

А потом подключение зависает.

Причём в каждой попытке зависание происходит на одном конкретном пакете одной конкретной длины - 48 байт зашифрованных данных.

Вот это уже стало выглядеть совсем интересно.

Магический заголовок на 50 символов

Попытка подмешать в запрос левый HTTP-заголовок со случайной строкой из 50 символов внезапно пробила блокаду.

После этого и через curl, и через openssl s_client обмен данными проходил успешно.

То есть чуть-чуть изменили внешний вид запроса - и проблема исчезла.

Но попытка симулировать похожую последовательность пакетов кастомными средствами снова приводила к зависанию.

Нормального объяснения у меня этому нет.

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

Может быть, роутер?

Верилось, конечно, слабо, но вдруг это мой роутер шалит.

Сервер был подключён к интернету напрямую, без роутера. Я вооружился клавиатурой и наушниками, сел перед комодом, на котором всё это добро установлено, и проверил ещё раз.

Нет.

Проблема не в роутере.

При прямом подключении поведение полностью идентичное.

Что я не проверил

Единственное, чего я не проверил, это такой же паттерн из других домашних сетей.

Например:

  • у других провайдеров;
  • у других пользователей Ростелекома;
  • из других регионов;
  • с другого домашнего оборудования.

Так что я не могу честно сказать, что проблема стопроцентно именно в Ростелекоме как в единственной возможной точке отказа.

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

Спасибо за стабильность

В общем, спасибо Ростелекому за стабильность, надёжность и прозрачность.

Конечно же, я обращусь в поддержку.

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

Самое смешное

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

Иначе как бы я пользовал Gemini, ChatGPT и другие сервисы, официально ушедшие из России и блокирующие российских пользователей.

А вот Prometheus, мирно собирающий метрики с моего сервера, внезапно оказался слишком подозрительным.

Тем временем

Пока я писал этот пост, Prometheus 8 раз прислал уведомление о том, что сервер лежит.

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

То есть сервер “лежит” только для моего домашнего Prometheus. Для всего остального мира он вполне бодр и трудоспособен.

PCAP-файлы

Я сохранил два pcap-файла:

  • один с перспективы домашнего сервера, то есть Prometheus client;
  • второй с перспективы удалённого сервера, где работает prometheus_node_exporter.

Архив можно скачать здесь:

Скачать pcap-архив

Если кто-то умеет читать такие штуки лучше меня и увидит там конкретную причину - буду рад узнать, что же это всё-таки было.

Итог

Что известно:

  • сервер жив;
  • node_exporter работает;
  • фаервол на сервере не является причиной;
  • с других серверов подключение проходит;
  • из домашней сети Ростелекома подключение зависает;
  • роутер исключён, потому что при прямом подключении проблема осталась;
  • TLS handshake проходит;
  • зависание происходит при передаче полезных данных;
  • изменение формы HTTP-запроса может магически починить соединение.

Что не доказано:

  • точный механизм поломки;
  • конкретный виновный узел;
  • воспроизводимость из других сетей Ростелекома.

Мой текущий вывод: где-то по пути от моей домашней сети до удалённого сервера происходит очень странная обработка трафика, из-за которой Prometheus не может нормально забрать метрики.

И да, это тот самый случай, когда сервер работает, сайты открываются, GitHub Action проходит, SSH жив, но мониторинг орёт, что всё умерло.

Люблю инфраструктуру.

Кирилл Белоусов
Автор
Кирилл Белоусов
Также известен как cyrmax. Пишу код, тестирую, автоматизирую инфраструктуру и помогаю делать цифровые продукты доступнее.