Пересылка пакетов 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