LINUX.ORG.RU

AmneziaWG selfhost

 ,


2

2

Приветствую, у меня имеется VPS сервер дата центр которого распологается в москве. на нем стоит OS Ubuntu 20.04. Недавно узнал про такой VPN клиент как AmneziaWG в котором можно легко создать свой VPN сервер. И вот у меня возник вопрос: как на ubuntu сделать раздельное туннелирование трафика с отключением DPI. Тобиш к определенным доменам мой VPS сервер будет обращатся с отключенным DPI а все остальные пакеты он проксировать не будет (Нужно для обхода блокировки youtube и discord)


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

Включить только отдельные диапазоны адресов, чтобы они работали через VPN, можно следующим образом.

Пример (для OpenVPN):

route-nopull
route 8.8.8.8 255.255.255.255

Эта команда включит маршрутизацию только адреса 8.8.8.8. А следующая команда позволит исключить 8.8.8.8, продолжив маршрутизировать все остальные адреса:

route 8.8.8.8 255.255.255.255 net_gateway

Узнать IP-адреса отдельных доменов можно консольной командой nslookup.

Пример:

$ nslookup ya.ru
Server:         192.168.101.1
Address:        192.168.101.1#53

Non-authoritative answer:
Name:   YA.RU
Address: 87.250.250.242
Name:   ya.ru
Address: 2a02:6b8::2:242

IPv4-адрес ya.ru — 87.250.250.242.

Такой подход применим только для случаев, когда домены заранее известны (и их немного), они не меняются со временем, не используют балансировку по географическому признаку, и не меняют IP-адреса со временем (такое часто встречается у доменов за CDN).
Если это крупная компания, использующая только собственные диапазоны из собственной автономной системы, можно взять все адреса с их автономной системы, см. https://bgp.he.net/

Также некоторые VPN-клиенты предоставляют собственный драйвер для перенаправления отдельных программ в VPN. Можете попробовать, например, клиент Windscribe — он позволяет загружать собственные конфигурационные файлы OpenVPN/WireGuard (не только сервиса Windscribe).

Альтернативный вариант #1

Поднять «умный» прокси-сервер на компьютере, который сам будет маршрутизировать трафик по доменам через VPN-интерфейс, а сам VPN не будет ничего маршрутизировать (установить маршрут по умолчанию с метрикой выше основного через провайдера).

Добавьте в конфигурационный файл следующие строки в любое место файла (также на примере OpenVPN):

route-nopull
route 0.0.0.0 0 vpn_gateway 1000

Пример конфигурации прокси-сервера v2fly, в котором через VPN маршрутизируется только ifconfig.co. Замените 192.168.100.11 на ваш IP-адрес внутри VPN.

Недостаток — это не VPN: нужно настраивать программы на использование прокси, будут работать только TCP и UDP (только при использовании Socks5, и не во всех программах, браузеры не поддерживают, звонки в discord, с большой вероятностью, также не заработает), и т.п.
Также типичная проблема прокси: даже если UDP поддерживается и в прокси, и в программе, VoIP и другие протоколы, использующие двусторонний UDP с пробивом NAT, скорее всего, не заработают, из-за несохранения порта и отсутствия поддержки TTL. В некоторых клиентах есть отдельные хаки/опции, позволяющие улучшить ситуацию, но необходима спец. настройка, отладка — чаще не работает, чем работает.

В некоторых клиентах (например, sing-box) есть возможность и маршрутизации только отдельных программ/процессов, а также присутствует режим отдельного сетевого интерфейса (tun), при использовании которого не нужно настраивать прокси в каждой из программ. Не уверен, что фильтр по программам/процессам работает в Linux (в Windows работает), но даже в режиме tun это просто прокси, с описанными выше недостатками.

Чтобы прокси мог определить домен, он должен либо понимать протокол, по которому устанавливается соединение (HTTPS/QUIC, с Encrypted Client Hello работать не будет), либо выступать специальным фейковым DNS-сервером.

Альтернативный вариант #2

Маршрутизация «по доменам», средствами DNS-резолвера.

Резолвер dnsmasq можно настроить таким образом, что при запросе определённых доменов, он получит IP-адреса, отдаст клиенту, и добавит их в ipset. Адреса из списка ipset можно маршрутизировать в VPN-интерфейс.

Недостатки:

  • Необходимо использовать именно по-особому настроенный резолвер, любой сторонний DNS не подойдёт
  • Он должен работать на той же машине, где настроен VPN-интерфейс
  • Если разные домены ссылаются на один IP-адрес, оба домена будут маршрутизироваться в VPN
  • Если программа использует доступ прямой доступ к IP-адресу без DNS, ничего работать не будет (адрес не окажется в ipset’е)

Примера настройки под рукой нет, но подобная конфигурация реализована в пакете pbr в OpenWrt, например.
См. справку по опции --ipset в dnsmasq.

