Если раздать Wi-Fi через VPN задача простая и решаемая, вот даже статья "WiFi-портал в Россию" недавно вышла, то с прокси дело обстоит чуть сложнее, нужно немного костылей и напильников, а так же замечательное ПО под названием tun2socks.
Но, в отличие от VPN, прокси дешевле, и если нужно тестировать мобильные устройства с разных геолокаций - то прокси будет неплохим выходом. Конечно, существуют готовые решения, такие как Double SSH Tunnel Manager и Raspberry с прошивкой "Linux Mars", но мы, как водится, пойдём своим путём, да и готовые решения выше предназначены для другого.
Disclaimer. Статья пишется больше для себя, как заметки на полях, поэтому подробного мануала тут не будет. Тем не менее, материал может быть полезен и неограниченному кругу лиц, кто захочет реализовать самостоятельно. Понадобятся небольшие знания по сетям и линуксам.
Немного за технологию
Для работы с прокси будем использовать такую славную вещь, как tun2socks. На хабре уже была статья про это ПО (настоятельно рекомендую к ознакомлению), где рассказывается как настроить шлюз через прокси на Linux или Windows машине. Я же расскажу чуть подробнее, как настроить такой шлюз на роутере.
Итак, нам понадобится:
Роутер на OpenWrt или роутер, который можно прошить в OpenWrt (я тестировал на незабвенном Tp-Link TL-MR3020 и на не менее незабвенном MikroTik hAP ac²). Помимо работы OpenWrt от роутера понадобится 128 и более мегабайт оперативной памяти и столько же места на внутреннем накопителе - или же возможность установить внешний.
Под внешний накопитель вполне подойдёт обычная usb-флешка или sd-карточка минимального размера. Я экспериментировал с древней флешкой на 4гб. Для ценителей - usb-модем с sd-карточкой:)
Прокси-провайдер (предпочтительнее socks5 c поддержкой udp)
Немного свободного времени
Прошивка роутера
Берём нашу модель и идём на сайт OpenWrt, дальше смотрим-курим поддержку и мануалы по установке. Например, для hAP ac² применимы стандартные методы прошивки для микротиков - https://openwrt.org/toh/mikrotik/common
Подробно расписывать я не буду, но небольшая памятка-TL;DR для микротиков - копируем лицензионный ключ к себе (на всякий случай) выставляем приоритет загрузки на сеть, по BOOTP при помощи например tftp32 грузим sysupgrade.bin, затем при помощи вебморды или ssh+scp прошиваем уже ось initramfs.bin. Если понадобилось вернуть RouterOS, то можно это сделать через netinstall, или через утилиту командной строки rbcfg.
Считаем что роутер у нас перепрошит в OpenWrt. Для роутеров с небольшой внутренней памятью (16мб в hAP ac²!) понадобится перенос системы на внешнюю флешку. Инструкцией в сети полно, поэтому опять же кратенько:
форматируем флешку - можно сделать сразу два раздела, под систему и swap. Под винду я использовал Minitool Partition Wizard. Выбор файловой системы - по вкусу, я вот взял ext4. По размерам - хватит минимального, я подкинул на swap 256мб, под систему - 1Гб
ставим в OpenWrt нужные пакеты (роутер надо будет выпустить в инет):
opkg update
opkg install block-mount kmod-usb-core kmod-usb2 kmod-usb-ohci kmod-usb-storage kmod-fs-ext4
Ротуер в ребут, через dmseg можно проверить, что флешка нашлась. Формируем fstab, можно через block-detect (block detect >> /etc/config/fstab), приводим fstab примерно к такому виду (честно стянуто с инета):
config 'global'
option anon_swap '0'
option anon_mount '1'
option auto_swap '1'
option auto_mount '1'
option delay_root '5'
option check_fs '0'
option from_fstab '1'
config 'swap'
option uuid 'b91e3bff-9e15-4fd0-82e7-25d75d889ce6'
option enabled '1'
config 'mount'
option target '/overlay'
option uuid '7ee9d192-239f-4401-b749-3fb60b4f8eaa'
option fstype 'ext4'
option options 'rw,sync'
option enabled '1'
переносим систему (конечно, на самом деле оверлей) на флешку:
mkdir /mnt/sda2
mount /dev/sda2 /mnt/sda2
tar -C /overlay -cf - . | tar -C /mnt/sda2 -xf -
umount /mnt/sda2
rm -rf /mnt/sda2
ребутаемся, убеждаемся через df -h что место есть и всё в порядке.
Теперь у нас есть роутер, на OpenWrt и с достаточным свободным местом. Едем дальше.
Магия tun2socks
Берём tun2socks под нужную нам платформу из гитхаба разработчика - https://github.com/xjasonlyu/tun2socks/releases. Например, для нашего hAP ac² нужна будет arm-архитектура. Я закинул бинарник сюда - /usr/bin/tun2socks
Ставим необходимые пакеты:
opkg update
opkg install ip-full kmod-tun
Создаём таблицу маршрутизации (в неё будем пихать весь трафик, который хотим завернуть в прокси):
echo -e '\n300 tun2socks\n' >> /etc/iproute2/rt_tables
Формируем файл для init.d, чтобы tun2socks работал как сервис. У меня он вышел примерно такой (/etc/init.d/tun2socks):
#!/bin/sh /etc/rc.common
START=90
USE_PROCD=1
#PROCD_DEBUG=1
#имя туннельного интерфейса
tun_name='t2s0'
#адрес туннельного интерфейса
tun_ip='10.254.1.1'
#самое главное - адрес прокси
proxy='socks5://192.168.88.201:123456'
loglevel='warn'
#запускаем tun2socks
tun2socks(){
procd_open_instance
procd_set_param command /usr/bin/tun2socks -device tun://$tun_name -proxy $proxy -loglevel $loglevel
procd_close_instance
}
#правила iptables при старте
rulesup(){
iptables -t mangle -N tun2socks
#отправляем всё, что с бриджа в прокси
iptables -t mangle -I PREROUTING -i br-lan -j MARK --set-mark 3
#отправляем https трафик в прокси
iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 3
#запускаем туннельный интерфейс
ip tuntap add dev $tun_name mode tun
ip addr add ${tun_ip}/24 dev $tun_name
ip link set dev $tun_name up
#формируем таблицу маршрутизации
ip route add default dev $tun_name table 300
ip rule add fwmark 3 lookup 300
#iptables -A forwarding_lan_rule -o $tun_name -j ACCEPT
}
#подчищаем правила, когда стопим сервис
rulesdown(){
ip rule del fwmark 3 lookup 300
iptables -t mangle -D PREROUTING -i br-lan -j MARK --set-mark 3
iptables -t mangle -D OUTPUT -p tcp --dport 443 -j MARK --set-mark 3
ip tuntap del dev $tun_name mode tun
}
start_service() {
rulesup
tun2socks
}
service_stopped() {
rulesdown
}
Теперь можно включить и запустить сервис, и наслаждаться вайфаем через прокси (настройку собственно вайфая на OpenWrt тоже пожалуй оставим за кадром):
/etc/init.d/tun2socks enable
/etc/init.d/tun2socks start
Из нюансов - для Tp-Link мне пришлось брать не самый свежий релиз tun2socks, свежий выпадал в ошибку. Зато если на роутере есть кнопка или переключатель - можно повесить на неё старт-стоп сервиса:) Для Tp-Link TL-MR3020 это может выглядеть, как скрипт /etc/hotplug.d/button/00-button :
#!/bin/sh
if [ $ACTION == "released" ] ; then
if [ $BUTTON == "BTN_1" ] ; then
/etc/init.d/tun2socks stop
#logger "Slider 3G"
elif [ $BUTTON == "BTN_0" ] ; then
/etc/init.d/tun2socks start
#logger "Slider WISP"
fi
elif [ $BUTTON == "BTN_0" ] || [ $BUTTON == "BTN_1" ] ; then
if grep -qe "sw1.*in hi" /sys/kernel/debug/gpio ; then
if grep -qe "sw2.*in hi" /sys/kernel/debug/gpio ; then
#logger "Slider AP"
fi
fi
fi
В принципе всё, за некоторым исключением, про которое поговорим отдельно.
Утечка DNS
Внимательный читатель заметит, что я зачем-то кидаю https-трафик от роутера в прокси тоже. Делается это по причине, чтоб не "подтекал" DNS, что обнаруживается всякими прокси-детекторами. Конечно, DNS работает по UDP:53.. А вот DoH (DNS over HTTPS) нет.
Поэтому не забудем включить поддержку DoH на нашем роутере, поставив соответствующий пакет:
opkg update
opkg install https-dns-proxy
В стандартных настройках используются DNS-серверы от Google и Cloudflare. Вы можете настроить на любой другой сервер, и, выбрав определённые IP серверов, маркировать трафик до них для отправки в прокси. Я же для простоты промаркировал весь https :)
Не хочу прошивать Микротик, он классный
С появлением RouterOS 7 и доработки функционала контейнеров в ней, можно и не сносить прекрасный RouterOS, а запихать tun2socks в контейнер. Оно работает, но с оговорками (поскольку создаётся tap-интерфейс, в процессе дебага может понадобится поребутать роутер). Контейнер можно приготовить на основе образа от разработчика - https://hub.docker.com/r/xjasonlyu/tun2socks , изменив в нём работу с таблицами маршрутизации и iptables по вкусу, и потом силами микротика и его nat (или route rule) отправлять нужный трафик в контейнер. Подробностей не будет, поскольку вариант хоть и занятный, но не каждый MikroTik умеет в контейнеры, да и задачу реализовывал ещё до поддержки контейнеров в ROS7, поэтому дальше так сказать MVP :) реализовывать не стал.
Но если кому захочется - документация о работе с контейнерами - https://help.mikrotik.com/docs/display/ROS/Container, в общем случае понадобится одна переменная среды - PROXY. Из коробки работать не будет, нужно адаптировать образ, ну и конечно понадобится флешка под хранилище - куда без неё:)
Статья вышла немного сумбурной, но надеюсь может быть полезной кому-то, кроме меня. Удачного проксирования!
at5Fd8NVdfpf
Так себе идея создавать правила фаервола таким образом. Лучше поставить пакет nwan3 и gui к нему (luci-app-mwan3) и настроить его. Будет намного удобнее писать правила какой трафик куда слать (это если соксов несколько, и устройств тоже) и даже балансировать нагрузку (пускать один девайс сразу в несколько соксов). Да и ваш скрипт сломается если mwan3 уже установлен.
avelor Автор
интересный вариант, спасибо (узнал про nwan3, буду иметь ввиду). Правда, кажется применим для более мощных роутеров, которые помимо раздачи проксированного wi-fi делают что-то ещё. моя концепция - тяп-ляп сделали коробочку на чистой системе, которую воткнули в локалку и она раздаёт проксированный wi-fi, лазить и настраивать правила на регулярной основе не нужно. Ну и следует учесть, что один инстанс tun2socks может кушать под 60+мб оперативки, поэтому не только лишь каждый роутер вытянет несколько соксов
at5Fd8NVdfpf
tun2socks отъедает намного больше ресурсов (особенно ram) чем mwan3, который запросто работает на довольно слабых девайсах.
Я делаю так: на каждый сокс запускается по экземпляру tun2socks с разными tun*, на них назначется по интерфейсу (статический ip/30) и на каждом default gateway с метрикой >1. Они прописываются в mwan3, в нём дефолтное правило: всё что пришло с wifi пускать в любой рабочий сокс. Для отдельных девайсов своё правило если нужно выбрать один конкретный сокс. Mwan3 следит за живостью соксов (посылая периодически http в инет (нужно установить пакет httping)), и не пытается слать пакеты если сокс дохлый.
avelor Автор
красивое:) для полного счастья не хватает конфига соксов через вебморду + разный вывод dns для разных девайсов (если например соксы разных стран и хочется избежать dns leak). как вариант, отдавать разные локальные адреса в качестве резолвера, а трафик с них пихать в соответствующий туннель..
а не подскажете, для общего развития - какое железо используете и сколько инстансов tun2socks?
at5Fd8NVdfpf
Обычные "роутеры" из магазина - 0 (не хватает ram для tun2socks). На перешитом микротике - 1. OpenWRT в виртуалке (kvm) на самом дешёвом хостинге - 4 но это далеко не предел ( и на нём же ещё v2ray/websocket/nginx).
Насчёт dns - есть грязный хак: пропускать через тот же сокс (не все соксы умеют udp, и каждый раз надо искать подходящий dns (если брать провайдерский) который будет доступен с того сокса). Это работает, но заемучашся при каждой смене сокса подбирать dns. Проще и удобнее прописать взятый с opennicproject для 99% целей это годный вариант.
avelor Автор
спасибо. я когда-то для проекта думал брать роутербокс (платформу с али "под пфсенс"), но проект в итоге в массы не пошёл. удивлён, что не один я перешивал микротики под openwrt :D думал я один такой дурачок :D
по dns мне вот очень зашёл вариант с DoH. не надо подбирать подходящий днс, не надо искать сокс с udp, всё идёт через tcp. Кажется чуть более изящное решение