Назад | Перейти на главную страницу

пересылка пакетов iptables на один из двух шлюзов в зависимости от происхождения

Учитывая следующую установку:

old router  192.168.1.1     with NAT forward of tcp port 80 to 192.168.1.10:80
new router  192.168.1.2     with NAT forward of tcp port 80 to 192.168.1.10:80
web server  192.168.1.10    with default gateway 192.168.1.1

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

Для беспрепятственного перехода на новый маршрутизатор (с другим внешним IP-адресом) я хочу сначала настроить новый маршрутизатор, протестировать все это с активными обоими подключениями, а затем изменить IP-адрес DNS на новый внешний адрес.

Теперь, с описанной выше настройкой, старый маршрутизатор все еще работает. Но TCP-соединения, которые адресованы новому маршрутизатору, также обрабатываются старым маршрутизатором, который не может их обработать.

Я думал об использовании nat с маскированием, но тогда весь трафик, адресованный новому маршрутизатору, будет выглядеть как локальный трафик. Это обманывает серверные IP-фильтры и ведение журнала.

Теперь я планирую использовать вспомогательный компьютер с Debian и iptables для временного решения:

old router  192.168.1.1     with NAT forward of tcp port 80 to 192.168.1.10:80
new router  192.168.1.2     with NAT forward of tcp port 80 to 192.168.1.20:80
web server  192.168.1.10    with default gateway 192.168.1.20
helper pc   192.168.1.20

вспомогательный компьютер теперь отвечает за поиск правильного шлюза:

Я нашел много отзывов в Интернете, особенно на serverfault.com (особенно этот), но все они охватывают только одну часть этой проблемы. Я думаю, ему нужна комбинация правил фильтрации на основе MAC-адресов -m mac --mac-source <mac>, NAT, состояния и rt_tables --set-mark / ip rule add fwmark (Похоже, что --gw не поддерживается Debian).

В зависимости от сценария есть два эффективных решения.

Решение 1. Веб-сервер - Linux и полностью под вашим контролем.

Во-первых, убедитесь, что /etc/iproute2/rt_tables содержит следующие строки:

201     gw1
202     gw2

Во-вторых, заполните таблицы

ip route add table gw1 default via $GW1_IP dev $ETH metric 100
ip route add table gw2 default via $GW2_IP dev $ETH metric 100

В-третьих, создайте два правила iproute2 для «шунтирования» обработки этих настраиваемых таблиц:

ip rule add prio 100 from all fwmark 1 lookup gw1
ip rule add prio 110 from all fwmark 2 lookup gw2

Наконец, создайте набор команд iptables для правильной маркировки соответствующих пакетов:

# Make sure mark exists before routing happens
#   The first handles incoming packets
-t mangle -A PREROUTING -j CONNMARK --restore-mark
#   The second handles outgoing packets
-t mangle -A OUTPUT     -j CONNMARK --restore-mark

# Mark packets and save the mark    
-t mangle -A INPUT -m mac --mac-source $GW1_MAC -j MARK --set-mark 1
-t mangle -A INPUT -m mac --mac-source $GW2_MAC -j MARK --set-mark 2
-t mangle -A INPUT -j CONNMARK --save-mark

Решение 2. Веб-сервер не Linux и / или это не полностью под вашим контролем

Это решение очень аналогично предыдущему решению. Разница в наборе правил iptables:

# Make sure mark exists before routing happens
-t mangle -A PREROUTING -j CONNMARK --restore-mark

# Mark packets and save the mark    
-t mangle -A FORWARD -m mac --mac-source $GW1_MAC -j MARK --set-mark 1
-t mangle -A FORWARD -m mac --mac-source $GW2_MAC -j MARK --set-mark 2

-t mangle -A POSTROUTING -j CONNMARK --save-mark

Изменить: модифицированное решение 2

То же, что и выше, но с добавлением:

ip rule add prio 10 to 192.168.1.0/24 lookup main

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

Также добавьте еще iptables правило:

-t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10

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

Если это только для локального теста, вы можете использовать параметр -s в iptables, чтобы сообщить своему старому маршрутизатору, что если трафик исходит с этого исходного IP-адреса, перенаправить его на новый маршрутизатор. Затем ваш новый маршрутизатор будет перенаправлять ваш запрос на веб-сервер (в зависимости от предоставленной вами конфигурации).

Даже если вы проводите тестирование извне, вы все равно можете отфильтровать исходный IP-адрес с помощью -s.

Пример:

iptables -I PREROUTING -i eth0 -s x.x.x.x -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80