Переадресация портов с двумя маршрутизаторами

Переадресация портов с двумя маршрутизаторами

У меня есть серверы за двумя разными публичными IP-адресами, и я использую DNAT для отправки трафика на разные внутренние серверы в зависимости от порта.


-------------------------                  -----------------------
| server a (port 80/tcp)|                  |       router A      |
|   (eth0) 192.168.1.123|..................|192.168.1.1 (eth1)   |
-------------------------         :        |       (eth0) 1.2.3.4|............
                                  :        -----------------------           :
                                  :                                          :
                                  :        -----------------------           :.... INTERNET
-------------------------         :        |       router B      |           :
| server a (port 25/tcp)|         :        |       (eth0) 2.3.4.5|...........:
|   (eth0) 192.168.1.234|..................|192.168.1.2 (eth1)   |
-------------------------                  -----------------------

На маршрутизаторах A и BI включена переадресация и следующие iptables:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 25 -j DNAT --to 192.168.1.234
iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.123

На самом деле у меня на серверах A и B добавлен следующий маршрут:

route add default gw 192.168.1.1

Таким образом, весь внутренний трафик в Интернет проходит через маршрутизатор A, а весь трафик на порты 25 и 80 корректно отправляется на серверы A и B, но соединения работают только в том случае, если трафик проходит через маршрутизатор A. Действительно, трафик через маршрутизатор B поступает на серверы, но возвращается через маршрутизатор A вместо B, поэтому соединения не работают.

Я добавил новый маршрут на серверах:

route add default fw 192.168.1.2

route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
0.0.0.0         192.168.1.2     0.0.0.0         UG    0      0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0

Но связь по-прежнему не работает.

Как мне это сделать?

Не так уж важно балансировать трафик Внутренний -> Внешний, но хочется, чтобы все входящие соединения из Интернета на внешние IP-адреса устанавливались корректно.

ПРИМЕЧАНИЕ: Я также пытался выполнить DNAT на одном из маршрутизаторов по внешнему IP-адресу другого маршрутизатора, но они находятся в разных сетях, и это не сработало:

iptables -t nat -I PREROUTING -p tcp --dport 25 -d ${ExternalIPA} -i eth0 -j DNAT --to ${ExternalIPB}

решение1

Ваша текущая настройка не будет работать так, как задумано. Вам нужен виртуальный IP, который будет плавать над Router-Aи Router-B. Это также позволит сбалансировать нагрузку между двумя маршрутизаторами с простотой. В этом примере я буду использовать отраслевой стандартВРРПна маршрутизаторе Linux (Ubuntu-16).

Вот процедура:

В Linux Router-Aи Router-Bвыполните следующие команды:

$ sudo echo "net.ipv4.ip_nonlocal_bind=1" >> /etc/sysctl.conf
$ sudo sysctl -p

Установить keepalived на обоих маршрутизаторах

$ sudo apt-get update
$ sudo apt-get install keepalived -y

Затем перейдите к Router-Aтому, что будет действовать как MASTER. Создайте новый файл конфигурации /etc/keepalived/keepalived.confсо следующими записями:

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    virtual_router_id 50
    priority 101

    authentication {
        auth_type AH
        auth_pass pass123
    }

    virtual_ipaddress {
        192.168.1.99
    }
}

Затем перейдите к Router-Bтому, что будет действовать как BACKUP, и сделайте то же самое с новым файлом конфигурации /etc/keepalived/keepalived.conf:

vrrp_instance VI_1 {
    interface eth1
    state BACKUP
    virtual_router_id 50
    priority 100

    authentication {
        auth_type AH
        auth_pass pass123
    }

    virtual_ipaddress {
        192.168.1.99
    }
}

Объяснение:

net.ipv4.ip_nonlocal_bind=1сообщает ядру, что виртуальный IP-адрес НЕ должен быть привязан к какому-либо физическому интерфейсу.

vrrp_instance VI_1должны совпадать на обоих маршрутизаторах. Это идентификатор, поскольку на одном маршрутизаторе может работать несколько VRRP.

interface eth1— это интерфейс, обращенный к локальной сети (к внутренним серверам).

state MASTERRouter-Aи так state BACKUPдалее , Router-Bэто говорит само за себя.

virtual_router_id 50должны совпадать на обоих маршрутизаторах. Это идентификатор.

priority 101Router-Aи так priority 100далее Router-B(в этом случае маршрутизатор A имеет более высокий приоритет).

authenticationдолжны совпадать на обоих маршрутизаторах. В этом случае я использовал общий ключpassw123

virtual_ipaddressплавающий IP-адрес, который будет использовать VRRP. Этот IP-адрес должен совпадать на обоих маршрутизаторах. Этот IP-адрес не должен использоваться ни одним устройством в сегменте LAN. В этом случае я выбрал192.168.1.99

Включить службу keepalived

$ sudo systemctl enable keepalived

Запустить службу поддержки активности

$ sudo systemctl start keepalived

Пришло время изменить правила iptables на обоих маршрутизаторах.

Очистите все правила NAT с обоих маршрутизаторов (избавьтесь от неисправных правил NAT)

$ sudo iptables -t nat -F
$ sudo iptables -t mangle -F

Затем добавьте правильные правила NAT:

Маршрутизатор-А

$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 192.168.1.99
$ sudo iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 25 -j DNAT --to 192.168.1.234

Маршрутизатор-B

$ sudo iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 192.168.1.99
$ sudo iptables -t nat -A PREROUTING -d ${externalIP} -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.123

Это все, что вам нужно со стороны маршрутизатора. Теперь перейдите на серверы (Server-A и Server-B), удалите существующий шлюз по умолчанию ( 192.168.1.1) и назначьте новый шлюз ( 192.168.1.99)

$ sudo ip route del 0/0
$ sudo route add default gw 192.168.1.99

При установлении соединений из Интернета два сервера (Сервер-A и Сервер-B) будут возвращать трафик на виртуальный IP-адрес ( 192.168.1.99), который находится выше Router-AиRouter-B

Ссылка:https://www.keepalived.org/manpage.html

решение2

Наконец мне удалось заставить это работать без использования виртуального IP, по сути, используя CONNNMARK и добавляя различные маршруты:

ПРИМЕЧАНИЕ:

  • Маршрутизатор A eth1 MAC = AA:AA:AA:AA:AA:AA
  • Маршрутизатор B eth1 MAC = BB:BB:BB:BB:BB:BB

Мне нужно добавить следующие маршруты и iptables на все серверы, использующие асимметричные маршруты:

# add the two routing tables
ip route add to default table 11 via 192.168.1.1 dev eth0
ip route add to default table 33 via 192.168.1.2 dev eth0

# add the mark to the routing tables
ip rule add priority 99 table 11 fwmark 11
ip rule add priority 99 table 33 fwmark 33

# mark the packets that came from the different routes
iptables -t mangle -A OUTPUT ! -d 192.168.1.0/24 -m addrtype --dst-type UNICAST -j CONNMARK --restore-mark
iptables -A INPUT -i eth0 ! -s 192.168.1.0/24 -m addrtype --src-type UNICAST -m mac --mac-source AA:AA:AA:AA:AA:AA -j CONNMARK --set-mark 33
iptables -A INPUT -i eth0 ! -s 192.168.1.0/24 -m addrtype --src-type UNICAST -m mac --mac-source BB:BB:BB:BB:BB:BB -j CONNMARK --set-mark 11

Теперь все работает нормально. Все соединения из интернета к любому из внешних IP-адресов маршрутизируются через маршрутизатор, который управляет соединением DNAT.

Связанный контент