iptables/ebtables/bridge-utils: PREROUTING/FORWARD на другой сервер через один сетевой адаптер

У нас есть ряд правил iptables для переадресации соединений, которые надежны и работают хорошо.

Например, порт 80 перенаправляет на порт 8080 на том же компьютере (веб-сервер). Когда данный веб-сервер перезапускается, мы пересылаем запросы на другой IP-адрес через порт 8080, который отображает страницу обслуживания. В большинстве случаев этот другой IP-адрес находится на отдельном сервере.

Это все работало отлично, пока мы не установили bridge-utils и не переключились на использование моста br0 вместо eth0 в качестве интерфейса.

Причина, по которой мы перешли на использование мостового интерфейса, состоит в том, чтобы получить доступ к возможностям ebtables MAC SNAT/DNAT. У нас нет другой причины добавлять мостовой интерфейс на серверы, поскольку они фактически не соединяют соединения через несколько интерфейсов.

Я знаю, что это странная причина для добавления моста на серверы, но мы используем возможности MAC SNAT/DNAT в новом проекте, и ebtables казался самым безопасным, быстрым и простым способом, так как мы уже так хорошо знакомы с Iptables.

Проблема заключается в том, что после преобразования в интерфейс br0 пересылка iptables PREROUTING на внешние серверы больше не работает.

Внутренняя пересылка PREROUTING работает нормально (например, запрос поступает на порт 80, он пересылается на порт 8080).

Цепочка OUTPUT также работает (например: мы можем подключиться из коробки через локальный IP-адрес назначения:8080, а цепочка OUTPUT сопоставляет его с IP-адресом сервера обслуживания на другом сервере, порту 8080 и возвращает веб-страницу).

Тем не менее, любой трафик, поступающий в коробку, кажется, прекращается после правила PREROUTING, если IP-адрес назначения является внешним.

Вот пример нашей установки:

Старая настройка:

iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT - к месту назначения $MAINTIP:8080
iptables -a FORWARD --in-interface eth0 -j ПРИНЯТЬ
iptables -t nat -A POSTROUTING -out-interface eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Новая настройка: (пробовал старую настройку в различных форматах..., пытался регистрировать пакеты eth0 и br0)

iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT - к месту назначения $MAINTIP:8080
iptables -a FORWARD --in-interface br0 -j ПРИНЯТЬ
iptables -t nat -A POSTROUTING --out-interface br0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Перед изменением на br0 клиентский запрос отправляется на сервер A через порт 9080, а затем MASQUERADED отключается на другой сервер $MAINTIP.

Как объяснено выше, это прекрасно работает, если $ MAINTIP находится на той же машине, но если он находится на другом сервере, пакет никогда не отправляется в $ MAINTIP при новой установке br0.

Мы хотим, чтобы пакеты выходили с того же интерфейса, на котором они входили, MASQUERADED, как они делали до того, как мы переключились на использование моста с одним NIC (br0/bridge-utils).

Я попытался добавить протоколирование на всех этапах в iptables. По какой-то причине цель TRAP iptables не работает в этой настройке, поэтому я не могу получить журнал TRACE, но пакет отображается в таблице PREROUTING, но после этого кажется, что он автоматически отбрасывается.

Я ознакомился с этим прекрасным документом и лучше понимаю поток между iptables и ebtables: http://ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html

Насколько я понимаю, кажется, что мост не пересылает пакеты с того же интерфейса, с которым они пришли, а отбрасывает их. Если бы у нас был добавлен второй интерфейс, я полагаю, что он будет перенаправлять их на этот интерфейс (на другой стороне моста) - именно так мосты должны работать;-)

Можно ли заставить эту работу работать так, как мы хотим, и ПРЕДОТВРАТИТЬ / НАПРАВЛЯТЬ эти пакеты через тот же интерфейс, с которым они пришли, как мы привыкли?

Я надеюсь, что есть некоторые правила ebtables, которые могут работать в сочетании с правилами iptables PREROUTING/FORWARD/POSTROUTING, чтобы пересылка iptables работала так, как это обычно происходит, и отправлять маршрутизированные пакеты из br0 (eth0) вместо их отбрасывания.

Комментарии, пламя, любые советы приветствуются!

С наилучшими пожеланиями, Нил

2 ответа

Я думаю, что вы сделали, но просто чтобы быть уверенным, вы добавили eth0 к мосту?

Хотя я не уверен, в чем проблема, я дам несколько советов по отладке, которые могут помочь вам или другим при отладке проблем bridge/ebtables/iptables:

Убедитесь, что "/proc/sys/net/bridge/bridge-nf-call-iptables" включен (1)
Это приводит к тому, что трафик моста проходит через код iptables сетевого фильтра.

Обратите внимание, что это может повлиять на производительность.

Проверьте перехват пакетов по правилам ebtabels / iptables,
Используйте команды:

iptables -t nat -L -n -v   

ebtables -t nat -L –Lc  

Это может помочь вам понять, совпадает ли трафик с перехватом или нет.
Проверьте, что трафик IP NAT появляется в таблице conntrack:

conntrack –L (if installed)  

Или же

cat /proc/net/nf_conntrack  

Проверьте MAC изучения моста

brctl showmacs br0  

Используйте tcpdump на eth0 и на br0, чтобы проверить, видны ли пакеты в обоих, как ожидалось
Используйте параметр -e, чтобы увидеть MAC-адрес.

Для отладки попробуйте перевести интерфейс моста в случайный режим, возможно, мост получает пакеты с другим MAC-адресом (в случайном режиме он также будет принимать другой MAC)

Возможно установить задержку переадресации моста на 0

brctl setfd br0 0  

И отключить STP (протокол связующего дерева)

brctl stp br0 off  

Как выглядит ваша таблица маршрутизации?
Попробуйте добавить конкретное или правило маршрута по умолчанию с помощью "dev br0"

Я надеюсь, что это немного помогает...
Удачи

Хорошо всего 1,5 года, но может быть полезно для последующих поисков. Глядя на вашу ссылку только сейчас, он говорит, что в частности, там, где brouting будет игнорировать пакет, если MAC находится на той же стороне моста (а не на другом порту или самом мосте (см. Рис. 2.b в вашей ссылке).

В дополнение к этому, я просто цитирую по этой ссылке: http://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxBridge

"... ebtables DROP vs iptables DROP

В iptables, который в большинстве случаев используется для фильтрации сетевого трафика, цель DROP означает "исчезновение пакета".

В ebtables "-j redirect --redirect-target DROP" означает, что "пакет перешел с моста в верхние уровни ядра, такие как маршрутизация \ пересылка" (<- соответствующий бит!)

Поскольку ebtables работает на канальном уровне соединения, чтобы перехватить соединение, мы должны "перенаправить" трафик до уровня, который iptables сможет перехватить \ tproxy.

И в этом ваш ответ (ставка добавлена ​​для будущих посетителей, конечно, если вы еще не участвуете в этом, p)

Другие вопросы по тегам