почему MASQUERADE SNAT может блокировать соединение localhost?

Я заметил странное поведение в Linux:

Сначала я очищаю все маршруты и правила iptables:

ip route flush table main
ip route flush table default
ip route flush table local
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -F
ip6tables -X

Затем я добавляю локальный маршрут:

ip route add local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 table local

Затем на терминале я открываю порт с помощью nc -lp 12345 , а на другом терминале я подключаюсь к это с nc 127.0.0.1 12345 , и я могу отправлять и получать данные между сервером netcat и клиентом. Так что пока все в порядке.

Теперь, после того, как я убил предыдущий сервер и клиент netcat, если я запустил:

iptables -t nat -A POSTROUTING -j MASQUERADE

и перезапускаю сервер netcat, клиент не сможет подключиться . Вы знаете, почему?

Я заметил, что добавление ip route add local 192.168.0.10 dev wlan0 proto kernel scope host src 192.168.0.10 table local заставляет соединение netcat снова работать. Однако я не понимаю, почему интерфейс wlan0 (IP-адрес которого 192.168.0.10) может влиять на интерфейс обратной связи?

Для информации я использую ArchLinux

0
задан 15 July 2021 в 18:31
3 ответа

Я не знаю если это ошибка или намеренный откат, но, как я могу видеть здесь, это не имеет ничего общего ни с упомянутым вами локальным маршрутом wlan0 , ни со всем шлюзом по умолчанию, бла-бла (без обид, но для меня это почти не имеет смысла) сказано в другом / "правильном" ответе.

Обычно MASQUERADE работает так: он выбирает адрес, настроенный на исходящем интерфейсе (который определяется маршрутизацией, следовательно, POSTROUTING ) для исходный NAT, который он выполняет.(Если на интерфейсе назначено несколько адресов, он, вероятно, выберет первый или тот, который установлен в качестве предпочтительного исходного адреса в соответствующем маршруте; я не очень знаком с этим, и это выходит за рамки здесь в любом случае). Это не имеет ничего общего с адресом следующего магазина / шлюза маршрута по умолчанию. (В любом случае NAT работает по-другому.)

Однако, когда дело доходит до интерфейса lo , все становится немного сложнее. Точнее, похоже, это как-то связано не с самим интерфейсом (помимо того факта, что это будет исходящий интерфейс, потому что местом назначения является локальный адрес), а скорее с тем фактом, что адреса в 127.0 Блок .0.0 / 8 не входит в область global . Хотя я понятия не имею, что происходит за кулисами, кажется, что трафик не может «проявиться», если хост не имеет настроенного IP-адреса области global , но пытается MASQUERADE .

Я вижу здесь, даже если вы просто настроите адрес, действительный для области global (например, 192.168.0.10/32 ) на любом интерфейсе (включая ] lo ), вы увидите, что он снова работает. (Упомянутый вами локальный маршрут будет добавлен автоматически. Но я не вижу, чтобы здесь работало добавление только маршрута.)

Как бы то ни было, адреса и интерфейсы не сильно связаны друг с другом в Linux (не прямым способом, например, он будет отвечать на трафик только в том случае, если их адрес назначения совпадает с настроенным адресом на входящем интерфейсе, даже если когда переадресация IP не имеет значения). Так что это может иметь какое-то отношение к этому: в случае, если MASQUERADE не может выбрать адрес области глобальный из того, что настроено на исходящем интерфейсе, он просто выбирает один из любого (я сомневаюсь, что хотя приоритет имеет какое-то отношение к маршруту по умолчанию), если все еще нет, он просто отказывается работать каким-то образом.

Если вам действительно нужно правило, которое включает MASQUERADE на всех интерфейсах, кроме lo , вы можете иметь:

iptables -t nat -A POSTROUTING ! -o lo -j MASQUERADE
1
ответ дан 28 July 2021 в 13:56

В дополнение к другим ответам я провел еще несколько экспериментов. Пожалуйста обратите внимание, что это только мои выводы, я не искал внутри исходного кода ядра (но если у вас есть документация, поделитесь).

Действительно, похоже, что интерфейс lo и 127.0.0.1 подчиняются своим собственным правилам.

Для других интерфейсов, вот как я считаю, что исходный IP-адрес назначается пакету (не говоря уже о MASQUERADE или таких вещах, как сырые сокеты):

Когда кто-то пытается отправить пакет на целевой IP-адрес, Linux будет поиск подходящего правила маршрутизации добавлен, например:

ip route add <NETWORK>/<PREFIX> dev <INTERFACE_XX> [src <SRC_IP>]

Если указан параметр src (это, кажется, подразумевает добавление правила типа ip route add local dev ]. Обратите внимание, что INTERFACE_XX и INTERFACE_YY не должны совпадать, что удивительно), тогда пакет отправляется на интерфейс INTERFACE_XX с SRC_IP в качестве IP-адреса источника.

Если параметр src не указан, он будет отправлять пакет на INTERFACE_XX , а адрес источника выбирается путем поиска первого действительного IP-адреса на интерфейсе от первого запущенного до последний (за исключением lo). Если IP-адрес не найден, IP-адрес источника устанавливается на 0.0.0.0. Если у интерфейса несколько IP-адресов, выбирается первый. Как ни странно, это означает, что пакет не обязательно имеет IP-адрес выходного интерфейса, на который он отправляется.

Думаю, MASQUERADE выбирает IP-адрес источника аналогичным образом.

Пожалуйста, поправьте меня, если вы думаете, что что-то не так.

0
ответ дан 28 July 2021 в 13:56

Это обоснованное предположение. Параметр MASQUERADE заменяет исходный IP-адрес в IP-пакетах на адрес, который он решает использовать. Я думаю, что в этом случае он заменяет исходный адрес адресом интерфейса, по которому доступен шлюз по умолчанию.

Итак, если ваш шлюз по умолчанию - 192.168.0.1 , адрес источника пакета заменяется на 192.168.0.1 . Назначение - 127.0.0.1 , и это не работает должным образом.

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

Вы можете сделать это с помощью следующей команды:

iptables -t nat -A POSTROUTING -o <if> -j MASQUERADE
1
ответ дан 28 July 2021 в 13:56

Теги

Похожие вопросы