Настройте маршрутизацию и iptables для нового VPN-подключения для перенаправления ** только ** портов 80 и 443


8

У меня новое VPN-соединение (использующее openvpn), чтобы позволить мне обходить некоторые ограничения ISP. Хотя он работает нормально, он принимает весь трафик через VPN. Это вызывает у меня проблемы с загрузкой (мое интернет-соединение намного быстрее, чем позволяет vpn) и удаленным доступом. Я запускаю ssh-сервер и у меня работает демон, который позволяет мне планировать загрузку через мой телефон.

У меня есть существующее соединение Ethernet на eth0, а новое VPN-соединение на tun0.

Я считаю, что мне нужно настроить маршрут по умолчанию для использования моего существующего соединения eth0 в сети 192.168.0.0/24 и установить шлюз по умолчанию на 192.168.0.1 (мои знания шатки, так как я не делал этого в течение ряда лет ). Если это правильно, то я не совсем уверен, как это сделать! Моя текущая таблица маршрутизации:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
0.0.0.0         10.51.0.169     0.0.0.0         UG    0      0        0 tun0     0     0      0
10.51.0.1       10.51.0.169     255.255.255.255 UGH   0      0        0 tun0     0     0      0
10.51.0.169     0.0.0.0         255.255.255.255 UH    0      0        0 tun0     0     0      0
85.25.147.49    192.168.0.1     255.255.255.255 UGH   0      0        0 eth0     0     0      0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0     0     0      0
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0     0     0      0

После исправления маршрутизации я считаю, что мне нужно использовать iptables для настройки предварительной маршрутизации или маскирования, чтобы принудительно настроить все для порта назначения 80 или 443 через tun0. Опять же, я не совсем уверен, как это сделать!

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

Любая помощь приветствуется.

ОБНОВИТЬ

Пока из разных источников я собрал воедино следующее:

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Теперь это, кажется, работает. За исключением того, что это не так!

Подключение к заблокированным веб - сайты будут идти через, соединение не на порты 80 и 443 будут использовать соединение без VPN.

Однако порты 80 и 443, которые не подключены к заблокированным веб-сайтам, также используют не-VPN-подключение!

Поскольку общая цель достигнута, я относительно счастлив, но было бы неплохо узнать, почему она работает не совсем правильно.

Любые идеи?

Для справки, у меня теперь есть 3 таблицы маршрутизации: main, internet и vpn. Список их выглядит следующим образом ...

Главный:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 

Интернет:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 
192.168.0.1 dev eth0  scope link  src 192.168.0.73

VPN:

default via 10.38.0.205 dev tun0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1

Приведенный выше скрипт работает как положено. Я просто ожидал увидеть трафик, исходящий с 10. адреса в netstat. Однако весь трафик начинается с 192. Но порты 80 и 443 направлены через VPN. Я поставлю все решение в ответе, но призываю @anttir предлагать iproute2 и fwmark. Я не сталкивался с ними, и без них я бы все еще бился головой о кирпичную стену!
— Стив

Ответы:


4

Итак, большая часть этого выше, но все решение было следующим:

Отредактируйте / etc / iproute2 / rt_tables и добавьте 2 строки внизу:

101 internet
102 vpn

Вы можете дать этим таблицам другие имена, которые имеют больше смысла, просто быть последовательными.

Затем вам нужно создать скрипт (я назвал его rt_setup) в /etc/init.d

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

Затем, очевидно, свяжите его с /etc/rc2.d (я использую ubuntu, уровень запуска может отличаться для вас). Убедитесь, что вы даете ему номер S выше, чем ссылка openvpn!

Сценарий делает несколько вещей. В верхней части настраиваются переменные, с некоторыми операторами perl и awk, используемыми для получения динамических IP-адресов и адресов шлюзов. Во втором разделе очищаются таблицы, настроенные в ipruote2, и копируется в них текущая таблица маршрутизации. Затем он создает два новых маршрута и два шлюза по умолчанию для них, при этом VPN-соединение проходит через VPN, а интернет-подключение - через мою локальную сеть.

Я не уверен, что следующие 2 строки необходимы, но они позволяют пересылку ip для использования в iptables.

Затем сценарий создает некоторые правила о том, где искать трафик, исходящий с соответствующего IP-адреса, и где искать, если трафик специально помечен.

