ПРОБЛЕМА
Экземпляр сервера OpenVPN (tun
, udp
, порт 1194
) устанавливается на маршрутизаторе на основе Linux, который также запускает экземпляр клиента OpenVPN (tun
, udp
, порт 1197
), соединяющий его с поставщиком VPN. И клиент, и экземпляр сервера работают нормально по отдельности. Однако клиенты не могут подключиться к VPN-серверу, когда включен экземпляр VPN-клиента.
Я уверен, что это происходит потому, что экземпляр VPN-клиента изменяет main
таблицу маршрутизации так, чтобы весь трафик от (OUTPUT
) и через (FORWARD
) маршрутизатора направлялся к провайдеру VPN. Это желаемое поведение по умолчанию, но не для подключений, которые инициируются из Интернета.
Как настроить политику маршрутизации, используя iptables
и / или ip
, чтобы все (или, по крайней мере, VPN) соединения, инициированные из Интернета, маршрутизировались через стандартный шлюз по умолчанию (192.168.1.1
)?
НАСТРОИТЬ
LINUX ROUTER
-----------------------------------------
| LAN if: br-lan, 192.168.2.1/24 |
| VPN client if: tun0, 10.63.10.6/32 |
| VPN server if: tun1, 10.255.0.1/24 |
| DMZ if: eth0, 192.168.1.2/24 |
-----------------------------------------
|
GATEWAY ROUTER |
--------------------------
| DMZ if: 192.168.1.1/24 |
| WAN if: x.x.x.x/x |
--------------------------
|
INTERNET | VPN CLIENT OF LINUX ROUTER (public IP: y.y.y.y/y)
----------------- --------------------------------------
| |----| VPN client if: tun1, 10.255.0.6/24 |
----------------- --------------------------------------
|
|
VPN PROVIDER OF LINUX ROUTER
--------------------------------
| VPN server if: 10.63.10.1/32 |
--------------------------------
Как вы заметите, мы находимся в ситуации двойного NAT. Как бы неудобно это ни было, проблема не в этом, поскольку клиенты могут подключаться, когда экземпляр VPN-клиента отключен.
С включенными экземплярами VPN-клиента и сервера, это main
таблица маршрутизации, как указано в ip route list table main
:
0.0.0.0/1 via 10.63.10.5 dev tun0 #added by VPN client instance
default via 192.168.1.1 dev eth0 proto static
10.63.10.1 via 10.63.10.5 dev tun0 #added by VPN client instance
10.63.10.5 dev tun0 proto kernel scope link src 10.63.10.6 #added by VPN client instance
10.255.0.0/24 via 10.255.0.2 dev tun1
10.255.0.2 dev tun1 proto kernel scope link src 10.255.0.1
128.0.0.0/1 via 10.63.10.5 dev tun0 #added by VPN client instance
178.162.199.211 via 192.168.1.1 dev eth0 #added by VPN client instance
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2
192.168.2.0/24 dev br-lan proto kernel scope link src 192.168.2.1
и это правила ip, как указано в ip rule list
:
0: from all lookup 128 #a non-existent table
1: from all lookup local
32766: from all lookup main
32767: from all lookup default #empty table
ПОПЫТКИ
Прежде всего я создал таблицу маршрутизации no_vpn_provider
(echo "2 no_vpn_provider" >> /etc/iproute2/rt_tables
), точную копию main
таблицы без изменений экземпляра клиента VPN. таблица списка маршрутов ip показывает ip route list table no_vpn_provider
default via 192.168.1.1 dev eth0 proto static
10.255.0.0/24 via 10.255.0.2 dev tun1
10.255.0.2 dev tun1 proto kernel scope link src 10.255.0.1
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.2
192.168.2.0/24 dev br-lan proto kernel scope link src 192.168.2.1
1) Я попробовал эти простые правила ip
ip rule add from 192.168.1.2 table no_vpn_provider priority 2
ip rule add from 10.255.0.1 table no_vpn_provider priority 3
где 192.168.1.2
и 10.255.0.1
- это IP-адреса внешнего интерфейса eth0
и интерфейса VPN-сервера tun1
соответственно.
Я также пробовал from all iif eth0
и from all iif tun1
вместо from 192.168.1.2
и from 10.255.0.1
.
2) Я попытался пометить 0x1
новые соединения (модуль conntrack
установлен) для интерфейсов eth0
и tun1
iptables -t mangle -A PREROUTING -m conntrack --ctstate NEW -i eth0 -j CONNMARK --set-mark 0x1
iptables -t mangle -A PREROUTING -m conntrack --ctstate NEW -i tun1 -j CONNMARK --set-mark 0x1
и добавление этого правила, чтобы помеченные соединения использовали новую таблицу маршрутизации
ip rule add fwmark 0x1 table no_vpn_provider priority 2
3) Я попытался пометить исходящие пакеты с порта VPN сервера 1194
iptables -t mangle -A OUTPUT -p udp --sport 1194 -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT -p tcp --sport 1194 -j MARK --set-mark 0x1 # just in case
и используя то же правило
ip rule add fwmark 0x1 table no_vpn_provider priority 2
Я также пробовал 2) и 3) с разными отметками и со вставкой (-I
) вместо добавления (-A
). Подозреваю, что мой брандмауэр вообще не помечен
iptables -t mangle -A FORWARD -s 192.168.2.0/24 -j MARK --set-mark 0x1
ip rule add fwmark 0x1 table no_vpn_provider priority 2
но, как и ожидалось, пакеты из моей локальной сети не пересылались провайдеру VPN.
4) Единственное, что работает до сих пор, это уродливое правило
ip rule add from all to y.y.y.y/y table no_vpn_provider priority 2
где yyyy /y - публичный IP-адрес клиента, пытающегося подключиться: это, конечно, ужасное решение, потому что клиенты не собираются подключаться всегда из одной и той же сети.