Если раздать Wi-Fi через VPN задача простая и решаемая, вот даже статья "WiFi-портал в Россию" недавно вышла, то с прокси дело обстоит чуть сложнее, нужно немного костылей и напильников, а так же замечательное ПО под названием tun2socks.

Но, в отличие от VPN, прокси дешевле, и если нужно тестировать мобильные устройства с разных геолокаций - то прокси будет неплохим выходом. Конечно, существуют готовые решения, такие как Double SSH Tunnel Manager и Raspberry с прошивкой "Linux Mars", но мы, как водится, пойдём своим путём, да и готовые решения выше предназначены для другого.

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

Немного за технологию

Для работы с прокси будем использовать такую славную вещь, как tun2socks. На хабре уже была статья про это ПО (настоятельно рекомендую к ознакомлению), где рассказывается как настроить шлюз через прокси на Linux или Windows машине. Я же расскажу чуть подробнее, как настроить такой шлюз на роутере.

Итак, нам понадобится:

  1. Роутер на OpenWrt или роутер, который можно прошить в OpenWrt (я тестировал на незабвенном Tp-Link TL-MR3020 и на не менее незабвенном MikroTik hAP ac²). Помимо работы OpenWrt от роутера понадобится 128 и более мегабайт оперативной памяти и столько же места на внутреннем накопителе - или же возможность установить внешний.

  2. Под внешний накопитель вполне подойдёт обычная usb-флешка или sd-карточка минимального размера. Я экспериментировал с древней флешкой на 4гб. Для ценителей - usb-модем с sd-карточкой:)

  3. Прокси-провайдер (предпочтительнее socks5 c поддержкой udp)

  4. Немного свободного времени

Прошивка роутера

Берём нашу модель и идём на сайт 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²!) понадобится перенос системы на внешнюю флешку. Инструкцией в сети полно, поэтому опять же кратенько:

  1. форматируем флешку - можно сделать сразу два раздела, под систему и swap. Под винду я использовал Minitool Partition Wizard. Выбор файловой системы - по вкусу, я вот взял ext4. По размерам - хватит минимального, я подкинул на swap 256мб, под систему - 1Гб

  2. ставим в OpenWrt нужные пакеты (роутер надо будет выпустить в инет):

opkg update
opkg install block-mount kmod-usb-core kmod-usb2 kmod-usb-ohci kmod-usb-storage kmod-fs-ext4
  1. Ротуер в ребут, через 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'
  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
  1. ребутаемся, убеждаемся через 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
Tp-Link TL-MR3020 как бы проксирует Wi-Fi
Tp-Link TL-MR3020 как бы проксирует Wi-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. Из коробки работать не будет, нужно адаптировать образ, ну и конечно понадобится флешка под хранилище - куда без неё:)

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

Комментарии (8)


  1. at5Fd8NVdfpf
    07.11.2022 19:51

    Так себе идея создавать правила фаервола таким образом. Лучше поставить пакет nwan3 и gui к нему (luci-app-mwan3) и настроить его. Будет намного удобнее писать правила какой трафик куда слать (это если соксов несколько, и устройств тоже) и даже балансировать нагрузку (пускать один девайс сразу в несколько соксов). Да и ваш скрипт сломается если mwan3 уже установлен.


    1. avelor Автор
      07.11.2022 20:03

      интересный вариант, спасибо (узнал про nwan3, буду иметь ввиду). Правда, кажется применим для более мощных роутеров, которые помимо раздачи проксированного wi-fi делают что-то ещё. моя концепция - тяп-ляп сделали коробочку на чистой системе, которую воткнули в локалку и она раздаёт проксированный wi-fi, лазить и настраивать правила на регулярной основе не нужно. Ну и следует учесть, что один инстанс tun2socks может кушать под 60+мб оперативки, поэтому не только лишь каждый роутер вытянет несколько соксов


      1. at5Fd8NVdfpf
        07.11.2022 21:05
        +1

        tun2socks отъедает намного больше ресурсов (особенно ram) чем mwan3, который запросто работает на довольно слабых девайсах.

        Я делаю так: на каждый сокс запускается по экземпляру tun2socks с разными tun*, на них назначется по интерфейсу (статический ip/30) и на каждом default gateway с метрикой >1. Они прописываются в mwan3, в нём дефолтное правило: всё что пришло с wifi пускать в любой рабочий сокс. Для отдельных девайсов своё правило если нужно выбрать один конкретный сокс. Mwan3 следит за живостью соксов (посылая периодически http в инет (нужно установить пакет httping)), и не пытается слать пакеты если сокс дохлый.


        1. avelor Автор
          07.11.2022 21:13

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

          а не подскажете, для общего развития - какое железо используете и сколько инстансов tun2socks?


          1. at5Fd8NVdfpf
            07.11.2022 22:42

            Обычные "роутеры" из магазина - 0 (не хватает ram для tun2socks). На перешитом микротике - 1. OpenWRT в виртуалке (kvm) на самом дешёвом хостинге - 4 но это далеко не предел ( и на нём же ещё v2ray/websocket/nginx).

            Насчёт dns - есть грязный хак: пропускать через тот же сокс (не все соксы умеют udp, и каждый раз надо искать подходящий dns (если брать провайдерский) который будет доступен с того сокса). Это работает, но заемучашся при каждой смене сокса подбирать dns. Проще и удобнее прописать взятый с opennicproject для 99% целей это годный вариант.


            1. avelor Автор
              07.11.2022 23:04

              спасибо. я когда-то для проекта думал брать роутербокс (платформу с али "под пфсенс"), но проект в итоге в массы не пошёл. удивлён, что не один я перешивал микротики под openwrt :D думал я один такой дурачок :D

              по dns мне вот очень зашёл вариант с DoH. не надо подбирать подходящий днс, не надо искать сокс с udp, всё идёт через tcp. Кажется чуть более изящное решение


  1. INSTE
    07.11.2022 23:40
    +1

    В KeeneticOS начиная с 3.9 есть поддержка socks/http proxy как полноценных интерфейсов.


    1. avelor Автор
      07.11.2022 23:55

      вот тут изобретаешь всякое (делал это всё с год назад), а тут кинетик вжжух - и реализовал:D и даже с DoH через прокси.. спасибо!