Учитывая следующую установку:
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).
В зависимости от сценария есть два эффективных решения.
Во-первых, убедитесь, что /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
Это решение очень аналогично предыдущему решению. Разница в наборе правил 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
То же, что и выше, но с добавлением:
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