Как стать автором
Обновить

IQ-Openvpn или Openvpn с распределенной маршрутизацией

Уровень сложностиСредний
Время на прочтение9 мин
Количество просмотров6.6K

C каждым днем все больше и больше людей узнают, что такое VPN, и начинают им пользоваться, но зачастую все сталкиваются с такой проблемой, что включая VPN мы получаем доступ к заблокированным ресурсам, но в тоже время теряем доступ к ресурсам, которые закрывают свой доступ из других локаций по тем или иным причинам. По этой причине приходится постоянно выключать VPN. В данном мане я расскажу, как поднять свой VPN сервис, который позволит получать доступ ко всем ресурсам в интернете не отключаясь от VPN‑сервера.

Для создания нам надо два сервера VPN1 и VPN2.

VPN1 в идеале должен находиться в той же стране, что и пользователь по двум причинам:

  1. Для ускорения сигнала и минимизации задержек.

  2. Многие ресурсы запрещают доступ из других локаций.

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

Для дальнейшего понимания что и куда "втыкать" определимся с данными серверов:

VPN1:
IP1 - 11.11.11.11
ip1_gateway - 11.11.11.1
IP_VPN1 - 192.168.11.1
ip_gateway_vpn1 - 192.168.11.1

VPN2:
IP2 - 12.12.12.12
ip2_gateway - 12.12.12.1
IP_VPN2 - 192.168.12.1
ip_gateway_vpn2 - 192.168.12.1

На сервере VPN1 мы подключаем пользователей с перенаправлением всего трафика, а на сервер VPN2 подключаем сервер VPN1 с «локальным» подключением. «Локальное» подключение — подключение при котором между серверами создается только туннель и в него идет определенный трафик, а весь трафик по умолчанию идет в обход туннеля.

Приступим к настройке сервера VPN1.

Для начала установим необходимые утилиты:

apt update && apt upgrade
apt install sudo vim shorewall curl wget openvpn dnsutils -y

Включаем пересылку пакетов на сервере. Находим строку и приводим ее к следующему виду:

vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
cd /etc/shorewall/

Далее нам надо взять шаблоны необходимых файлов, чтобы не писать их с нуля:

cp /usr/share/doc/shorewall/examples/two-interfaces/{interfaces,policy,rules,snat,zones} /etc/shorewall/
cp /usr/share/shorewall/configfiles/{tunnels,routes} /etc/shorewall/
mkdir {local,routes.d}

Теперь приводим шаблоны к нашей ситуации. На сервере VPN1 у нас будет три интерфейса:

ens3 – физический интерфейс с внешним статическим IP,
tun1u – виртуальный интерфейс vpn1.server,
tun2u – виртуальный интерфейс vpn2.client.

Сервер VPN1 находится в зоне ru, значит так ее и назовем, а VPN2 находится в зоне nl:

vim zones
fw      firewall
net     ipv4
ru      ipv4
nl      ipv4

Обращаем внимание на названия интерфейсов!

vim interfaces
net     ens3           dhcp,tcpflags,nosmurfs,routefilter,logmartians,sourceroute=0
ru      tun1u          optional,tcpflags,nosmurfs,routefilter,logmartians
nl      tun2u          optional,tcpflags,nosmurfs,routefilter,logmartians

В следующем файле мы прописываем настройки для пересылки трафика VPN, где указываем свои протокол и порт vpn сервера:

vim tunnels
openvpnserver:udp:11443   net     0.0.0.0/0

Нам надо включить маскардинг, для этого в файле snat убираем дефолтные настройки и прописываем свои с подстановкой своих подсетей:

vim snat
MASQUERADE              192.168.11.0/24         ens3
MASQUERADE              192.168.11.0/24         tun2u
vim policy
$FW     net             ACCEPT
$FW     ru              ACCEPT
$FW     nl              ACCEPT
ru      $FW             ACCEPT
ru      net             ACCEPT
ru      nl              ACCEPT
net     all             DROP            $LOG_LEVEL
# THE FOLOWING POLICY MUST BE LAST
all     all             REJECT          $LOG_LEVEL
vim rules
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
#       Don't allow connection pickup from the net
#
Invalid(DROP)   net             all             tcp
#
#       Accept DNS connections from the firewall to the network
#
DNS(ACCEPT)     $FW             net
#
#       Accept SSH connections from the local network for administration
#
SSH(ACCEPT)     net             $FW
SSH(ACCEPT)     nl              $FW
SSH(ACCEPT)     ru              $FW
SSH(ACCEPT)     $FW             net
SSH(ACCEPT)     $FW             nl
SSH(ACCEPT)     $FW             ru
#
#       Allow Ping from the local network
#
Ping(ACCEPT)    nl              $FW
Ping(ACCEPT)    ru              $FW
#
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#
Ping(DROP)      net             $FW
ACCEPT          $FW             nl              icmp
ACCEPT          $FW             ru              icmp
ACCEPT          $FW             net             icmp