Альтернативный вариант #3

Вариация метода #2, в которой используется ремаппинг адресов вместо ipset.

На VPN-сервере запущен специальный DNS-резолвер, устанавливающий отображение (соответствие, маппинг) настоящего IP-адреса домена в свободный IP-адрес большой внутренней подсети, и отдающий запрашиваемому клиенту адрес из внутренней подсети.

Основное преимущество: маршрутизируются только заблокированные домены, а не все сайты на заблокированном IP-адресе.

Описана здесь, реализация здесь и здесь

ValdikSS ★★★★★
()
Последнее исправление: ValdikSS (всего исправлений: 3)

❓ Почему нельзя просто настроить маршрутизацию по доменам, которые передаются в TLS ClientHello, встроенными средствами маршрутизации?

Допустим, вы настроили роутер на анализ пакета TLS ClientHello, который ищёт домен twitter.com. Если такой пакет найдён, IP-адрес добавляется в ipset, после чего маршрутизируется в VPN-интерфейс.

Ну как пример для твиттера mangle правила такие:

 3    ;;; add twitter.com to addr list
      chain=prerouting action=add-dst-to-address-list protocol=tcp 
      address-list=Адрес-лист address-list-timeout=none-dynamic 
      in-interface=!ИнтерфейсVPN log=no log-prefix="" tls-host=twitter.com 

 4    ;;; add mobile.twitter.com to addr list
      chain=prerouting action=add-dst-to-address-list protocol=tcp 
      address-list=Адрес-лист address-list-timeout=none-dynamic 
      in-interface=!ИнтерфейсVPN log=no log-prefix="" tls-host=mobile.twitter.com 

 5    ;;; add api.twitter.com to addr list
      chain=prerouting action=add-dst-to-address-list protocol=tcp 
      address-list=Адрес-лист address-list-timeout=none-dynamic 
      in-interface=!ИнтерфейсVPN log=no log-prefix="" tls-host=api.twitter.com 

 6    ;;; add *.twimg.com to addr list
      chain=prerouting action=add-dst-to-address-list protocol=tcp 
      address-list=Адрес-лист address-list-timeout=none-dynamic 
      in-interface=!ИнтерфейсVPN log=no log-prefix="" tls-host=*.twimg.com 

 7    ;;; add t.co to addr list
      chain=prerouting action=add-dst-to-address-list protocol=tcp 
      address-list=Адрес-лист address-list-timeout=none-dynamic 
      in-interface=!ИнтерфейсVPN log=no log-prefix="" tls-host=t.co 

Каждый раз когда адрес резолвится в новый ip он уходит в address list до следующей перезагрузки роутера. Пока address list не набьется возможно легкое подтупливание, которое решается перезагрузкой страницы.

Вы только что включили маршрутизатор, все таблицы пустые.

  1. Вы открываете twitter.com, происходит резолвинг DNS, браузер устанавливает соединение на IP-адрес, маршрутизатор маршрутизирует его через вашего обычного провайдера;
  2. Происходит TCP handshake (с IP-адреса вашего провайдера), браузер отправляет TLS ClientHello, маршрутизатор считывает SNI, добавляет адрес в таблицу маршрутизации через VPN;
  3. Пакет TLS ClientHello маршрутизируется через интерфейс VPN. В зависимости от настроек маршрутизации и NAT, либо это происходит с правильным IP (тогда пакет доходит до Twitter и отбрасывается сервером с RST, т.е. произошла смена source ip на адрес VPN-сервера, а Twitter знает только о соединении с исходящим IP-адресом вашего провайдера, а не VPN-сервера, и считает соединение некорректным), либо уходит с неправильным адресом (NAT не подхватывает правило уже установленного соединения, у которого внезапно изменился интерфейс с необходимостью еще одной подмены адреса), тогда пакет уходит в VPN, и VPN-сервер его (с большой вероятностью) отбрасывает, т.к. source address клиента не совпадает с сетью VPN.

Итого: первое соединение либо разрывается из-за несовпадения адресов, вызванных внезапной сменой маршрута, либо «зависает», по аналогичной причине. Последующие соединения (если IP-адрес тот же) будут устанавливаться успешно. Если у домена несколько адресов, аналогичные проблемы будут для каждого адреса.

Всё это будет работать только при условии, что IP-адрес заблокированного сайта в принципе доступен, т.е. к нему можно установить соединение и отправить первый TLS-пакет, содержащий домен. Если же заблокирован сам IP-адрес, до анализа домена дело просто не дойдёт.

Техническое решение этой проблемы однозначно осуществимо, но мне неизвестны ни готовые программы, ни даже наработки в эту сторону. Одна из тех проблем, где нужно просто взять и сделать ПО, но из года в год никто не делает.

ValdikSS ★★★★★
()