NFT Tables: изменить DUP пакет

Вопрос или проблема

У меня есть сервер H с двумя сетевыми адаптерами с IP-адресами 192.168.105.10 и 192.168.104.10. Приложение, работающее на H, получает данные от сервера C по UDP порту 1703. IP-адрес сервера C192.168.105.14

Я хочу дублировать входящие UDP пакеты и отправлять их на сервер D, где другое приложение слушает на 192.168.104.11 также на порту 1703.

H работает на debian 11 (ядро 5.10).
Пока у меня есть следующая настройка таблицы NFT на H:

#!/sbin/nft -f

table ip route_C_packets
delete table ip route_C_packets

table ip route_C_packets {
    chain C_in {
         type filter hook prerouting priority 0; policy accept;
         ip saddr "192.168.105.14" udp port 1703 ip daddr set "192.168.104.11" dup to "192.168.104.11" ip daddr set "192.168.105.10"
    }
}

Это работает, однако выглядит немного некрасиво. Согласно моему пониманию:

ip saddr "192.168.105.14" udp port 1703: фильтрует только UDP пакеты из C на интересующем меня порту

ip daddr set "192.168.104.11: переопределяет адрес назначения (так что приложение, работающее на D, действительно может их получить)

dup_to "192.168.104.11": дублирует пакет и отправляет его на D, но самостоятельно не модифицирует daddr

ip daddr set "192.168.105.10": восстанавливает исходный адрес назначения для не дублированного пакета, чтобы приложение, работающее на H, могло действительно его получить.

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

ИЗМЕНЕНИЕ: Все здесь имеет маску подсети 255.255.255.0. 168.105 и 168.104 по сути две изолированные сети.

Ответ или решение

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

Теория

В данном случае мы имеем сервер H с двумя сетевыми интерфейсами, на который поступают UDP пакеты от сервера C. Задача состоит в том, чтобы не только обеспечить доставку этих пакетов на сервер H, но и продублировать их на сервер D. nftables позволяет управлять сетевыми пакетами, предоставляя возможности для фильтрации, маршрутизации и модификации пакетов на уровне ядра.

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

Пример

Ваш существующий скрипт:

#!/sbin/nft -f

table ip route_C_packets
delete table ip route_C_packets

table ip route_C_packets {
    chain C_in {
         type filter hook prerouting priority 0; policy accept;
         ip saddr "192.168.105.14" udp port 1703 ip daddr set "192.168.104.11" dup to "192.168.104.11" ip daddr set "192.168.105.10"
    }
}

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

Применение

Для достижения желаемого результата без "хаков" с изменением и восстановлением адреса назначения исходных пакетов, мы можем воспользоваться командой chain. Мы можем создать две разные цепочки: одну для изменения исходящих пакетов, и вторую, которая просто будет дублировать пакеты на нужный IP адрес:

#!/sbin/nft -f

table ip route_C_packets
delete table ip route_C_packets

table ip route_C_packets {
    chain C_in {
        type filter hook prerouting priority 0; policy accept;
        ip saddr "192.168.105.14" udp dport 1703 dup to "192.168.104.11"
    }

    chain C_dup {
        type nat hook postrouting priority 100; policy accept;
        ip saddr "192.168.105.14" udp dport 1703 ip daddr "192.168.104.11" snat to "192.168.105.10"
    }
}

В этом примере:

  1. Выделение цепочек: Мы создаем две цепочки — C_in для дублирования пакетов и C_dup для изменения адреса назначения в дубликате.

  2. Дублирование с dup to: В C_in мы просто используем команду dup to "192.168.104.11", которая отвечает за дублирование пакетов на сервер D. Это нужно для создания копии пакета без изменений в IP адресах.

  3. NAT для дублированного пакета: В этапе postrouting с помощью C_dup, после дублирования, можно попытаться использовать NAT для изменения адреса назначения в дублированном пакете, однако это может зависеть от версии nftables — изменять его только при отправке дубликатов. Как правило, для такой задачи может понадобиться дополнительная настройка и проверка с использованием подменных IP или маршрутов.

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

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

Оцените материал
Добавить комментарий

Капча загружается...