Настраиваем vpn сервер, запускаем. Так же перезапускаем shorewall:

systemctl restart shorewall
systemctl enable shorewall

Можем выпустить уже пользовательский сертификат с оборотом всего трафика и проверить работоспособность. Проверить можно на сайте https://2ip.ru ну или на том, который больше нравится. Если подключение пошло, на сайте мы увидели IP сервера, тогда все сделали верно.

Начинаем настраивать VPN2.

Для начала установим необходимые утилиты:

apt update && apt upgrade
apt install sudo vim shorewall curl wget openvpn dnsutils -y

Включаем пересылку пакетов на сервере. Находим строку и приводим ее к следующему виду:

vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
cd /etc/shorewall/

Далее нам надо взять шаблоны необходимых файлов, чтобы не писать их с нуля:

cp /usr/share/doc/shorewall/examples/two-interfaces/{interfaces,policy,rules,snat,zones} /etc/shorewall/
cp /usr/share/shorewall/configfiles/tunnels /etc/shorewall/

Теперь приводим шаблоны к нашей ситуации. На сервере VPN2 у нас будет два интерфейса:

ens3 – физический интерфейс с внешним статическим IP,
tun2u – виртуальный интерфейс vpn2.server.

Сервер VPN2 находится в зоне nl, значит так ее и назовем:

vim zones 
fw      firewall 
net     ipv4 
nl      ipv4

Обращаем внимание на названия интерфесов!

vim interfaces
net     ens3          dhcp,tcpflags,nosmurfs,routefilter,logmartians,sourceroute=0 
nl      tun2u         optional,tcpflags,nosmurfs,routefilter,logmartians

В следующем файле мы прописываем настройки для пересылки трафика VPN где указываем свои протокол и порт vpn сервера:

vim tunnels
openvpnserver:udp:12443   net     0.0.0.0/0

Далее нам надо включить маскардинг, для этого в следующем файле убираем дефолтные настройки и прописываем свои с подстановкой своих подсетей:

vim snat
MASQUERADE              192.168.0.0/16         ens3
vim policy
$FW     net             ACCEPT
$FW     nl              ACCEPT
nl      net             ACCEPT
net     all             DROP            $LOG_LEVEL
# THE FOLOWING POLICY MUST BE LAST
all     all             REJECT          $LOG_LEVEL
vim rules
?SECTION ALL 
?SECTION ESTABLISHED 
?SECTION RELATED 
?SECTION INVALID 
?SECTION UNTRACKED 
?SECTION NEW 
#       Don't allow connection pickup from the net 
# 
Invalid(DROP)   net             all             tcp 
# 
#       Accept DNS connections from the firewall to the network 
# 
DNS(ACCEPT)     $FW             net 
# 
#       Accept SSH connections from the local network for administration 
# 
SSH(ACCEPT)     net             $FW 
SSH(ACCEPT)     nl              $FW 
SSH(ACCEPT)     $FW             net 
SSH(ACCEPT)     $FW             nl 
# 
#       Allow Ping from the local network 
# 
Ping(ACCEPT)    nl              $FW 
Ping(ACCEPT)    nl              nl 
# 
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded.. 
# 
Ping(DROP)      net             $FW 
ACCEPT          $FW             nl              icmp 
ACCEPT          $FW             net             icmp

Настраиваем vpn сервер, запускаем. Так же перезапускаем shorewall

systemctl restart shorewall 
systemctl enable shorewall

Теперь можем создать пользовательский сертификат, но без оборачивания всего трафика в vpn, который только создаст туннель между VPN1 сервером и VPN2, локальный. Сертификат отправляем на VPN1 сервер, включаем и добавляем в автозагрузку.

Теперь начинаем делать то, ради чего все и затевалось. Нам надо настроить маршрутизацию трафика по зонам (да, мы делаем только два сервера, но можно сделать и больше). Первое, что мы должны сделать, это создать список адресов локации.

Сложный, нудный, но веселый вариант

Для этого мы идем на сайт и выбираем для какой страны (страна, где мы находимся).

