Есть возможность поднять свой VPN сервер ? Не хотим использовать redsocks ?
Хотим завертывать на VPN только часть трафика ?
Например, из ipset zapret только порт tcp:443, из ipban - весь трафик, не только tcp ?
Да, с VPN такое возможно.
Опишу понятийно как настраивается policy based routing в openwrt на примере wireguard.
Вместо wireguard можно использовать openvpn или любой другой. Но wireguard прекрасен сразу несколькими вещами.
Главная из которых - в разы большая скорость, даже немного превышающая ipsec.
Ведь openvpn основан на tun, а tun - всегда в разы медленнее решения в kernel mode,
и если для PC оно может быть не так актуально, для soho роутеров - более чем.
Wireguard может дать 50 mbps там, где openvpn еле тащит 10.
Но есть и дополнительное требование. Wireguard работает в ядре, значит ядро должно
быть под вашим контролем. vps на базе openvz не подойдет ! Нужен xen, kvm,
любой другой вариант, где загружается ваше собственное ядро, а не используется
общее, разделяемое на множество vps. В openvz вам никто не даст лезть в ядро.

Если вдруг окажется, что основные VPN протоколы блокируется DPI, включая wireguard,
то стоит смотреть в сторону либо обфускации трафика до состояния нераспознаваемого
мусора, либо маскировки под TLS (лучше на порт 443). Скорость, конечно, вы потеряете, но это
та самая ситуация, которая описывается словами "медленно или никак".
Маскированные под TLS протоколы DPI может распознать двумя действиями :
пассивно через анализ статистических характеристик пакетов (время, размер, периодичность, ..) 
или активно через подключение к вашему серверу от себя и попытку поговорить с сервером по
известным протоколам (называется active probing). Если вы подключаетесь к серверу
с фиксированных IP, то активный пробинг можно надежно заблокировать через ограничение
диапазонов IP адресов, с которых можно подключаться к серверу. В ином случае можно использовать
технику "port knocking".
Перспективным направлением так же считаю легкую собственную модификацию исходников
существующих VPN с целью незначительного изменения протокола, которая ломает стандартные
модули обнаружения в DPI. В wireguard можно добавить в начало пакета handshake лишнее поле,
заполненное случайным мусором. Разумеется, в таком случае требуется держать измененную версию
как на сервере, так и на клиенте. Если затея срабатывает, то вы получаете максимальную
скорость, при этом полностью нагибая регулятора.
Полезная инфа по теме : https://habr.com/ru/post/415977/

Понятийно необходимо выполнить следующие шаги :
1) Поднять vpn сервер.
2) Настроить vpn клиент. Результат этого шага - получение поднятого интерфейса vpn.
Будь то wireguard, openvpn или любой другой тип vpn.
3) Создать такую схему маршрутизации, при которой пакеты, помечаемые особым mark,
попадают на vpn, а остальные идут обычным способом.
4) Создать правила, выставляющие mark для всего трафика, который необходимо рулить на vpn.
Критерии могут быть любые, ограниченные лишь возможностями iptables и вашим воображением.

Будем считать наш vpn сервер находится на ip 91.15.68.202.
Вешать его будем на udp порт 12345. На этот же порт будем вешать и клиентов.
Сервер работает под debian 9. Клиент работает под openwrt.
Для vpn отведем подсеть 192.168.254.0/24.

--- Поднятие сервера ---

На сервере должны быть установлены заголовки ядра (linux-headers-...) и компилятор gcc.
Качаем последний tar.xz с wireguard отсюда : https://git.zx2c4.com/WireGuard/

# tar xf WireGuard*.tar.xz
# cd WireGuard-*/src
# make
# strip --strip-debug wireguard.ko
# sudo make install

wireguard основан на понятии криптороутинга. Каждый пир (сервер - тоже пир)
имеет пару открытый/закрытый ключ. Закрытый ключ остается у пира,
открытый прописывается у его партнера. Каждый пир авторизует другого
по знанию приватного ключа, соответствующего прописанному у него публичному ключу.
Протокол построен таким образом, что на все неправильные udp пакеты не следует ответа.
Не знаешь приватный ключ ? Не смог послать правильный запрос ? Долбись сколько влезет,
я тебе ничего не отвечу. Это защищает от активного пробинга со стороны DPI и просто
экономит ресурсы.
Значит первым делом нужно создать 2 пары ключей : для сервера и для клиента.
wg genkey генерит приватный ключ, wg pubkey получает из него публичный ключ.

