Рейтинг:0

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

флаг jp

Я наблюдал странное поведение в Linux:

Во-первых, я очищаю все маршруты и правила iptables:

основная таблица IP-маршрутов
IP-маршрутная таблица сброса по умолчанию
локальная таблица IP-маршрутов
iptables -P ВВОД ПРИНЯТЬ
iptables -P ПЕРЕДАТЬ ПРИНЯТЬ
iptables -P ВЫВОД ПРИНЯТЬ
iptables -t физ -F
iptables -t мангл -F
iptables-F
iptables -X
ip6tables -P ВВОД ПРИНЯТЬ
ip6tables -P ПЕРЕДАТЬ ПРИНЯТЬ
ip6tables -P ВЫВОД ПРИНЯТЬ
ip6tables -t физ -F
ip6tables -t мангл -F
ip6tables -F
ip6tables -X

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

ip route add local 127.0.0.1 dev lo proto область ядра host src 127.0.0.1 table local

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

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

iptables -t nat -A POSTROUTING -j MASQUERADE

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

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

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

Saïmonn avatar
флаг in
Я предполагаю, что правило MASQUERADE изменяет порт исходного пакета, тем самым искажая возвращаемый пакет. Не могли бы вы опубликовать вывод из tcpdump, запущенного на локальном хосте, пока вы играете с netcat? Я уверен, что это могло бы приблизить нас к поддающемуся проверке ответу.
Рейтинг:1
флаг in

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

Обычно как МАСКАРАД работает, он выбирает адрес, который настроен на исходящий интерфейс (который определяется маршрутизацией, следовательно, РАЗМЕЩЕНИЕ) для исходного NAT, который он выполняет. (Если на интерфейсе назначено несколько адресов, он, вероятно, выберет первый или тот, который установлен в качестве предпочтительного исходного адреса в соответствующем маршруте; я не очень знаком с этим, и это выходит за рамки здесь тем не мение). Это не имеет ничего общего с адресом nexthop/gateway маршрута по умолчанию. (В любом случае это не то, как работает исходный NAT.)

Однако, когда дело доходит до интерфейса вот, все становится немного сложнее. Точнее, это, похоже, не связано с самим интерфейсом (кроме того, что это будет исходящий интерфейс, потому что адрес назначения является локальным адресом), а скорее с тем, что адреса в 127.0.0.0/8 блок не в тему Глобальный. Хотя я понятия не имею, что происходит за кулисами, кажется, что трафик не может «появиться», если у хоста нет области видимости. Глобальный IP-адрес настроен, но попытка МАСКАРАД.

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

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

Если вам действительно нужно правило, позволяющее МАСКАРАД на всех интерфейсах, кроме вот, вы можете иметь:

iptables -t nat -A ОТПРАВКА ! -o lo -j МАСКАРАД
Рейтинг:1
флаг us

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

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

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

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

iptables -t nat -A POSTROUTING -o <if> -j MASQUERADE
Рейтинг:0
флаг jp

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

Действительно, кажется, что вот интерфейс и 127.0.0.1 следовать своим правилам.

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

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

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

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

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

Я предполагаю, что MASQUERADE выбирает исходный IP-адрес аналогичным образом.

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

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

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