Рейтинг:0

Как запретить сетевому фильтру автоматически менять исходные порты

флаг jp

Я заметил, что netfilter меняет исходный порт при установлении соединения в модуле conntrack. Мне нужно предотвратить такое поведение.

Вот что я сделал, чтобы воспроизвести свою проблему:

  1. Я создаю правило netfilter, которое будет выполнять DNAT с порта 2002 по 2003.

sudo iptables -w -t nat -A ВЫВОД -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001 --dport 2002 -j DNAT --к месту назначения: 2003

  1. Затем я создаю запись conntrack, чтобы имитировать соединение с 192.168.30.1:2001 (Мой компьютер) на 192.168.30.1:2003.

sudo /sbin/conntrack -I -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 --timeout 100000

  1. В конце концов, я выполняю подключение к 192.168.30.1:2002 со своего компьютера с исходным портом 2001:

sudo nc -u -p 2001 192.168.30.1 2002

Из-за правила netfilter DNAT я ожидал выходной пакет с портом назначения 2003 и портом источника 2001. Однако на wirehark я заметил, что порт источника изменился на случайное число. Я предполагаю, что это потому, что мой компьютер считает, что существует существующее соединение на порту 2001 (из-за записи conntrack), а затем запрещает исходный порт быть 2001 (правильно?). Но я не хочу такого поведения? Как я могу принудительно использовать номер порта 2001?

Tom Yan avatar
флаг in
Я не думаю, что это имеет какое-либо отношение к DNAT или netfilter. Скорее это просто поведение `nc`.
sebastien dontneedtoknowthat avatar
флаг jp
Я почти уверен, что это не поведение `nc` (по крайней мере, потому что мой пакет достигает моего правила DNAT с исходным портом).
Рейтинг:0
флаг in

NAT изменяет исходный порт, чтобы уменьшить риск конфликта портов. Что должно произойти, если этот спорт 2002 уже занят на машине NAT?

Если у вас есть особые требования к определенным портам, вы можете добавить определенные СНАТ правила для этого, но опять же, что, если несколько внутренних клиентов попытаются использовать один и тот же исходный порт?

Здесь мы должны вернуться и признать, что NAT — это хак, который был создан, чтобы уменьшить проблему отсутствия общедоступных IP-адресов. Настоящее исправление здесь заключается в том, чтобы у всех были общедоступные IP-адреса без NAT.

Говоря о NAT в наши дни, мы чаще всего имеем в виду частные IP-адреса за одним IP. В этих случаях это на самом деле NAPT а Аналогичный вопрос, связанный с этим, я думал о МАСКАРАД цель и не ДНКТ

Tom Yan avatar
флаг in
DNAT никоим образом не может вызвать изменение исходного порта (не для *оригинального* трафика), поскольку это будет означать, что это подразумевает SNAT. Скажем, если бы это было так, это означало бы, что SNAT, предложенный вами / запрошенный пользователем, будет «вторичным» SNAT, что вообще не имеет смысла (для * одной * «машины NAT»). Не забывайте, что для каждого SNAT требуется «обратный DNAT» для ответов. История, которую вы здесь рассказываете, касается SNAT, но вы предлагаете SNAT в качестве решения (или обходного пути; что угодно).
флаг in
Если вы выполняете NAT, при необходимости искажаются полные пакеты, даже если вы намереваетесь использовать только DNAT или SNAT.
Рейтинг:0
флаг in

Для работы DNAT (в том смысле, чтобы программа могла распознавать ответы), «обратный NAT», который меняет исходный порт отвечающего трафика с 192.168.30.1192.168.30.3:2001) от 2003 к 2002 нужно будет выполнить.

Однако при наличии трафика, исходящего из 192.168.30.1:2003 к 192.168.30.3:2001 которые с точки зрения conntrack не являются следствием DNAT (поскольку согласно созданной записи conntrack хост не является тем, кто инициировал соединение), обратный NAT будет неуместным.

Таким образом, netfilter «вынужден» также выполнять SNAT для трафика, совпадающего с правилом DNAT, чтобы он мог различать отвечающие трафики (то есть также из 192.168.30.1:2003) по месту назначения 192.168.30.3:$ случайный.

Я предполагаю, что netfilter либо выполнит обратный NAT для DNAT (который является SNAT) перед обратным NAT для SNAT (который является DNAT), либо сумеет использовать место назначения перед обратным NAT для SNAT (т. 192.168.30.3:$ случайный) как сопоставление для обратного NAT для DNAT, иначе принудительный SNAT будет бессмысленным.(Однако в случае без реверса ни одно из них не является истинным, AFAIK: DNAT будет выполняться в PREROUTING до SNAT в INPUT, а сопоставление пункта назначения в правиле SNAT, если таковое имеется, будет использовать значение, полученное в DNAT)


Дело в том, что история выше / «проблема» в вашем вопросе вряд ли имеет какой-либо смысл на самом деле. Возьмем в качестве примера VPN с двумя хостами Wireguard: предположим, вы хотите иметь Конечная точка = установлен на обоих хостах (чтобы любой из них мог инициировать связь) и не хочет, чтобы значения неожиданно «обновлялись» из-за принудительного SNAT (при условии, что это действительно может быть запущено), что вы должны сделать, это просто «всегда -on" SNAT, который "дополняет" DNAT/ эквивалентен резервному NAT:

iptables -t nat -A INPUT -s 192.168.30.1 -d 192.168.30.3 -p udp --sport 2003 --dport 2001 -j SNAT --к источнику: 2002

что обычно не требуется в модели клиент-сервер из-за автоматического обратного NAT для DNAT.

P.S. Вы все еще не должны достичь 192.168.30.1:2003 к 192.168.30.1:2003 однако, в противном случае принудительный исходный NAT также произойдет, если вы снова достигнете его 192.168.30.1:2002 до того, как запись conntrack первого будет удалена. Дополнительное правило SNAT в INPUT также не должно доставить вам лишних хлопот.

Рейтинг:0
флаг cl
A.B

Вы можете установить два потока, которые обычно сталкиваются в коннтрек таблица поиска (таким образом, обычно вызывает перезапись исходного порта в новом потоке, чтобы избежать коллизии), чтобы она находилась в разных зоны контракта. Это свойство дополнительной зоны делает коннтрек не совпадать/не сталкиваться с существующим потоком в другой зоне conntrack: перезаписи исходного порта не произойдет.

Для вашего конкретного примера вот конкретное правило, которое предотвратит коллизию и, следовательно, предотвратит перезапись исходного порта:

iptables -t raw -A ВЫВОД -s 192.168.30.3 -d 192.168.30.1 -p udp --sport 2001 --dport 2002 -j CT --zone-orig 1

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


Первоначальный вариант использования, в котором появилась эта опция, — это когда коннтрек в том же сетевом стеке (без дополнительного сетевого пространства имен) со сложной настройкой маршрутизации (например: маршрутизация между 4 разными частными локальными сетями с использованием одних и тех же IP-адресов, например, между 192.168.1.0/24 eth0 <-> eth1 10.1.0.0/24 и еще раз 192.168.1.0/24 eth2 <-> 10.1.0.0/24 eth3) могут видеть два несвязанных потока с одинаковыми адресами/портами. Как Сетевой фильтр и коннтрек ничего не знаю о маршрутизации (т. коннтрек справочная таблица включает только адреса) их надо научить считать эти потоки отдельно, добавив свойство зоны, привязанное вручную к топологии маршрутизации в коннтрек Справочная таблица.

(Вот LWN-ссылка когда функция была первоначально предложена.)

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.