# wg genkey
oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0=
# echo oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0= | wg pubkey
bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
# wg genkey
OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM=
# echo OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM= | wg pubkey
EELdA2XzjcKxtriOCPBXMOgxlkgpbRdIyjtc3aIpkxg=

Пишем конфиг
--/etc/wireguard/wgvps.conf-------------------
[Interface]
PrivateKey = OKXX0TSlyjJmGt3/yHlHxi0AqjJ0vh+Msne3qEHk0VM=
ListenPort = 12345

[Peer]
#Endpoint =
PublicKey = bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
AllowedIPs = 192.168.254.3
PersistentKeepalive=20
----------------------------------------------

Wireguard - минималистичный vpn. В нем нет никаких средств для автоконфигурации ip.
Все придется прописывать руками.
В wgvps.conf должны быть перечислены все пиры с их публичными ключами,
а так же прописаны допустимые для них ip адреса.
Назначим нашему клиенту 192.168.254.3. Сервер будет иметь ip 192.168.254.1.
Endpoint должен быть прописан хотя бы на одном пире.
Если endpoint настроен для пира, то wireguard будет периодически пытаться к нему подключиться.
В схеме клиент/сервер у сервера можно не прописывать endpoint-ы пиров, что позволит
менять ip и быть за nat. Endpoint пира настраивается динамически после успешной фазы
проверки ключа.

Включаем маршрутизцию :
# echo net.ipv4.ip_forward = 1 >>/etc/sysctl.conf
# sysctl -p

Интерфейс конфигурится стандартно для дебианоподобных систем :

--/etc/network/interfaces.d/wgvps-------------
auto wgvps
iface wgvps inet static
        address 192.168.254.1
        netmask 255.255.255.0
        pre-up ip link add $IFACE type wireguard
        pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf
        post-up iptables -t nat -A POSTROUTING -o eth0 -s 192.168.254.0/24 -j MASQUERADE
        post-up iptables -A FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
        post-down iptables -D FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
        post-down iptables -t nat -D POSTROUTING -o eth0 -s 192.168.254.0/24 -j MASQUERADE
        post-down ip link del $IFACE
----------------------------------------------

Поднятие через ifup wgvps, опускание через ifdown wgvps.
При поднятии интерфейса заодно настраивается nat. eth0 здесь означает интерфейс vpn сервера с инетовским ip адресом.
Если у вас какая-то система управления фаерволом, то надо настройку nat прикручивать туда.
Пример написан для простейшего случая, когда никаких ограничений нет, таблицы iptables пустые.
Чтобы посмотреть текущие настройки wireguard, запустите 'wg' без параметров.


--- Поднятие клиента ---

# opkg update
# opkg install wireguard

Добавляем записи в конфиги.

--/etc/config/network--------------------------
config interface 'wgvps'
	option proto 'wireguard'
	option auto '1'
	option private_key 'oAUkmhoREtFQ5D5yZmeHEgYaSWCcLYlKe2jBP7EAGV0='
	option listen_port '12345'
	option metric '9'
	option mtu '1420'

config wireguard_wgvps
	option public_key 'EELdA2XzjcKxtriOCPBXMOgxlkgpbRdIyjtc3aIpkxg=
	list allowed_ips '0.0.0.0/0'
	option endpoint_host '91.15.68.202'
	option endpoint_port '12345'
	option route_allowed_ips '0'
	option persistent_keepalive '20'

config interface 'wgvps_ip'
	option proto 'static'
	option ifname '@wgvps'
	list ipaddr '192.168.254.3/24'

config route
	option interface 'wgvps'
	option target '0.0.0.0/0'
	option table '100'
	
config rule
	option mark '0x800/0x800'
	option priority '100'
	option lookup '100'
------------------------------------------------

--/etc/config/firewall--------------------------
config zone
	option name 'tunvps'
	option output 'ACCEPT'
	option input 'REJECT'
	option masq '1'
	option mtu_fix '1'
	option forward 'REJECT'
	option network 'wgvps wgvps_ip'

config forwarding
	option dest 'tunvps'
	option src 'lan'

config rule
	option name 'Allow-ICMP-tunvps'
	option src 'tunvps'
	option proto 'icmp'
	option target 'ACCEPT'
	
config rule
	option target 'ACCEPT'
	option src 'wan'
	option proto 'udp'
	option family 'ipv4'
	option src_port '12345'
	option src_ip '91.15.68.202'
	option name 'WG-VPS'
------------------------------------------------

