Pull to refresh

Tun2Socks: прокси-сервер в качестве шлюза, или VPN через прокси

Reading time9 min
Views60K
  1. Что такое Tun2Socks

  2. Инструкция для Windows

  3. Инструкция для Linux

В бытовом случае в сетевых настройках вашего компьютера указан шлюз по умолчанию. Чаще всего устройство, являющееся шлюзом, называют "роутер" или "маршрутизатор" — через него идут все запросы на IP-адреса, которые не входят в вашу локальную сеть. Прокси-сервер (от англ. "уполномоченный" или "доверенный") также выступает посредником между вами и целевым сетевым ресурсом, но не является шлюзом по умолчанию, то есть для его использования в приложении нужно явно указать соответствующие параметры. Самый простой пример — доступ в сети I2P или Tor. Всю внутреннюю логику этих сетей обеспечивает отдельное приложение, которое предоставляет пользователю прокси-интерфейс для подключения. Указав нужный прокси в настройках веб-браузера, мы можем посещать сайты с доменными именами ".i2p" и ".onion", о которых обычный маршрутизатор даже не догадывается. Также прокси-сервисы набирают популярность для обхода блокировок: прописал в настройках браузера какой-нибудь прокси из либеральной страны и открываешь любые сайты, не зная духоскрепного маразма.

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

Какой бы сценарий использования прокси у вас ни был, использовать шлюз по умолчанию в большинстве случаев удобнее. Хотя бы потому, что некоторые приложения не умеют работать через прокси.

Tun2Socks

Tun2Socks — свободный кроссплатформенный проект (GPL-3.0), написанный на Golang. Костяк команды разработчиков составляют китайцы. Приложение не имеет графической оболочки и конфигурируется незамысловатыми параметрами при запуске. Название Tun2Socks (Tunnel to SOCKS) трактуется как "туннель через SOCKS-прокси". Почему именно SOCKS, когда есть HTTP-прокси? Ответ прост: работать через HTTP-прокси Tun2Socks тоже умеет, но протокол HTTP не поддерживает передачу UDP-трафика. Через UDP идет большинство информации, доставка которой требует максимальной скорости (аудио- и видеозвонки, онлайн игры, а также DNS-запросы, разрешающие человекочитаемые имена сетевых ресурсов в IP-адреса). Поэтому поддержку UDP нельзя недооценивать.

Суть работы Tun2Socks сводится к созданию виртуального сетевого адаптера, который операционная система будет воспринимать как обычный сетевой интерфейс. Вся информация, пришедшая на такой виртуальный адаптер, фактически будет передана внутрь Tun2Socks, который обеспечит необходимую логику дальнейшей передачи информации на прокси-сервер.

Информация об использовании утилиты при запуске с параметром --help:

