Вопрос или проблема
У меня есть 3 Linux машины, как показано ниже:
Машина 1 Машина 2 Машина 3
----------------------- ------------------------ -----------------------
| eth0: 172.17.0.1/16 |======| eth0: 172.17.0.2/16 | | |
| | | | | |
| | | eth1: 172.18.0.2/16 |======| eth0: 172.18.0.1/16 |
----------------------- ------------------------ -----------------------
Я использую smcroute для добавления маршрута на машине 2, чтобы отправлять трафик для мультикаст-группы 239.255.0.1 с машины 1 на машину 3:
smcroutectl add eth0 239.255.0.1 eth1
И я включаю IP маскарадинг на интерфейсе eth1 на машине 2:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
И я подписываюсь на эту группу на машине 3:
smcroutectl join eth0 239.255.0.1
Тогда я думаю, что должен быть в состоянии пинговать этот мультикаст-адрес с машины 1, используя
ping 239.255.0.1 -t 2
Используя tcpdump, я получаю следующее через eth1 на машине 2:
00:35:19.798686 IP 172.18.0.2 > 239.255.0.1: ICMP echo request, id 133, seq 12, length 64
00:35:19.798739 IP 172.18.0.1 > 172.18.0.2: ICMP echo reply, id 133, seq 12, length 64
Но ответ не де-NATится и не отправляется на машину 1. Я думаю, это потому что nat ожидает, что исходный IP будет мультикаст-адресом:
/# conntrack -L
icmp 1 29 src=172.17.0.1 dst=239.255.0.1 type=8 code=0 id=130 [UNREPLIED] src=239.255.0.1 dst=172.18.0.2 type=0 code=0 id=130 mark=0 use=1
conntrack v1.4.6 (conntrack-tools): 1 flow entries have been shown.
Но ядро будет отвечать на мультикаст-пинг с ip интерфейса, на котором мы присоединились к группе, так что ответ будет отброшен на машине 2. Как я могу обойти это и получить ответ обратно на машину 1?
Ответ или решение
Рассмотрим ситуацию, когда отзывчивость на многоадресные ICMP-запросы не должным образом де-натируется в Linux-системе. В данном случае у нас есть три машины с конфигурацией сетевых интерфейсов, как указано в описании проблемы. Машина 1 находится в сети 172.17.0.0/16, Машина 2 имеет по одному интерфейсу в двух сетях: 172.17.0.0/16 и 172.18.0.0/16, а Машина 3 находится в сети 172.18.0.0/16.
Теория
В сетях IP многоадресная передача (multicast) позволяет одному узлу отправлять пакеты в заранее определенную группу адресов. Например, адрес 239.255.0.1 относится к диапазону многоадресных адресов, которые используются для локального администрирования. Когда узел отправляет ICMP-запрос на многоадресный адрес, ожидается, что любой узел, подписанный на этот адрес, ответит.
Для маршрутизации многоадресного трафика в Linux обычно используется утилита smcroute, которая добавляет маршруты для таких групп между различными интерфейсами. В данном сценарии, машина 2, работая в качестве промежуточного узла, должна транслировать трафик из одной сети в другую и управлять трансляцией адресов сети (NAT) через таблицу iptables
.
Сложность этого сценария возникает из-за NAT-правил, которые машинально заменяют исходные и целевые адреса IP. Типичная задача NAT – модификация исходящих пакетов таким образом, чтобы они выглядели как исходящие из одного известного внешнего IP, который может быть маршрутизирован в сетях.
Пример
В данном сценарии машина 2 выполняет IP маскарад на интерфейсе eth1 командой:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Это означает, что исходящие пакеты на eth1 будут автоматически заменять свой исходный адрес на адрес интерфейса eth1 (172.18.0.2).
Затем на машине 2 вы настроили smcroute для маршрутизации трафика многоадресной группы:
smcroutectl add eth0 239.255.0.1 eth1
Подписка на данную группу на машине 3 осуществляется командой:
smcroutectl join eth0 239.255.0.1
Когда с машины 1 отправляется пинг на многоадресный адрес:
ping 239.255.0.1 -t 2
Вы видите, что ICMP-эхо-запрос отправляется от 172.18.0.2 к 239.255.0.1, а эхо-ответ приходит от 172.18.0.1 к 172.18.0.2, но де-NATинг не происходит.
Применение
Так как NAT ожидает, что исходный IP адрес эхо-ответа будет совпадать с адресом назначения эхо-запроса (239.255.0.1), это вызывает проблему: ответный пакет приходит c IP адресом 172.18.0.1, то есть смещенным адресом интерфейса, из которого происходит подписка на группу. Это поведение соответствует стандартам работы IP-стека, так как возвратный пакет использует адрес сетевого интерфейса, к которому было привязано многоадресное подключение.
Для решения этой проблемы можно предпринять несколько шагов:
-
Управляемый NAT: Создать более детализированные правила NAT, которые разрешат де-NAT для соответствующего источника. Это может включать в себя создание специфичных правил для обработки ICMP-ответов вместо применения маскарадинга.
-
Политики обратного маршрутизации: Правила для таких ситуаций могут быть созданы с применением iproute2, чтобы гарантировать, что трафик будет корректно маршрутизироваться обратно к исходной машине.
-
Изменение конфигурации ответной политики: Возможно, потребуется внесение изменений в конфигурации сетевой политики машины 2 или применение более сложных механизмов маршрутизации, таких как PBR (Policy Based Routing).
-
Использование прокси-машины: Установка трансляционного прокси, который может управлять и преобразовывать входящие и исходящие ICMP трафики, освобождает сетевые компоненты от необходимости выполнять преобразование.
Эти подходы помогут обеспечить правильное поведение ICMP-ответов, де-NATинг и маршрутизацию. Однако каждое решение имеет свои издержки и сложность внедрения, и выбор должен основываться на конкретных требованиях сети и доступных ресурсах.