Я сделал два эксперимента. Это сеть для них обоих:
[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.)