POSTROUTING и PREROUTING гарантирует, что трафик, исходящий от адреса, получит ответ!

Окончательное ПРЕДУПРЕЖДЕНИЕ iptables является частью тегов трафика и гарантирует, что все, что идет к портам 80 или 443, помечено для использования Таблицы 2 (VPN)

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

В настоящее время процесс работает блестяще. VPN запускается при включении компьютера, и этот сценарий запускается через несколько секунд (я могу добавить оператор ожидания только для того, чтобы убедиться, что VPN полностью инициализирована перед запуском этого сценария). Мое подключение удаленного доступа (SSH и т. Д.) Отлично работает. Мои соединения, которые не идут к портам 80 или 443, используют мое локальное соединение, но весь веб-трафик проходит через VPN, и в обход элементов управления, установленных моим провайдером!

Как я сказал в своем комментарии к моему вопросу, я бы даже не начал искать этот маршрут без предложения @anttir. За спиной этого предложения, сайты http://blog.khax.net/2009/11/28/multi-gateway-routing-with-iptables-and-iproute2/ и http://linux-ip.net/ html / adv-multi-internet.html были очень полезны (даже если код не завершен на 100%!)


1
Последнее добавление, я добавил a sleep 20в начало скрипта, так как соединение openvpn не завершалось вовремя. Я также добавил echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filterв скрипт, так как необходимо отключить фильтр обратных пакетов для tun0. Когда ответ возвращается из tun0 с адресом источника S, обратный фильтр пакетов проверяет, «если я должен был направить пакет на адрес S, и он не прошел через tun0, я отброшу пакет» - и потому, что при этом при поиске нет действительного fwmark, он определяет, что маршрут будет обычным маршрутом по умолчанию, поэтому отбрасывает пакет.
— Стив

Мне пришлось отредактировать ваш скрипт, чтобы он работал на меня. Последняя строка, route add default gw 192.168.0.1 eth0казалось, направляла трафик порта 80/443 через локальный шлюз вместо tun0, как предполагалось. Изменение последней строки, route add default tun0кажется, помогает мне.

1

маршрутизация по протоколу немного сложна. Обычно таблица маршрутизации используется для проверки шлюза по IP-адресу назначения и использования шлюза по умолчанию openvpn или 192.168.0.1.

Было бы проще настроить, например, Squid http proxy на другом конце VPN и настроить браузер на использование прокси.

Вы не будете использовать iptables, так как это изменит целевой IP-адрес HTTP-соединения, и это не будет работать.

Вы можете создать новую таблицу маршрутизации (/ etc / iproute2 / rt_tables) с маршрутом по умолчанию, установленным для конечной точки VPN, использовать iptables fwmark (-j MARK), чтобы отметить все пакеты HTTP, а затем использовать правило ip, чтобы создать собственное правило для помечены пакеты для использования новой таблицы маршрутизации.


Спасибо за вашу помощь. Я обязательно посмотрю на них. Вещи немного хитры в том, что у меня нет контроля над концом сервера, только моя сторона. Кроме того, я не могу использовать squid, потому что мне нужно маршрутизировать трафик https через соединение, и squid не очень хорошо с этим работает.
— Стив

Как насчет маршрутизации всего нескольких IP-адресов через VPN и остальной мир за пределами VPN?
— Антти Рыцёля

Я задумывался о маршрутизации всего нескольких IP-адресов, но список меняется по мере перемещения сайтов, и мне нужно сделать это простым для использования другими пользователями на ПК. Я начал смотреть на настройку новой таблицы маршрутизации и маркировки пакетов. Маркировка пакетов была легкой задачей, я не уверен в таблицах маршрутизации. Я могу настроить один для VPN, который выглядит правильно, и один для всего остального, который выглядит правильным, но я не уверен, что делать с main, так как он все еще установлен на значения по умолчанию (который является VPN). Все еще играет ...
— Стив

linux-ip.net/html/adv-multi-internet.html ip rule show и ip rule добавьте fwmark 4, таблица 4, приоритет 10000
— Antti Rytsölä

В оригинал добавлено обновление, в котором подробно я до сих пор! AH! Просто понял, что я отредактировал твой ответ, а не мой вопрос. Сожалею! Я не использовал это так много, и не понимал, что смогу отредактировать ответ другого человека!
— Стив
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.