C каждым днем все больше и больше людей узнают, что такое VPN, и начинают им пользоваться, но зачастую все сталкиваются с такой проблемой, что включая VPN мы получаем доступ к заблокированным ресурсам, но в тоже время теряем доступ к ресурсам, которые закрывают свой доступ из других локаций по тем или иным причинам. По этой причине приходится постоянно выключать VPN. В данном мане я расскажу, как поднять свой VPN сервис, который позволит получать доступ ко всем ресурсам в интернете не отключаясь от VPN‑сервера.
Для создания нам надо два сервера VPN1 и VPN2.
VPN1 в идеале должен находиться в той же стране, что и пользователь по двум причинам:
Для дальнейшего понимания что и куда "втыкать" определимся с данными серверов:
VPN1:
VPN2:
На сервере VPN1 мы подключаем пользователей с перенаправлением всего трафика, а на сервер VPN2 подключаем сервер VPN1 с «локальным» подключением. «Локальное» подключение — подключение при котором между серверами создается только туннель и в него идет определенный трафик, а весь трафик по умолчанию идет в обход туннеля.
Приступим к настройке сервера VPN1.
Для начала установим необходимые утилиты:
Включаем пересылку пакетов на сервере. Находим строку и приводим ее к следующему виду:
Далее нам надо взять шаблоны необходимых файлов, чтобы не писать их с нуля:
Теперь приводим шаблоны к нашей ситуации. На сервере VPN1 у нас будет три интерфейса:
Сервер VPN1 находится в зоне ru, значит так ее и назовем, а VPN2 находится в зоне nl:
Обращаем внимание на названия интерфейсов!
В следующем файле мы прописываем настройки для пересылки трафика VPN, где указываем свои протокол и порт vpn сервера:
Нам надо включить маскардинг, для этого в файле snat убираем дефолтные настройки и прописываем свои с подстановкой своих подсетей:
Настраиваем vpn сервер, запускаем. Так же перезапускаем shorewall:
Можем выпустить уже пользовательский сертификат с оборотом всего трафика и проверить работоспособность. Проверить можно на сайте https://2ip.ru ну или на том, который больше нравится. Если подключение пошло, на сайте мы увидели IP сервера, тогда все сделали верно.
Начинаем настраивать VPN2.
Для начала установим необходимые утилиты:
Включаем пересылку пакетов на сервере. Находим строку и приводим ее к следующему виду:
Далее нам надо взять шаблоны необходимых файлов, чтобы не писать их с нуля:
Теперь приводим шаблоны к нашей ситуации. На сервере VPN2 у нас будет два интерфейса:
Сервер VPN2 находится в зоне nl, значит так ее и назовем:
Обращаем внимание на названия интерфесов!
В следующем файле мы прописываем настройки для пересылки трафика VPN где указываем свои протокол и порт vpn сервера:
Далее нам надо включить маскардинг, для этого в следующем файле убираем дефолтные настройки и прописываем свои с подстановкой своих подсетей:
Настраиваем vpn сервер, запускаем. Так же перезапускаем shorewall
Теперь можем создать пользовательский сертификат, но без оборачивания всего трафика в vpn, который только создаст туннель между VPN1 сервером и VPN2, локальный. Сертификат отправляем на VPN1 сервер, включаем и добавляем в автозагрузку.
Теперь начинаем делать то, ради чего все и затевалось. Нам надо настроить маршрутизацию трафика по зонам (да, мы делаем только два сервера, но можно сделать и больше). Первое, что мы должны сделать, это создать список адресов локации.
Сложный, нудный, но веселый вариант
Для этого мы идем на сайт и выбираем для какой страны (страна, где мы находимся).
Мы получаем список сетей с начальным и конечным адресами и в таком виде мы не можем их использовать, нам надо привести их к следующему виду xx.xx.xx.xx/xx, а для этого нужно правльно высчитать маску каждой сети из таблицы. Можно вручную считать на бумажке или в уме, а можно пойти сюда и считать с помощью калькулятора сетей. Нужно быть очень внимательным при пересчете, ведь допущенные ошибки могут привести к тому, что трафик будет перенаправляться не так, как нам надо или система совсем не заведется.
И так, считаем сети и сразу записываем в файл /etc/shorewall/local/ru на сервере VPN1 в колонку в виде:
Работа достаточно большая, особенно если страна большая)
Простой и скучный вариант
Идем на тот же сайт, но чуть дальше, выбираем страну и формат CIDR и скачиваем архив со списком адресов в нужном нам формате, однако в списке есть первые лишние строки, удаляем их и сохраняем в файл /etc/shorewall/local/ru на сервере VPN1.
Закончили? Идем дальше. Теперь нам надо сделать так, чтобы данные адреса в нужном формате попали в конфигурационный файл, плюс включить пересылку трафика на VPN2, для этого нам надо создать скрипт (можно не паниковать, я уже давно все написал, нам надо только скопировать и вставить, подставляя свои значения):
Важное замечание
Данная схема будет работать только в том случае, если и клиент подключатся из той же зоны, где сервер VPN1, в противном случае доступа к серверу не будет. Однако если есть желание дать другу из Турции сертификат к своему vpn, то надо взять его IP адрес и добавить в файл routes:
Теперь делаем файл исполняемым:
Запускаем скрипт и перезапускаем shorewall:
Теперь у нас практически все готово, сначала проверим работу. Подключаемся к 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 имя моего сертификата:
Проблемное место
На свежей версии debian shorewall не хочет запускаться после openvpn, что мы указывали выше. Я не разобрался пока в проблеме, если у кого-то есть ответ, то пишите в комментариях. Пока предложу другое решение, запускать через cron:
Теперь все готово!
Сервера брал тут, можно купить "вечный сервер". Еще использую сервера здесь, данный хостинг имеет большое разнообразие локаций по приемлемым ценам.
Можно настроить обновление данных в автоматическом режиме. Через крон будет скачиваться файл с адресами и записываться в shorewall, но данный способ является платным. Надо купить подписку и получить ссылку и токен для скачивания в следующем формате:
автор @dumasti
habr.com
Для создания нам надо два сервера VPN1 и VPN2.
VPN1 в идеале должен находиться в той же стране, что и пользователь по двум причинам:
- Для ускорения сигнала и минимизации задержек.
- Многие ресурсы запрещают доступ из других локаций.
Для дальнейшего понимания что и куда "втыкать" определимся с данными серверов:
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
Код:
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.
Для начала установим необходимые утилиты:
Код:
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}
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
Код:
vim tunnels
Код:
openvpnserver:udp:11443 net 0.0.0.0/0
Код:
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
Код:
systemctl restart shorewall
systemctl enable shorewall
Начинаем настраивать 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/
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
Код:
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
Код:
systemctl restart shorewall
systemctl enable shorewall
Теперь начинаем делать то, ради чего все и затевалось. Нам надо настроить маршрутизацию трафика по зонам (да, мы делаем только два сервера, но можно сделать и больше). Первое, что мы должны сделать, это создать список адресов локации.
Сложный, нудный, но веселый вариант
Для этого мы идем на сайт и выбираем для какой страны (страна, где мы находимся).
Мы получаем список сетей с начальным и конечным адресами и в таком виде мы не можем их использовать, нам надо привести их к следующему виду 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
Код:
./auto.sh
shorewall restart
Остался последний шаг на сервере 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'
автор @dumasti
habr.com