Пересылка пакетов 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-адресом) я хочу сначала настроить новый маршрутизатор, протестировать все вместе с активными обоими подключениями, а затем изменить DNS-IP на новый внешний адрес.

Теперь с вышеупомянутой настройкой старый маршрутизатор все еще работает. Но соединения 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

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

  • сохранить состояние соединений, которые были перенаправлены с помощью 192.168.1.2, и переслать их, не изменяя на 192.168.1.10 (я думаю об идентификации их по их MAC-адресу источника и SYN)
  • пересылать пакеты отслеживаемых соединений на 192.168.1.2
  • пересылать пакеты неотслеживаемых соединений на 192.168.1.1

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

2 ответа

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

Решение 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
Другие вопросы по тегам