Что тут было сделано :
*) Настроен интерфейс wireguard. Указан собственный приватный ключ.
*) Настроен пир-партнер с указанием его публичнго ключа и endpoint (ip:port нашего сервера)
   такая настройка заставит периодически долбиться на сервер по указанному ip
   route_allowed_ip '0'  запрещает автоматическое создание маршрута
   allowed_ips '0.0.0.0/0' разрешает пакеты с любым адресом источника.
    ведь мы собираемся подключаться к любым ip в инете
   persistent_keepalive '20'  помогает исключить дропание mapping на nat-е, если мы сидим за ним,
    да и вообще полезная вещь, чтобы не было подвисших пиров
*) Статическая конфигурация ip интерфейса wgvps.
*) Маршрут default route на wgvps в отдельной таблице маршрутизации с номером 100. Аналог команды ip route add .. table 100
*) Правило использовать таблицу 100 при выставлении в mark бита 0x800. Аналог команды ip rule.
*) Отдельная зона фаервола для VPN - 'tunvps'. В принципе ее можно не создавать, можете приписать интерфейс к зоне wan.
   Но в случае с отдельной зоной можно настроить особые правила на подключения с vpn сервера в сторону клиента.
*) Разрешение форвардинга между локалкой за роутером и wgvps.
*) Разрешение принимать icmp от vpn сервера, включая пинги. ICMP жизненно важны для правильного функционирования ip сети !
*) И обязательно проткнуть дырку в фаерволе, чтобы принимать пакеты wireguard со стороны инетовского ip vpn сервера.
   
# fw3 restart
# ifup wgvps
# ifconfig wgvps
# ping 192.168.254.1

Если все хорошо, должны ходить пинги.
С сервера не помешает :
# ping 192.168.254.3


--- Маркировка трафика ---

Завернем на vpn все из ipset zapret на tcp:443 и все из ipban.
OUTPUT относится к исходящим с роутера пакетам, PREROUTING - ко всем остальным.
Если с роутера ничего заруливать не надо, можно опустить все до команд с PREROUTING.

--/etc/firewall.user----------------------------
. /lib/functions/network.sh

network_find_wan wan_iface

for ext_iface in $wan_iface; do
    network_get_device DEVICE $ext_iface
    
    iptables -t mangle -C OUTPUT -p tcp --dport 443 -o $DEVICE -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800 ||
     iptables -t mangle -I OUTPUT -p tcp --dport 443 -o $DEVICE -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800
    iptables -t mangle -C OUTPUT -o $DEVICE -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800 ||
     iptables -t mangle -I OUTPUT -o $DEVICE -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800
done

iptables -t mangle -C PREROUTING -p tcp --dport 443 -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800 ||
 iptables -t mangle -I PREROUTING -p tcp --dport 443 -m set --match-set zapret dst -j MARK --set-mark 0x800/0x800
iptables -t mangle -C PREROUTING -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800 ||
 iptables -t mangle -I PREROUTING -m set --match-set ipban dst -j MARK --set-mark 0x800/0x800
------------------------------------------------

# fw3 restart


--- По поводу двойного NAT ---

В описанной конфигурации nat выполняется дважды : на роутере-клиенте происходит замена адреса источника из LAN
на 192.168.254.3 и на сервере замена 192.168.254.3 на внешний адрес сервера в инете.
Зачем так делать ? Исключительно для простоты настройки. Но если вы готовы чуток еще поднапрячься и не хотите двойного nat,
то можете вписать в /etc/config/firewall "masq '0'", на сервер дописать маршрут до вашей подсети lan.
Чтобы не делать это для каждого клиента, можно отвести под всех клиентов диапазон 192.168.0.0-192.168.127.255
и прописать его одним маршрутом.

--/etc/network/interfaces.d/wgvps-------------
        post-up ip route add dev $IFACE 192.168.0.0/17
        post-down ip route del dev $IFACE 192.168.0.0/17
----------------------------------------------

Так же необходимо указать wireguard дополнительные разрешенные ip для peer :

--/etc/wireguard/wgvps.conf-------------------
[Peer]
PublicKey = bCdDaPYSTBZVO1HTmKD+Tztuf3PbOWGDWfz7Lb1E6C4=
AllowedIPs = 192.168.254.3, 192.168.2.0/24
----------------------------------------------

Всем клиентам придется назначать различные диапазоны адресов в lan и индивидуально прописывать AllowedIPs
для каждого peer.

# ifdown wgvps ; ifup wgvps

На клиенте разрешим форвард icmp, чтобы работал пинг и корректно определялось mtu.

--/etc/config/firewall--------------------------
config rule
	option name 'Allow-ICMP-tunvps'
	option src 'tunvps'
	option dest 'lan'
	option proto 'icmp'
	option target 'ACCEPT'
------------------------------------------------

# fw3 restart

