Настройка шлюза в случае внешнего порт-форвардинга

Итак, пусть в компании имеется два шлюза с внутренними IP адресами:

Шлюз с IP 192.168.0.90 выполняет проброс порта PPTP (TCP 1723) на другой шлюз с IP 192.168.0.250. Такое имеет место быть: Ubuntu-шлюз подключен к WiMax провайдеру Yota и не имеет доступного извне IP адреса, кроме того, IP адрес Ubuntu шлюз получает по DHCP из сети 10.0.0.0/8 (поэтому решение на базе DYNDNS отпадает). Win шлюз же имеет внешний постоянный адрес. Итак, вы настроили проброс с Win-шлюза по порту PPTP на Ubuntu шлюз, но ничего не работает… Посмотрим на таблицу маршрутизации на Ubuntu-шлюзе:

route -n
Таблица маршутизации ядра протокола IP
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.240   0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2
10.133.112.0    0.0.0.0         255.255.240.0   U     0      0        0 wimax0
0.0.0.0         10.133.112.1    0.0.0.0         UG    0      0        0 wimax0

Мы видим, что имеется 1 маршрут по-умолчанию, отсылающий пакеты к шлюзу провайдера Yota. Т.О., когда приходят проброшенные пакеты с Windows-шлюза, Ubuntu-шлюз отправляет их по маршруту по-умолчанию, что не приемлемо. Нужно сделать так, чтобы все проброшенные пакеты шли обратно по-тому же маршруту, по которому пришли. Решим проблему с помощью дополнительной таблицы маршрутизации.

1. Добавим в файл /etc/iproute2/rt_tables строку вида «Числовой_номер Имя_Таблицы»:

4 4

Для удобства я всегда присваиваю для обоих полей числовой номер. Мы создали новую дополнительную таблицу маршрутизации с номером 4 и именем 4. Пока она пуста: вывод ip route show table 4 пуст.

2. Будем работать с таблицей mangle IPtables. Таблица mangle используется для модификации проходящих пакетов TCP/IP и работаем с пятью «цепочками» (man iptables):

Поскольку мне нужно направить локально-сгенерированные пакеты по нужному маршруту, т.е. перед маршрутизацией, я выбираю цепочку OUTPUT. Пишем правило:

/sbin/iptables -t mangle -A OUTPUT -p TCP --sport 1723 -j MARK --set-mark 0x4
/sbin/iptables -t mangle -A OUTPUT -p GRE -s 192.168.0.250/32 -j MARK --set-mark 0x4 

Т.е. все локально-сгенерированные пакеты, с порта отправителя 1723, а также все GRE пакеты, помечаются меткой (как бы привязываются к нашей созданной ранее таблице маршрутизации).

Обратите внимание, значение после –set-mark указывается в 16-ричном виде, тогда как в /etc/iproute2/rt_tables значения хранятся в 10-виде.

3. Пишем простой скрипт для инициализации дополнительной таблицы маршрутизации:

#!/bin/sh

echo "Erase the route..."

INET_GW="192.168.0.90"

/bin/ip route flush cache
/bin/ip route flush table 4

echo "Copy main routing table to table 4 (ID 4)"

/bin/ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done
/bin/ip route add table 4 default via $INET_GW

/bin/ip rule add fwmark 4 table 4

/bin/echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter
/bin/echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

В этом скрипте мы очищаем таблицу маршрутизации и добавляем в нее все имеющиеся маршруты, кроме маршрута по-умолчанию. Маршрут по-умолчанию в таблице 4 теперь будет проходить через Win-шлюз (IP 192.168.0.90).

Теперь надо, чтобы дополнительная таблица маршрутизации инициализировалась каждый раз при старте системы, т.е. можно просто добавить в секцию объявления какого-либо сетевого интерфейса в /etc/network/interfaces соответствующую директиву up (я добавил в секции описания моего Wimax модема):

auto wimax0
iface wimax0 inet dhcp
pre-up iptables-restore < /etc/iptables.rules.2       # правила фаерволла, в которые добавлена директива по работе с таблицей mangles (см. выше)
up /root/scripts/setup.routing.table.sh

TAG: