Почему NAT не резервирует порты из пула портов TCP и UDP машины?


8

Я сделал два эксперимента. Это сеть для них обоих:

        [private network]     [public network]
    A -------------------- R ----------------- B
192.168.0.5     192.168.0.1|192.0.2.1       192.0.2.8

Шлюз по умолчанию имеет значение R . R имеет активную пересылку IPv4 и следующее правило iptables:

iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 50000

Намерение, что любой TCP от A будет маскироваться как 192.0.2.1, используя порт 50000 R.

Я опубликовал службу TCP на порт 60000 на B, используя nc -4l 192.0.2.8 60000.

Затем я открыл соединение от A :nc -4 192.0.2.8 60000

А начал отправлять пакеты, которые выглядели так:

192.168.0.5:53269 -> 192.0.2.8:60000

R перевел это на

192.0.2.1:50000 -> 192.0.2.8:60000

Все идет нормально.

Затем я попытался открыть следующий клиент на R : nc -4 192.0.2.8 60000 -p 50000. Я отправлял сообщения, ничего не происходит. Никакие пакеты не могут быть замечены на R 'tcpdump.

Поскольку существует правило маскарада или, по крайней мере, потому что оно активно, я ожидал, что R 'nc потерпит неудачу с сообщением об ошибке "nc: Address уже используется", что происходит, если я связываю два ncs с одним и тем же портом.

Затем я немного подождал, чтобы карта Контрака умерла.

Второй эксперимент состоял в том, что я сначала пытался открыть клиент R. R начинает говорить с B очень хорошо. Если я тогда открою соединение от A , его пакеты игнорируются. А сигналы SYN «s прибывают в R , но они не ответили, даже не ошибки ICMP. Я не знаю, связано ли это с тем, что R знает, что у него закончились маскирующиеся порты, или потому что Linux просто беспорядочно запутан (он технически маскирует порт, но уже установленное соединение как-то мешает).

Я чувствую, что поведение NAT неверно. Я мог бы случайно настроить порт как для маскировки (в частности, не указав --to-portsво время правила iptables), так и для службы, и ядро ​​будет молча сбрасывать соединения. Я также нигде не вижу ничего подобного.

Например:

  • Делает обычный запрос B . R маскирует порт 50k.
  • Делает DNS запрос к R . Поскольку T является рекурсивным, R (используя, по чистой случайности, эфемерный порт 50k) запрашивает авторитетный сервер имен Z на порту 53.

Столкновение только что произошло; R теперь использует порт 50k для двух отдельных соединений TCP.

Я думаю, это потому, что вы обычно не публикуете сервисы на маршрутизаторах. Но опять же, не повредит ли ядру «заимствовать» порт из пула портов TCP, когда он станет активно маскироваться?

Я знаю, что могу отделить свои эфемерные порты от своих --to-ports. Тем не менее, это не похоже на поведение по умолчанию. И NAT, и временные порты по умолчанию имеют значение 32768-61000, что является жутким.

(Я нашел эфемерный диапазон, запросив / proc / sys / net / ipv4 / ip_local_port_range, и диапазон NAT, просто перебирая множество UDP-запросов в отдельном эксперименте и печатая исходный порт на стороне сервера. Я не смог найти способ распечатать диапазон, используя iptables.)


2
Почему жутко, что NAT использует эфирный диапазон портов? Если клиент на A использует временный порт, также используемый на R, он получает NAT на новый. И почему такой сервис, как DNS или DHCP на R, как-то связан с этим? DNS и DHCP не используют эфемерные порты (на стороне сервера). И зачем использовать только один порт для маскировки?
Томас Эркер

@Thomas: Ваши вопросы фактически привели меня в правильном направлении, и я очень благодарен, но, похоже, у вас также есть небольшое заблуждение: если клиент на A использует эфемерный порт, также используемый на R, это не обязательно получить NAT к свежему; NAT не запрашивает пулы портов TCP / UDP. Я действительно заметил, что сталкивающиеся соединения NAT являются нормальными и безвредными; смотри мой ответ.
Yd Ahhrk

@ Томас: я не продумал DHCP; Я на самом деле думал о DNS. Я предполагаю, что DNS использует эфемерные порты, если это рекурсивный сервер имен (для запроса авторитетных); см. мое редактирование
Yd Ahhrk

@Thomas: весь эксперимент предназначен для того, чтобы увидеть, что происходит при столкновениях; Я уменьшил эфемерный диапазон до одного порта, чтобы вызвать столкновение.
Yd Ahhrk

Ответы:


2

Не повредит ли ядру «заимствовать» порт из пула портов TCP, когда он станет активно маскироваться?

Я думаю, что ответ «нет, но это не имеет большого значения».

Я неправильно предположил, что R использовал только транспортный адрес назначения пакета ответа, чтобы сказать, направлялся ли он к A или сам. На самом деле кажется, что для определения соединения используется полный кортеж транспортных адресов источника-получателя. Таким образом, для NAT вполне нормально создавать несколько соединений с использованием одного ( принадлежащего R ) порта; это не создает путаницы. Следовательно, пулы портов TCP / UDP не имеют значения.

Теперь это очевидно, когда я об этом думаю.

Затем я попытался открыть следующий клиент на R : nc -4 192.0.2.8 60000 -p 50000. Я отправлял сообщения, ничего не происходит. Никакие пакеты не могут быть замечены на R 'tcpdump.

Это часть экспериментов, где я все испортил.

Ошибка происходит потому, что оба транспортных адреса источника и назначения совпадают, а не только потому, что адрес источника одинаков.

Если я скажу nc -4 192.0.2.8 60001 -p 50000, это действительно работает. Даже если он использует тот же порт, что и маска NAT.

Я чувствую, что поведение NAT неверно. Я мог бы случайно настроить порт как для маскировки (в частности, не указав --to-portsво время правила iptables), так и для службы, и ядро ​​будет молча сбрасывать соединения.

Этого не произойдет, потому что маскированные соединения и R- запущенные соединения, скорее всего, будут иметь разные пункты назначения.

Поскольку существует правило маскарада или, по крайней мере, потому что оно активно, я ожидал, что R 'nc потерпит неудачу с сообщением об ошибке "nc: Address уже используется", что происходит, если я связываю два ncs с одним и тем же портом.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.