Сейчас уже можно с vpn сервера пингануть ip адрес внутри локалки клиента. Пинги должны ходить.

Отсутствие двойного NAT значительно облегчает проброс портов с внешнего IP vpn сервера в локалку какого-либо клиента.
Для этого надо выполнить 2 действия : добавить разрешение в фаервол на клиенте и сделать dnat на сервере.
Пример форварда портов 5001 и 5201 на 192.168.2.2 :

--/etc/config/firewall--------------------------
config rule
        option target 'ACCEPT'
        option src 'tunvps'
        option dest 'lan'
        option proto 'tcp udp'
        option dest_port '5001 5201'
        option dest_ip '192.168.2.2'
        option name 'IPERF'
------------------------------------------------

# fw3 restart

--/etc/network/interfaces.d/wgvps-------------
	post-up iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
	post-up iptables -t nat -A POSTROUTING -o $IFACE -d 192.168.2.2 -p tcp -m multiport --dports 5001,5201 -j MASQUERADE
	post-up iptables -t nat -A PREROUTING -i eth0 -p udp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
	post-up iptables -t nat -A POSTROUTING -o $IFACE -d 192.168.2.2 -p udp -m multiport --dports 5001,5201 -j MASQUERADE
	post-down iptables -t nat -D PREROUTING -i eth0 -p tcp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
	post-down iptables -t nat -D POSTROUTING -o $IFACE -d 192.168.2.2 -p tcp -m multiport --dports 5001,5201 -j MASQUERADE
	post-down iptables -t nat -D PREROUTING -i eth0 -p udp -m multiport --dports 5001,5201 -j DNAT --to-destination 192.168.2.2
	post-down iptables -t nat -D POSTROUTING -o $IFACE -d 192.168.2.2 -p udp -m multiport --dports 5001,5201 -j MASQUERADE
----------------------------------------------

# ifdown wgvps ; ifup wgvps

Пример приведен для iperf и iperf3, чтобы показать как пробрасывать несколько портов tcp+udp с минимальным количеством команд.
Проброс tcp и udp порта так же необходим для полноценной работы bittorrent клиента, чтобы работали входящие.

--- Как мне отправлять на vpn весь трафик с bittorrent ? ---

Можно поступить так : посмотрите порт в настройках torrent клиента, убедитесь, что не поставлено "случайный порт",
добавьте на роутер правило маркировки по порту источника.
Но мне предпочтительно иное решение. На windows есть замечательная возможность
прописать правило установки поля качества обслуживания в заголовках ip пакетов в зависимости от процесса-источника.
Для windows 7/2008R2 необходимо будет установить ключик реестра и перезагрузить комп :
# reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\QoS /v "Do not use NLA" /t REG_SZ /d "1"
Редактировать политику можно в : gpedit.msc -> Computer Configuration -> Windows Settings -> Policy-based QoS
На win 10 ключик реестра больше не работает, правила qos в gpedit применяются только для профиля домена.
Необходимо пользоваться командой powershell New-NetQosPolicy. Гуглите хелп по ней. Пример :
# powershell New-NetQosPolicy -Name "torrent" -AppPathNameMatchCondition "qbittorrent.exe" -DSCPAction 1
Однозначно требуется проверка в wireshark или netmon успешности установки поля dscp. Если там по-прежнему 0x00,
значит что-то не сработало. 0x04 означает DSCP=1 (dscp находится в старших 6 битах).

На роутере в фаер прописываем правило :

--/etc/config/firewall--------------------------
config rule
	option target 'MARK'
	option src 'lan'
	option proto 'all'
	option extra '-m dscp --dscp 1'
	option name 'route-dscp-1'
	option set_mark '0x0800/0x0800'
------------------------------------------------

# fw3 restart

Теперь все с полем dscp "1" идет на vpn. Клиент сам решает какой трафик ему нужно забрасывать
на vpn, перенастраивать роутер не нужно.
На linux клиенте проще всего будет выставлять dscp в iptables по номеру порта источника :

--/etc/rc.local---------------------------------
iptables -t mangle -A OUTPUT -p tcp --sport 23444 -j DSCP --set-dscp 1
iptables -t mangle -A OUTPUT -p udp --sport 23444 -j DSCP --set-dscp 1
------------------------------------------------

можно привязываться к pid процесса, но тогда нужно перенастраивать iptables при каждом перезапуске
торент клиента, это требует рута, и все становится очень неудобно.

--- А если не заработало ? ---

Мануал пишется не как копипастная инструкция, а как помощь уже соображающему.
В руки вам ifconfig, ip, iptables, tcpdump, ping. В умелых руках творят чудеса.
