Избирательная маршрутизация в OpenVPN

Все настройки выполнены в VPS от hostsailor.com

Сайт для статьи размещён на fornex.com

ВНИМАНИЕ! На сайте rknsucks.xyz больше нет демонстрационного стенда.

В связи с решением о блокировке Telegram на территории России народ потянулся к моим статьям по VPN и стали поступать всякие разные вопросы о реализации VPN для обхода блокировок. Основной посыл: запускать весь трафик через VPN неудобно/медленно/избыточно, как запустить только для отдельных сайтов и ресурсов.

Сейчас я Вам всё покажу.

Немного предыстории. Чтобы не пилить всё с нуля (в основном сайт для данной статьи) я скомуниздил наработки проекта zaborona.help. Проект создан с целью помочь гражданам Украины обходить блокировки российских ресурсов. Автор проекта всегда разрешал открыто использовать любые части проекта. Сам проект полностью размещён на github.

Немного формальностей. Данная статья, а также сайт secfall.com не предоставляет способов обхода блокировок. И в данной статье, и на сайте secfall.com описываются инструменты штатного применения программного продукта OpenVPN. Автор статьи и администрация сайта secfall.com не могут нести ответственность за противоправные действия третьих лиц, при использовании описываемых в статье и на сайте инструментов.

Итак.  Вы решили сделать такой VPN сервер, через который будете перенаправлять не весь трафик, а только к определённым адресам. И может даже дадите им попользоваться своим друзьям и родственникам. Ведь если вы, например, перенаправите трафик только к серверам мессенджера, то, очевидно, трафик будет весьма не большим и сервер будет простаивать. Почему не поделиться?

Для удобства целесообразно арендовать (или получить бесплатное) доменное имя. Например rknsucks.xyz. Как получить доменное имя и настроить его описано в этой статье. На самом адресе rknsucks.xyz разместим всю необходимую для подключения информацию (да, да, сайт нагло скомунизжен, я писал выше), а для VPN сервера сделаем домен третьего уровня, например ovpn.rknsucks.xyz

Теперь понадобиться VPS. Как выбрать и первично настроить виртуалку, написано здесь и здесь

Важный момент: поскольку в данной статье описывается создание многопользовательского публичного сервиса, то всем клиентам сервера будет выдаваться отдельный IPv6 адрес. Для этого, после аренды VPS, я попросил у хостера выдать /64 подсеть IPv6.  Это не обязательно и будет показано в конфигах ниже. Вообще, белый адрес для каждого, пусть и IPv6, это хорошо!

Дальше включаем лень. Установить и настроить OpenVPN хоть и не сложно, но мне лениво и я воспользуюсь своим же скриптом автонастройки

Дальше в статье я буду исходить из того, что сервер настроен по по моим статьям. Это сэкономит время и уменьшит текст.

В процессе работы скрипта я использовал следующие настройки:

  • протокол TCP
  • порт 443
  • DNS от Google

Тут будут вопли, что tcp и 443 не православно, но я таки буду настаивать. Ибо во многих сетях, офисных и публичных, другие порты и протоколы наружу попросту закрыты.

После проверки, что VPN сервер жив, цел, орёл, начнём его переделывать (как проверить, подробно описано в этой статье). Все конфиги можно найти на github.

Остановим сервер командой:

systemctl stop openvpn@server

И начинаем безбожно править файл /etc/openvpn/server.conf

mode server
port 443
proto tcp
dev-type tun
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
crl-verify crl.pem

topology subnet 
server 10.8.224.0 255.255.248.0
server-ipv6 2a04:dd00:9:b::/112

duplicate-cn
client-config-dir ccd

ifconfig-pool-persist ipp.txt
remote-cert-eku "TLS Web Client Authentication"

txqueuelen 250
keepalive 300 900
tls-server
tls-auth ta.key 0
tls-timeout 120
auth SHA512
cipher AES-256-CBC
comp-lzo

user nobody
group nobody
 
persist-key
persist-tun
 
status openvpn-status.log
log openvpn.log
verb 4

Обратите внимание на строчки:

server 10.8.224.0 255.255.248.0 — это из расчета двух тысяч пользователей сервера. Вам наверняка можно сделать меньше (оставить, как было в конфиге)

server-ipv6 2a04:dd00:9:b::/112 — это выдаётся белый IPv6 каждому клиенту. Мой хостер запросто раздаёт /64 подсети IPv6. Грех не воспользоваться. Если у Ваш хостер такого услуги не предоставляет, удалите строчку.

client-config-dir ccd — самое интересное. В этой папке «ccd» будет лежать конфиг, настраивающий избирательную маршрутизацию.

Закрываем /etc/openvpn/server.conf с сохранением.

Создайте папку /etc/openvpn/ccd, а в ней файл DEFAULT с таким содержимым

push "dhcp-option DNS 8.8.8.8" # Google ipv4 dns
push "dhcp-option DNS 8.8.4.4" # Google ipv4 dns

push "dhcp-option DNS6 2001:4860:4860::8888" # Google ipv6 dns
push "route-ipv6 2001:4860:4860::8888"

push "dhcp-option DNS6 2001:4860:4860::8844" # Google ipv6 dns
push "route-ipv6 2001:4860:4860::8844"

#Persist TUN
push "persist-tun"

# Routes

# myip.ru 
push "route 178.62.9.171 255.255.255.255"

