Правило маршрутизации читает метку пакета, а не conntrack
Маршрутизация по политике читает метку пакета; conntrack хранит другое значение с более долгой жизнью. Копирование между ними — шаг, который кто-то должен написать.
Четыре проверки отделяют работающее правило метки от работающего маршрута: какую метку читает правило, несёт ли её пакет ещё в момент поиска, была ли метка соединения восстановлена на последующих пакетах и позволяют ли маска и приоритет подходящего правила ему сработать. Растущий счётчик доказывает лишь то, что какое-то правило с чем-то совпало. Он ничего не говорит о том, что нес пакет, когда ядро выбирало его путь.
Две метки живут в разных местах и истекают по разным расписаниям.
Две метки, две жизни
Метка пакета принадлежит одному skb, путешествует с ним через хуки и потребляется селектором fwmark маршрутизации по политике. Метка соединения принадлежит записи conntrack, сохраняется на протяжении пакетов этого потока и невидима для правила маршрутизации, пока что-то не скопирует её обратно. Сохранение метки пакета в соединении — это запись; восстановление — отдельное действие. Ни то ни другое не происходит неявно.
Поэтому набор правил может выглядеть согласованным, тогда как решение о маршруте видит ноль: значение было сохранено, и ничто его не восстановило.
Копирование между ними — шаг, который пишете вы
Два важных утверждения работают в противоположных направлениях: одно сохраняет метку пакета в соединении, другое загружает метку соединения на пакет. Какое из них нужно, зависит от того, когда происходит классификация относительно потока. Проекту может требоваться только метка пакета, а добавление маркировки через conntrack из-за того, что какой-то обходной приём использовал обе, — это путь, на котором простая политика приобретает второй режим отказа.
ct mark set meta mark meta mark set ct mark
Запишите направление рядом с правилом, потому что из синтаксиса на первый взгляд это не очевидно. Первая строка сохраняет, вторая восстанавливает, и ни одна не подразумевает другую.
Классифицируйте до поиска, который это потребляет
Локально порождённый трафик и трафик, пересылаемый из LAN, проходят через разные хуки и достигают решений о маршруте в разные моменты. Правило вывода, работающее для собственных соединений маршрутизатора, не доказывает, что пакет пересылаемого клиента был помечен до своего поиска. Разместите классификацию там, где потребляющий её поиск ещё не произошёл, и проверьте, не перезаписывают ли значение последующие правила в той же цепочке. Порядок внутри цепочки — часть конфигурации, а не деталь реализации.
Сохранение состояния соединения тоже требует явного плана. Если классифицируется только первый пакет потока, последующим пакетам нужно восстановление сохранённой метки, иначе они пойдут по немаркированному пути. В этом разница между меткой, описывающей соединение, и меткой, описывающей пакет.
Задайте маршруту помеченный вопрос
ip route get 10.77.0.10 mark 0x2
Просмотрите правила и таблицу, затем запросите маршрут с включённой меткой, а также источник или входящий интерфейс, когда они влияют на политику. Обычный поиск без метки отвечает на другой вопрос и охотно сообщит путь, который вам не нужен. Проверьте маску и приоритет правила, а также его значение, и убедитесь, что выбранная таблица содержит пригодный маршрут.
Растущий счётчик — доказательство того, что какое-то правило совпало с каким-то пакетом. Это не доказательство того, что итоговый пакет нёс нужную метку в правильной точке решения.
Читайте метку, направление, момент и маску. Четыре проверки, и маршрут перестаёт быть загадкой.