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

Проследите один пакет через сервер

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

Forwarding pathWho decidesWhat the host firewall sees
Kernel routing between clientsHost routing table and forward rulesEvery inner packet, with interface names
Peer forwarding inside the server processThe VPN daemon's own peer tableOnly the outer encrypted transport

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

Тест счётчиком, который решает, какой путь выполнялся

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

sudo nft list ruleset
sudo nft add rule inet filter forward iifname "tun0" oifname "tun0" counter accept
sudo nft list chain inet filter forward

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

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

Коммутатор — это не список доступа

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

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

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

Выбор точки пересылки

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

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

Что бы вы ни выбрали, запишите это рядом с правилами межсетевого экрана. Набор правил, который выглядит разрешающим трафик между узлами, тогда как демон всё равно решает сам, вводит в заблуждение следующего человека, который будет отлаживать неудачную передачу. Тот, кто читает только правила, будет считать, что ворота — это ядро.

Что проверить перед изменением правил

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

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

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