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

Проверка 1: прочитайте правило, которому соответствует ядро

Начните с правила политики, а не с межсетевого экрана. Ядро просматривает правила в порядке приоритета, и первое совпадение определяет таблицу. Прочитайте значение fwmark и маску из самого правила, затем убедитесь, что пакет с заданной вами меткой действительно ему соответствует. Правило, ожидающее полное 32-битное значение, не совпадёт с пакетом, несущим только один бит.

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

Это решают две команды: список правил и поиск маршрута до получателя в этой таблице.

Проверка 2: метка пакета или метка соединения

nftables может ставить метку на пакет и метку на запись отслеживания соединений, и это разные объекты. Метка пакета живёт на протяжении прохода обработки пакета, тогда как метка соединения сохраняется для потока и должна копироваться намеренно. Поставить одну и ждать другую — распространённое половинчатое исправление.

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

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

Проверка 3: кто ещё пишет эту метку

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

Метки также используются другими средствами межсетевого экрана, контейнерными сетями и маршрутизацией по политике для других целей, поэтому запись всего поля двумя подсистемами — конфликт, даже если каждая по отдельности корректна.

Перечислите писателей, прежде чем добавлять ещё одного.

Проверка 4: маска решает, что вы сохраняете

Метка — это 32-битное поле, а маски — способ, которым несколько владельцев делят его. Установка значения с маской сохраняет биты, которыми вы не владеете; установка всего поля уничтожает биты всех остальных. Читайте маску в каждом правиле, которое касается поля, включая те, которые вы не писали.

Задокументируйте распределение битов рядом с набором правил.

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

Проверка 5: проверяйте реальным потоком, а не поиском

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

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

Запишите метку, маску и таблицу в одном месте, и следующая правка станет проверяемой.

Похожие статьи