Usage of tun2socks:
  -device string
    	Use this device [driver://]name
  -fwmark int
    	Set firewall MARK (Linux only)
  -interface string
    	Use network INTERFACE (Linux/MacOS only)
  -loglevel string
    	Log level [debug|info|warn|error|silent] (default "info")
  -mtu int
    	Set device maximum transmission unit (MTU)
  -proxy string
    	Use this proxy [protocol://]host[:port]
  -stats string
    	HTTP statistic server listen address
  -token string
    	HTTP statistic server auth token
  -udp-timeout int
    	Set timeout for each UDP session
  -version
    	Show version information and quit

Всё может показаться ясным с первого взгляда только бывалому админу, либо тому, кто ничего на самом деле не понял. При практическом знакомстве с Tun2Socks встает вопрос: если в системе создастся виртуальный сетевой адаптер, то как он станет шлюзом по умолчанию и нужно ли вручную задавать ему адрес. На помощь приходит документация.

Дублировать здесь официальное описание проекта и всю документацию не имеет смысла, поэтому перейдем к сути — к практической конфигурации шлюза с пояснением каждого шага.

Windows

Для начала необходимо скачать свежую версию Tun2Socks. Бинарники распространяются на странице релизов в официальном гит-репозитории проекта. Выберите один из пакетов, название которого начинается на tun2socks-windows. Если у вас 64-разрядная Windows на стареньком железе, вам наверняка подойдет tun2socks-windows-amd64.zip (так как архитектура ARM на старых машинах с Windows мне еще не встречалась).

После загрузки распакуйте архив в любое удобное место.

Tun2Socks создает виртуальный сетевой адаптер, но драйвер для этого (Wintun) нужно скачать отдельно. Вот прямая ссылка для загрузки версии Wintun 0.11. Рекомендую именно эту версию, так как с более новыми версиями в моем случае Tun2Socks v2.3.1 работать отказался. При желании, свежий релиз драйвера можно найти на официальной странице. Из всего архива вам понадобится только один файл wintun.dll, который надо взять из нужной директории в зависимости от вашей операционной системы. В случае архитектуры amd64, путь до нужной библиотеки выглядит так: wintun/bin/amd64/wintun.dll. Положите подходящий файл wintun.dll в директорию, где находится исполняемый файл Tun2Socks.

Tun2Socks запускается с передаваемыми значениями через командную строку (команды, приведенные ниже, должны быть выполнены с правами администратора). Команда для простого запуска имеет следующий вид:

tun2socks-windows-amd64.exe -device tun://gatewaytun -proxy socks5://10.10.100.1:1080
  • tun2socks-windows-amd64.exe является именем исполняемого файла Tun2Socks;

  • -device tun://gatewaytun определяет название нового виртуального сетевого интерфейса (gatewaytun);

  • -proxy socks5://10.10.100.1:1080 сообщает протокол (в моем случае это SOCKS5) и адрес прокси-сервера.

Этого достаточно, чтобы создать в системе новый сетевой интерфейс, но работать, как нам хочется, он пока что не будет. Для этого необходимо вручную присвоить новому сетевому интерфейсу IP-адрес и объяснить операционной системе, что он является шлюзом.

Присвоить интерфейсу IP-адрес и указать маску подсети можно через стандартный графический интерфейс Windows, но воспользуемся благами командной строки:

netsh interface ip set address name="gatewaytun" static 127.254.254.1 255.255.255.255

В примере виртуальному интерфейсу присваивается адрес 127.254.254.1, но фактически это может быть любой частный адрес из подсети, которая, во-первых, не используется другими сетевыми адаптерами вашей операционной системы, во-вторых, не используется в локальной сети вашего предприятия или дома (иначе будет нарушена локальная маршрутизация). В большинстве случаев адрес из примера будет корректным значением (так как используется диапазон 127.0.0.1/8). В некоторых тестах Windows 10 отказывалась применять подобный адрес к интерфейсу. Если отказалась и у вас — воспользуйтесь чем-нибудь вроде 10.254.254.1.Итак, будем считать, что адрес виртуальному сетевому интерфейсу присвоен.

Теперь нужно сообщить операционной системе новый интерфейс в качестве шлюза:

route add 0.0.0.0 mask 0.0.0.0 127.254.254.1

Внимание! Если прокси-сервер находится не в локальной сети с той же подсетью, что и один из сетевых интерфейсов вашего компьютера, т.е. обращение к прокси-серверу осуществляется через уже существующий шлюз, необходимо оставить доступ к прокси-серверу в прежнем виде, иначе приведенная конфигурация работать не будет — согласитесь, что попытка подключения к прокси-серверу через сам же прокси-сервер является абсурдом. На практике это означает, что для подключения к прокси-серверу нужно добавить еще один маршрут:

route add 10.10.100.0 mask 255.255.255.0 10.10.5.25

В примере указано правило маршрутизации в подсеть 10.10.100.0/24, которая должна идти не через общий шлюз (gatewaytun), а через сетевой интерфейс, имеющий доступ к устройству с адресом 10.10.5.25 (которое является шлюзом в нужную подсеть). Это правило справедливо, во-первых, если нужно сохранить доступ в подсеть локальной сети, которая недоступна непосредственно и, во-вторых, что более важно — если в заданной подсети находится сам прокси-сервер, через который в дальнейшем пойдет весь наш трафик.

При домашнем использовании, когда нет никаких локальных подсетей, и всё, что требуется, это подключение к прокси-серверу через интернет-провайдера, приведенная выше команда заменяется этой:

route add 11.11.11.11 mask 255.255.255.255 10.10.5.25
  • 11.11.11.11 — адрес прокси-сервера в интернете;

  • 255.255.255.255 — маска, означающая, что в правило входит только адрес прокси-сервера;

  • 10.10.5.25 — адрес шлюза в локальной сети, который вам предоставляет интернет-провайдер.

Если вы используете не HTTP-, а SOCKS-прокси (который поддерживает UDP), в настройках виртуального сетевого интерфейса можно указать адрес DNS-сервера, через который мы хотим резолвить доменные имена. Это возможно сделать как через графический интерфейс Windows, так и через командную строку:

netsh interface ip set dns "gatewaytun" static 1.1.1.1

В примере адрес 1.1.1.1 является адресом DNS-сервера.

В итоге получается следующий набор команд:

tun2socks-windows-amd64.exe -device tun://gatewaytun -proxy ПРОТОКОЛ_ПРОКСИ://АДРЕС_ПРОКСИ_СЕРВЕРА:ПОРТ
netsh interface ip set address name="gatewaytun" static 127.254.254.1 255.255.255.255
route add 0.0.0.0 mask 0.0.0.0 127.254.254.1

# Опционально. Для локальной сети предприятия.
route add СЕГМЕНТ_ЛОКАЛЬНОЙ_СЕТИ mask МАСКА_СЕГМЕНТА АДРЕСА_ШЛЮЗА_В_СЕГМЕНТ

# Опционально. При использовании прокси-сервера в интернете.
route add АДРЕС_ПРОКСИ_СЕРВЕРА mask 255.255.255.255 АДРЕС_ШЛЮЗА_ПРОВАЙДЕРА

# Опционально. DNS-сервер, если прокси-сервер умеет работать с UDP.
netsh interface ip set dns "gatewaytun" static АДРЕС_СЕРВЕРА_DNS

Большинству пользователей ручное выполнение всех команд может показать неудобным. Такие люди могут поэкспериментировать с автоматизированными сценариями (батниками). Например, вписать все нужные команды в какой-нибудь start.bat и добавить его в автозагрузку. В батниках и правах доступа Windows я не силён. В напутствие лишь замечу, что все команды должны быть исполнены с правами администратора. Возможно, кто-то поделится красивым скриптом в комментариях.

Linux

Пользователи GNU/Linux (и других *nix-систем) в своем большинстве являются более компетентными в вопросах командной строки и системных настроек, поэтому местами пояснения будут более скудные (тем более, что суть происходящего уже подробно описана чуть выше). Практическая инструкция дана на примере Debian.

Бинарники для Linux есть среди прочих на странице релизов. Например, для Debian amd64 подойдет вариант tun2socks-linux-amd64.zip. Внутри архива находится один файл. После извлечения присвойте ему флаг исполняемости (chmod +x tun2socks-linux-amd64) и положите в удобное место, например, /usr/sbin/. Дополнительные драйвера для создания туннеля WireGuard в Linux не требуются — современные дистрибутивы поддерживают технологию на уровне ядра.

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

Команда запуска выглядит следующим образом:

/usr/sbin/tun2socks-linux-amd64 -device tun://gatewaytun -proxy socks5://10.10.100.1:1080
  • -device tun://gatewaytun определяет название нового виртуального сетевого интерфейса (gatewaytun);

  • -proxy socks5://10.10.100.1:1080 сообщает протокол (в моем случае это SOCKS5) и адрес прокси-сервера.

После запуска Tun2Socks в системе создается новый сетевой интерфейс с заданным именем. Теперь необходимо откорректировать правила маршрутизации:

# Присваиваем адрес новому интерфейсу
ip addr add 127.254.254.1/32 dev gatewaytun

# Включаем интерфейс
ip link set gatewaytun up

# Добавляем маршрут по умолчанию через новый интерфейс (спасибо @Aytuar)
ip route add default dev gatewaytun metric 50

# Опционально. Добавляем маршрут до прокси-сервера в локальной сети
ip route add АДРЕС_СЕТИ/ПРЕФИКС dev ИМЯ_ИНТЕРФЕЙСА_В_ЛОКАЛЬНОЙ_СЕТИ

# Опционально. Маршрут до прокси-сервера в интернете (наиболее вероятный вариант для дома)
ip route add АДРЕС_ПРОКСИ/32 dev ИМЯ_ИНТЕРФЕЙСА_В_СЕТИ_ПРОВАЙДЕРА

Настройки DNS в *nix-системах, как правило, являются глобальными, поэтому нет нужды указывать их явно для каждого интерфейса. Однако, кому нужно, тот знает не только про /etc/resolv.conf, но и про возможность явного указания DNS-сервера в конфиге сетевых подключений. На этом останавливаться не будем.

Автоматизация — второе имя любого админа. Для Debian я напишу сервис systemd, который будет запускать Tun2Socks и поднимать интерфейс gatewaytun, а в конфигурации данного сетевого интерфейса укажу команды, которые нужно выполнять при его включении. При необходимости вы можете адаптировать данный подход под другие операционные системы с учетом их специфики.

Файл сервиса, который ляжет в /etc/systemd/system/tun2socks.service:

[Unit]
Description=Tun2Socks gateway
After=network.target

[Service]
User=root
Type=idle
ExecStart=/usr/sbin/tun2socks-linux-amd64 -device tun://gatewaytun -proxy socks5://10.10.100.1:1080 & sleep 3; ip link set gatewaytun up
Restart=on-failure

[Install]
WantedBy=multi-user.target

Обратите внимание на путь до Tun2Socks и адрес прокси-сервера в строке ExecStart. Измените эти параметры под себя. После амперсанда указана пауза в три секунды, следом за которой осуществляется включение нового сетевого интерфейса. Пауза задается на случай высокой загрузки системы, чтобы дать время на создание интерфейса перед попыткой его включения.

Указываем в /etc/network/interfaces параметры интерфейса и дополнительные инструкции для исполнения после его включения. Строки добавляются в конец файла:

allow-hotplug gatewaytun
iface gatewaytun inet static
address 127.254.254.0
netmask 255.255.255.255
post-up ip route add default dev gatewaytun metric 50

# Опционально. Добавляем маршрут до прокси-сервера в локальной сети
# post-up ip route add АДРЕС_СЕТИ/ПРЕФИКС dev ИМЯ_ИНТЕРФЕЙСА_В_ЛОКАЛЬНОЙ_СЕТИ

# Опционально. Маршрут до прокси-сервера в интернете (наиболее вероятный вариант для дома)
# post-up ip route add АДРЕС_ПРОКСИ/32 dev ИМЯ_ИНТЕРФЕЙСА_В_СЕТИ_ПРОВАЙДЕРА

# post-up <прочие правила, исполняемые после включения интерфейса (при надобности)>

Теперь, когда всё готово, запускать и отключать шлюз можно двумя простыми командами:

systemctl start tun2socks # ЗАПУСК
systemctl stop tun2socks # ОСТАНОВКА

Если Tun2Socks нужен на постоянной основе, созданную службу можно добавить в автозагрузку:

systemctl enable tun2socks

Послесловие

Мотивом для статьи послужило отсутствие адекватной поисковой выдачи по запросам вроде "шлюз через прокси", "как пустить весь трафик через прокси" и тому подобные. Полагаю, материал будет полезен самой широкой аудитории.

С автоматизацией на Windows долго, честно говоря, не разбирался. Из коробки не завелось и — пусть отдыхает. Не люблю я винду, простите. Да и как любить ее, если для исполнения команды из bat-файла с правами администратора нужно создать ярлык этого батника и поставить в нем галочку "Запускать с правами администратора". Ярлык и галочка, Карл! Да и более того, команда добавления маршрута все равно не хотела отрабатывать.

Спасибо за внимание.

Tags:
Hubs:
Total votes 14: ↑13 and ↓1+13
Comments14

Articles