Строим маршрутизатор в SOCKS на ноутбуке с Debian 10
Целый год (или два) я откладывал публикацию данной статьи по главной причине — мной уже были опубликованы две статьи, в которых я описал процесс создания маршрутизатора в SOCKS из самого обычного ноутбука с Debian.
Однако, с тех пор стабильная версия Debian обновилась до Buster, мне в личку обратилось достаточное количество людей с просьбой помочь в настройке, а значит, мои предыдущие статьи не являются исчерпывающими. Что ж, я и сам догадывался, что методы, изложеннные в них, не до конца раскрывают все тонкости настройки Linux для маршрутизации в SOСKS. К тому же они написаны для Debian Stretch, а после обновления до Buster, в системе инициализации systemd, я заметил небольшие изменения во взаимодействии служб. Да и в самих статьях я не использовал systemd-networkd, хотя она лучше всего подходит для сложных сетевых конфигураций.
Кроме вышеуказаных изменений, в мою конфигурацию добавились такие службы как hostapd — служба для виртуализации точки доступа, ntp для синхронизации времени клиентов локальной сети, dnscrypt-proxy для шифрования соединений по протоколу DNS и отключения рекламы на клиентах локальной сети, а также, как я упомянал ранее, systemd-networkd для конфигруации сетевых интерфейсов.
Вот простейшая блок-схема, внутреннего устройства такого маршрутизатора.
Итак, я напомню, какие цели преследует цикл данных статей:
Маршрутизировать в SOCKS все соединения ОС, а также соединения всех устройств, состоящих в одной сети с ноутбуком.
Ноутбук в моем случае должен оставаться полностью мобильным. То есть, давать возможность использовать окружение рабочего стола и не быть привязанным к физическому местуположению.
Последний пункт подразумевает подключение и маршрутизацию только через встроенный беспроводной интерфейс.
Ну, и конечно, создание исчерпывающего руководства, а также разбор соответсвующих технологий в меру моих скромных познаний.
Что будет рассмотрено в данной статье:
git — скачаем репоизитории проектов tun2socks, необходимого для маршрутизации трафика TCP в SOCKS, и create_ap — скрипта для автоматизации настройки виртуальной точки доступа с помощью hostapd.
tun2socks — построим и установим службу systemd в систему.
systemd-networkd — настроим беспроводной и виртуальные интерфейсы, таблицы статической маршрутизации и перенаправление пакетов.
create_ap — установим службу systemd в систему, настроим и запустим виртуальную точку доступа.
Необязательные шаги:
ntp — установим и настроим сервер для сихронизации времени на клиентах виртуальной точки доступа.
dnscrypt-proxy — зашифруем запросы DNS, маршрутизируем их в SOCKS и отключим рекламные домены для локальной сети.
Зачем всё это?
Это один из способов организации защиты TCP-соединений локальной сети. Главное преимущество — все соединения идут в SOCKS, если для них не построен статический маршрут через оригинальный шлюз. Это значит, что не нужно прописывать настройки SOCKS-сервера ни отдельным программам, ни клиентам в локальной сети — они все идут в SOCKS по-умолчанию, так как он является шлюзом по-умолчанию, пока мы не укажем обратного.
По сути мы добавляем второй шифрующий роутер в качестве ноутбука перед оригинальным роутером и используем интернет соединение оригинального роутера для уже зашифрованных SOCKS-запросов ноутбука, который, в свою очередь, маршрутизирует и шифрует запросы клиентов локальной сети.
С точки зрения провайдера мы постоянно подключены к одному серверу с зашифрованным трафиком.
Соответственно, все устройства подключаются к виртуальной точке доступа ноутбука.
Установите в систему tun2socks
Пока на вашей машине есть интернет, скачайте все необходимые инструменты.
apt update
apt install git make cmake
Скачайте пакет badvpn
git clone https://github.com/ambrop72/badvpn
В вашей системе появится папка badvpn. Создайте отдельную папку для сборки
--tundev — принимает имя виртуального интерфейса, который мы инициализируем с помощью systemd-networkd.
--netif-ipaddr — сетевой адрес «маршрутизатора» tun2socks, к которому подключается виртуальный интерфейс. Лучше сделать отдельной зарезервированной подсетью.
--socks-server-addr — принимает сокет (адрес:порт сервера SOCKS).
Если ваш SOCKS сервер требует аутентификации, вы можете указать параметры --username и --password.
Далее зарегистрируйте службу
systemctl daemon-reload
И включите
systemctl enable tun2socks
Прежде чем запускать службу, обеспечим её виртуальным сетевым интерфейсом.
NetworkManager-wait-online — это служба, которая ждет наличие работающего сетевого подключения прежде, чем systemd продолжит запуск других служб, зависящих от наличия сети. Мы отключаем её, так как перейдем на аналог systemd-networkd.
Давайте сразу включим его:
systemctl enable systemd-networkd-wait-online
Настройте беспроводной сетевой интерфейс
Создайте файл конфигурации systemd-networkd для беспроводного сетевого интерфейса /etc/systemd/network/25-wlp6s0.network.
Name — это имя вашего беспроводного интерфейса. Идентифицируйте его командой ip a.
IPForward — директива, которая включает перенаправление пакетов на сетевом интерфейсе.
Address отвечает за присвоение IP-адреса беспроводному интерфейсу. Мы указываем его статически потому, что при эквивалентной директиве DHCP=yes, systemd-networkd создаёт в системе шлюз по-умолчанию. Тогда весь трафик пойдет через оригинальный шлюз, а не через будущий виртуальный интерфейс в отличной подсети. Вы можете проверить текущий шлюз по-умолчанию командой ip r
Создайте статический маршрут для удалённого сервера SOCKS
Если ваш SOCKS сервер не локальный, а удалённый, то вам необходимо создать для него статический маршрут. Для этого добавьте секцию Route в конец созданного вами файла конфигурации беспроводного интерфейса со следующим содержанием:
[Route]
Gateway=192.168.1.1
Destination=0.0.0.0
Gateway — это шлюз по-умолчанию или адрес вашей оригинальной точки доступа.
Destination — адрес сервера SOCKS.
Настройте wpa_supplicant для systemd-networkd
systemd-networkd использует wpa_supplicant для подключения к защищенной точке доступа. При попытке «поднять» беспроводной интерфейс systemd-networkd запускает службу wpa_supplicant@имя, где имя — это имя беспроводного интерфейса. Если вы не использовали systemd-networkd до этого момента, то, наверняка, эта служба в вашей системе отсутствует.
Поэтому создайте ее командой:
systemctl enable wpa_supplicant@wlp6s0
Я использовал wlp6s0 в качестве имени своего беспроводного интерфейса. У вас это имя может отличаться. Вы можете узнать его командой ip l.
Теперь созданная служба wpa_supplicant@wlp6s0 будет запускаться при «поднятии» беспроводного интерфейса, однако она, в свою очередь, будет искать настройки SSID и пароля точки доступа в файле /etc/wpa_supplicant/wpa_supplicant-wlp6s0. Поэтому необходимо создать его с помощью утилиты wpa_passphrase.
где SSID — это имя вашей точки доступа, password — пароль, а wlp6s0 — имя вашего беспроводного интерфейса.
Инициализируйте виртуальный интерфейс для tun2socks
Создайте файл для инициализации нового вирутального интерфейса в системе/etc/systemd/network/25-tun2socks.netdev
[NetDev]
Name=tun2socks
Kind=tun
Name — это имя, которое systemd-networkd назначит будущему виртуальному интерфейсу при его инициализации.
Kind — это тип виртуального интерфейса. Исходя из названия службы tun2socks, вы можете догататься, что она использует интерфейс типа tun.
netdev — это расширение файлов, которые systemd-networkd использует для инициализации виртуальных сетевых интерфейсов. Адрес и другие сетевые настройки для этих интерфейсов указываются в .network-файлах.
Создайте такой файл /etc/systemd/network/25-tun2socks.network со следующим содержимым:
Name — имя виртуального интерфейса, которое вы указали в netdev-файле.
Address — IP адрес, который будет назначен вирутальному интерфейсу. Должен быть в одной сети с адресом, который вы указали в службе tun2socks
Gateway — IP адрес «маршрутизатора» tun2socks, который вы указали при создании службы systemd.
Таким образом, интерфейс tun2socks имеет адрес 172.16.1.2, а служба tun2socks — 172.16.1.1, то есть является шлюзом для всех соединений с виртуального интерфейса.
Настройте виртуальную точку доступа
Установите зависимости:
apt install util-linux procps hostapd iw haveged
Скачайте репозиторий сreate_ap на свою машину:
git clone https://github.com/oblique/create_ap
Перейдите в папку репозитория на вашей машине:
cd create_ap
Установите в систему:
make install
В вашей системе появится конфиг /etc/create_ap.conf. Вот основные опции для правки:
GATEWAY=10.0.0.1 — лучше сделать отдельной зарезервированной подсетью.
NO_DNS=1 — выключите, так как этим параметром будет управлять виртуальный интерфейс systemd-networkd.
INTERNET_IFACE=tun2socks — виртуальный интерфейс, созданный для tun2socks.
SSID=hostapd — имя виртуальной точки доступа.
PASSPHRASE=12345678 — пароль.
Не забудьте включить службу:
systemctl enable create_ap
Включите DHCP сервер в systemd-networkd
Служба create_ap инициализирует в системе виртуальный интерфейс ap0. По идее, на этом интерфейсе «висит» dnsmasq, но зачем устанавливать лишние службы, если systemd-networkd содержит встроенный DHCP-сервер?
Чтобы включить его, определим сетевые настройки для виртуальной точки. Для этого создайте файл /etc/systemd/network/25-ap0.network со следующим содержимым:
После того, как служба сreate_ap инициализирует виртуальный интерфейс ap0, systemd-networkd автоматически присвоит ему IP-адрес и включит DHCP сервер.
Строки EmitDNS=yes и DNS=10.0.0.1 передают настройки DNS сервера устройствам, подключенным к точке доступа.
Если вы не планируете использовать локальный DNS сервер — в моём случае это dnscrypt-proxy — можете установить DNS=10.0.0.1 в DNS=192.168.1.1, где 192.168.1.1 — адрес вашего оригинального шлюза. Тогда запросы DNS вашего хоста и локальной сети пойдут в незашифрованном виде через серверы провайдера.
EmitNTP=yes и NTP=192.168.1.1 передают настройки NTP.
Добавьте адреса публичных серверов, например, Google Public NTP:
server time1.google.com ibrust
server time2.google.com ibrust
server time3.google.com ibrust
server time4.google.com ibrust
Предоставьте доступ к серверу клиентам из вашей сети:
restrict 10.0.0.0 mask 255.255.255.0
Включите трансляцию в вашу сеть:
broadcast 10.0.0.255
Наконец, добавьте адреса этих серверов в таблицу статической маршрутизации. Для этого откройте файл конфигурации беспроводного интерфейса /etc/systemd/network/25-wlp6s0.network и добавьте в конец секции Route.
После перезагрузки или перезапуска у вас появится вторая точка доступа, которая маршрутизирует хост и устройства локальной сети в SOCKS.
Примерно так выглядит вывод ip a обычного ноутбука:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: tun2socks: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 500
link/none
inet 172.16.1.2/24 brd 172.16.1.255 scope global tun2socks
valid_lft forever preferred_lft forever
inet6 fe80::122b:260:6590:1b0e/64 scope link stable-privacy
valid_lft forever preferred_lft forever
3: enp4s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether e8:11:32:0e:01:50 brd ff:ff:ff:ff:ff:ff
4: wlp6s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 4c:ed:de:cb:cf:85 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.2/24 brd 192.168.1.255 scope global wlp6s0
valid_lft forever preferred_lft forever
inet6 fe80::4eed:deff:fecb:cf85/64 scope link
valid_lft forever preferred_lft forever
5: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 4c:ed:de:cb:cf:86 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.1/24 brd 10.0.0.255 scope global ap0
valid_lft forever preferred_lft forever
inet6 fe80::4eed:deff:fecb:cf86/64 scope link
valid_lft forever preferred_lft forever
В итоге
Провайдер видит только зашифрованное соединение к вашему серверу SOCKS, а значит, ничего не видит.
И всё же он видит ваши NTP запросы, чтобы предотвратить это, удалите статические маршруты для NTP серверов. Однако, не факт, что ваш сервер SOCKS разрешает протокол NTP.
Костыль, замеченный на Debain 10
Если попытаться перезапустить сетевую службу из консоли, то она упадет с ошибкой. Связанно это с тем, что её часть в виде виртуального интерфейса привязана к службе tun2socks, а значит используется. Чтобы перезапустить сетевую службу, сначала нужно остановить службу tun2socks. Но, я думаю, если вы дочитали до конца, для вас это точно не проблема!