Почему изменяется порт udp пакета после маскарада?
Два сервака имеют белые адреса, связал их через GRE туннель. Один сервер является шлюзом, который форвардит диапазон портов через туннель на второй сервер. На втором сервере приложения слушают и tcp и udp. На втором серваке маркирую пакеты, которые эти приложения выплёвывают и отправляю обратно в туннель. TCP трафик ходит как нужно, а вот с UDP какой-то прикол.
На сервере-шлюзе в tcpdump видно следующее:
Входящий tcp пакет пришёл на 100.100.100.100:31000 ушёл в туннель на 10.10.10.2:31000, вернулся из туннеля имея источник 10.10.10.2:31000, получает маскарад, становится 100.100.100.100:31000 и улетает клиенту, всё хорошо.
Udp пакет в свою очередь приходит на 100.100.100.100:31000, получает форвард в туннель на 10.10.10.2:31000, а возвращается из туннеля с источником 200.200.200.200:31000, получает маскарад и становится 100.100.100.100:рандомный_порт, соответственно клиент не получает в ответ ничего, потому что не ждёт рандомный порт.
Ниже накидал +- схему, все правила для tcp и udp одинаковые.
Подскажите, куда жмать, чтобы всё работало?? А лучше объясните, почему так происходит: изменяется sport после маскарада, и из туннеля возвращается пакет с saddr другого интерфейса. Полагаю, что-то с conntrack связанное, но я не знаю, как гуглить даже
Дополнительно:
Имеются ли у вас еще правила iptables после "озвученных" по очередности? Может они применяются...
Самый простой и правильный способ туннелирования так, как вы хотите:
1. На сервере слева оставляем только PREROUTING-часть (без POSTROUTING masquerade), в существующие PREROUTING-правила добавляем daddr 100.100.100.100
2. На сервере справа убераем всё текущее, добавляем только:
ip route add default dev gate-finl table 101 ip rule add from 10.10.10.2 table 101 |
ip route add default dev gate-finl table 101 ip rule add from 10.10.10.2 table 101
Либо, вместо пункта 2, добавляем default-маршрут через gate-finl с метрикой выше, чем у основного, в таблицу маршрутизации по умолчанию, и bind'им программу, работающую с пакетами с этого интерфейса, на этот интерфейс (SO_BINDTODEVICE, bind на IP-адрес недостаточно). Всё.
А разве без маскарада в построутинге не будет такого, что пакет пришедший из туннеля пакет полетит клиенту имея сурс адрес 10.10.10.2? Я не проверял в текущей конфиге, просто где-то уже использовал и тут добавил
Забиндить софтину на интерфейс не вариант, а вот способ с маршрутизацией мне нравится, спасибо. Но вопрос остаётся открытым, будут ли udp пакеты бегать правильно?
Я пока на костыль поставил, сделал маскарад на udp трафик, который в туннель летит, и всё работает, но второй сервак естественно видит сурс адрес шлюза, а не клиента.
А разве без маскарада в построутинге не будет такого, что пакет пришедший из туннеля пакет полетит клиенту имея сурс адрес 10.10.10.2?
Да, вы правы. Попробуйте в ваше правило добавить еще проверку на исходящий интерфейс. И вы с oif не ошиблись? У вас на картинке ens1, а в правиле ens3.
Ответы:
Udp натится с оговорками. И одна из причин прописана в rfc. И порт обязательно будет меняться. Только конусный нат возможен.
Читайте разницу в трансляциях tcp и udp.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Изменение порта UDP пакета после прохождения через маскарад (NAT) обычно происходит из-за того, что NAT изменяет исходный порт пакета для того, чтобы корректно передать его через сеть.
Когда пакет проходит через NAT, NAT создает запись в своей таблице преобразования адресов (NAT translation table), где сохраняет информацию об исходном и измененном порте пакета. При получении ответного пакета NAT использует эту таблицу для того, чтобы правильно перенаправить пакет обратно на исходный IP и порт.
Это необходимо из-за того, что внутренние устройства в сети имеют локальные IP адреса, которые не могут быть напрямую доступны извне сети. Поэтому NAT изменяет порт исходного пакета, чтобы он мог быть корректно доставлен обратно на внутреннее устройство.
Пример кода на PHP, демонстрирующий это поведение:
// Создание сокета для отправки UDP пакета $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // Установка адреса и порта получателя $address = '192.168.1.100'; $port = 1234; // Отправка UDP пакета socket_sendto($socket, $data, strlen($data), 0, $address, $port); // Закрытие сокета socket_close($socket);
Если вы хотите сохранить исходный порт UDP пакета при прохождении через NAT, вам может потребоваться настроить NAT на использование статического портового преобразования (static port forwarding). Это позволит вам указать конкретные порты для конкретных устройств в сети, и тогда порт UDP пакета не будет изменяться при прохождении через NAT.
Надеюсь, это поможет вам понять, почему изменяется порт UDP пакета после маскарада. Если у вас возникли дополнительные вопросы, не стесняйтесь задавать.