Мы получаем список сетей с начальным и конечным адресами и в таком виде мы не можем их использовать, нам надо привести их к следующему виду xx.xx.xx.xx/xx, а для этого нужно правльно высчитать маску каждой сети из таблицы. Можно вручную считать на бумажке или в уме, а можно пойти сюда и считать с помощью калькулятора сетей. Нужно быть очень внимательным при пересчете, ведь допущенные ошибки могут привести к тому, что трафик будет перенаправляться не так, как нам надо или система совсем не заведется.

И так, считаем сети и сразу записываем в файл /etc/shorewall/local/ru на сервере VPN1 в колонку в виде:
 xx.xx.xx.xx/xx
 xx.xxx.xx.xx/xx
 и т.д.
Работа достаточно большая, особенно если страна большая)

Простой и скучный вариант

Идем на тот же сайт, но чуть дальше, выбираем страну и формат CIDR и скачиваем архив со списком адресов в нужном нам формате, однако в списке есть первые лишние строки, удаляем их и сохраняем в файл /etc/shorewall/local/ru на сервере VPN1.

Закончили? Идем дальше. Теперь нам надо сделать так, чтобы данные адреса в нужном формате попали в конфигурационный файл, плюс включить пересылку трафика на VPN2, для этого нам надо создать скрипт (можно не паниковать, я уже давно все написал, нам надо только скопировать и вставить, подставляя свои значения):

cd /etc/shorewall/
vim auto.sh
#!/bin/bash

input=local/ru 
output=routes.d/ru 
localnet="<ip1_gateway>" 
interface=ens3
tun2=tun2u  
ip2="<IP2>"
ip_gateway_vpn2="<ip_gateway_vpn2>"

echo "#provider   dest                gateway         device" > $output 
echo "#provider   dest                gateway         device 
main        0.0.0.0/0		$ip_gateway_vpn2	$tun2 
main        $ip2	$localnet	$interface  #connect nl 
main        195.201.201.32	$localnet	$interface  #check 2ip.ru
INCLUDE /etc/shorewall/routes.d/ru" > routes  
while IFS= read -r network 
do
    echo "main      $network                  $localnet     $interface" >> $output 
done < $input
Важное замечание

Данная схема будет работать только в том случае, если и клиент подключатся из той же зоны, где сервер VPN1, в противном случае доступа к серверу не будет. Однако если есть желание дать другу из Турции сертификат к своему vpn, то надо взять его IP адрес и добавить в файл routes:

vim /etc/shorewall/routes
...
main        <IP_of_friend> 	<localnet>	<interface>
...

Теперь делаем файл исполняемым:

chmod +x auto.sh

Запускаем скрипт и перезапускаем shorewall:

./auto.sh
shorewall restart

Теперь у нас практически все готово, сначала проверим работу. Подключаемся к vpn и идем проверять. Переходим на сайт 2ip.ru и видим адрес VPN1, так как мы прописали пересылку пакетов на этот сайт через VPN1. Теперь идем на сайт 2ip.ua или любой другой, но который точно не находится в зоне ru (в примере я делал для нее) и видим адрес VPN2. Если все так, тогда поздравляю, если нет, тогда стоит проверить все еще раз по шагам.

Остался последний шаг на сервере VPN1, если конечно не хотим делать все вручную каждый раз после перезагрузки (при чем доступ по ssh будет закрыт). Нам надо настроить условие автозагрузки shorewall. Для этого мы редактируем файл /usr/lib/systemd/system/shorewall.service  и меняем строчку «After=network-online.target» на «After=openvpn@cli002008.service», где cli002008 имя моего сертификата:

vim /usr/lib/systemd/system/shorewall.service
Проблемное место

На свежей версии debian shorewall не хочет запускаться после openvpn, что мы указывали выше. Я не разобрался пока в проблеме, если у кого-то есть ответ, то пишите в комментариях. Пока предложу другое решение, запускать через cron:

crontab -e
...
@reboot sleep 10; systemctl restart shorewall
...

Теперь все готово!

Сервера брал тут и тут, можно купить "вечный сервер". Еще использую сервера здесь, данный хостинг имеет большое разнообразие локаций по приемлемым ценам.

Можно настроить обновление данных в автоматическом режиме. Через крон будет скачиваться файл с адресами и записываться в shorewall, но данный способ является платным. Надо купить подписку и получить ссылку и токен для скачивания в следующем формате:

curl -o firewall.gz 'https://dl.ip2location.com/v1/firewall?token=mOdUlMdh0nK9Oap3iHaJxFrX0koqVahHX9Е9gfZhP9nURa126U4xnS9vKlbU3gry&country=RU|BY&format=cidr'
Благодарности за помощь

Благодарю за редакторские правки Дарью.

Теги:
Хабы:
Всего голосов 7: ↑6 и ↓1+5
Комментарии16

Публикации