# telegram
push "route 91.108.4.0 255.255.252.0"
push "route 91.108.8.0 255.255.252.0"
push "route 91.108.56.0 255.255.252.0"
push "route 149.154.160.0 255.255.240.0"
push "route 149.154.164.0 255.255.252.0"
push "route 91.108.16.0 255.255.252.0"
push "route 91.108.56.0 255.255.254.0"
push "route 149.154.168.0 255.255.252.0"
push "route 91.108.12.0 255.255.252.0"
push "route 149.154.172.0 255.255.252.0"
push "route 91.108.20.0 255.255.252.0"
push "route 91.108.36.0 255.255.254.0"
push "route 91.108.38.0 255.255.254.0"
push "route 91.108.56.0 255.255.254.0"
push "route 91.108.56.0 255.255.252.0"
push "route 91.108.4.0 255.255.252.0"
push "route 67.198.55.0 255.255.255.0"
push "route 149.154.168.0 255.255.252.0"
push "route 149.154.172.0 255.255.252.0"
push "route 149.154.164.0 255.255.252.0"
push "route 109.239.140.0 255.255.255.0"
push "route-ipv6 2001:b28:f23f::/48"
push "route-ipv6 2001:b28:f23d::/48"
push "route-ipv6 2001:67c:4e8::/48"

Думаю тут всё интуитивно понятно. Впихиваем клиенту DNS и адреса подсетей, трафик на которые пойдёт через VPN. Обратите внимание, я добавил адрес сайта myip.ru. Это нужно для того, чтобы проконтролировать работоспособность сервера и конфига. если всё работает, то подключившись к серверу и зайдя на этот сайт вы увидите IP-адрес VPN сервера. На всех остальных сайтах-определителях IP (даже здесь, справа стороны экрана) вы будете видеть тот адрес, который выдавал Вам провайдер интернета.

Файл DEFAULT можно править на ходу, не останавливая службу сервера. Для того, чтобы настройки применились к клиенту, клиент просто должен переподключиться. 

Сохраните файл DEFAULT.

Запустим сервер командой:

systemctl start openvpn@server

И проверим командой:

systemctl status openvpn@server

Если есть ошибки, сверяйте конфиги.

Теперь подправил IPtables. Если вы делали по моим статьям или с моим скриптом автоустановки, то у вас есть файл /root/ipt-set

Его тоже нужно подправить:

#!/bin/sh
IF_EXT="venet0"
IF_OVPN="tun0"
OVPN_PORT="443"
IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"
# flush
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X
$IPT6 --flush
# loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
$IPT6 -P INPUT DROP
$IPT6 -P OUTPUT DROP
$IPT6 -P FORWARD DROP
# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 1 > /proc/sys/net/ipv6/conf/default/forwarding
echo 1 > /proc/sys/net/ipv6/conf/all/proxy_ndp
# NAT
# #########################################
# SNAT - local users to out internet
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
# INPUT chain
# #########################################
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT6 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ssh
$IPT -A INPUT -i $IF_EXT -p tcp --dport 22 -j ACCEPT
# VPN
$IPT -A INPUT -i $IF_OVPN -p icmp -s 10.8.224.0/21 -j ACCEPT
$IPT6 -A INPUT -i $IF_OVPN -p icmp -s 2a04:dd00:9:b::/64 -j ACCEPT
# DNS
$IPT -A INPUT -i $IF_OVPN -p udp --dport 53 -s 10.8.224.0/21 -j ACCEPT
$IPT6 -A INPUT -i $IF_OVPN -p udp --dport 53 -s 2a04:dd00:9:b::/64 -j ACCEPT
# openvpn
$IPT -A INPUT -i $IF_EXT -p tcp --dport $OVPN_PORT -j ACCEPT

# FORWARD chain
# #########################################
$IPT -A FORWARD -i $IF_OVPN -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_EXT -o $IF_OVPN -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT6 -A FORWARD -i $IF_OVPN -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT6 -A FORWARD -i $IF_EXT -o $IF_OVPN -m state --state ESTABLISHED,RELATED -j ACCEPT
# OUTPUT chain
# #########################################
$IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT6 -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Здесь всё для Вас знакомо, только убраны правила, разрешавшие соединения между клиентами сервера и добавлены правила для IPv6.

Если IPv6 не нужен, то конфиг будет таким:

#!/bin/sh
IF_EXT="venet0"
IF_OVPN="tun0"
OVPN_PORT="443"
IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"
# flush
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X
$IPT6 --flush
# loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
$IPT6 -P INPUT DROP
$IPT6 -P OUTPUT DROP
$IPT6 -P FORWARD DROP
# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# NAT
# #########################################
# SNAT - local users to out internet
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
# INPUT chain
# #########################################
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ssh
$IPT -A INPUT -i $IF_EXT -p tcp --dport 22 -j ACCEPT
# VPN
$IPT -A INPUT -i $IF_OVPN -p icmp -s 10.8.224.0/21 -j ACCEPT
# DNS
$IPT -A INPUT -i $IF_OVPN -p udp --dport 53 -s 10.8.224.0/21 -j ACCEPT
# openvpn
$IPT -A INPUT -i $IF_EXT -p tcp --dport $OVPN_PORT -j ACCEPT

# FORWARD chain
# #########################################
$IPT -A FORWARD -i $IF_OVPN -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF_EXT -o $IF_OVPN -m state --state ESTABLISHED,RELATED -j ACCEPT
# OUTPUT chain
# #########################################
$IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Применим его командой:

bash /root/ipt-set

Собственно всё. Сервер для друзей готов. Подключаться, как описано в статье и на сайте rknsucks.xyz

В следующей статье мы прикрутим socks5

Да. И о безопасности. Многие сейчас возопят, что тот, у кого VPS, сможет читать трафик. Да, сможет, но толку? Мы пускаем в зашифрованный канал изначально зашифрованный трафик. Т.е. шифруем зашифрованное. И на выходе с VPS трафик всё также зашифрован. Таким же он выходит из Вашего роутера, если вы не используете VPN. 

 

 

 

Вы можите оставить комментарий, или поставить трэкбек со своего сайта.

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>