Pull to refresh

Настройка клиента Outline VPN на OpenWRT (все версии) на базе пакета shadowsocks-libev и tun2socks

Level of difficultyEasy
Reading time10 min
Views37K

Outline VPN это проект компании Jigsaw, дочерней компании Google. Outline использует протокол Shadowsocks для связи между клиентом и сервером. Трафик шифруется с помощью шифра IETF ChaCha20 и аутентифицируется с помощью IETF Poly1305.

В этой инструкции мы рассмотрим настройку клиента на базе пакета shadowsocks-libev и опционально, поднятие интерфейса с помощью kmod-tun и xjasonlyu/tun2socks. Способ подходит для роутеров с объёмом ОЗУ от 64 Мб и ПЗУ от 8 Мб.

UPD. 14.09.2023 Решение для ошибки ниже найдено, описал в п.4

daemon.err /usr/bin/ss-redir[7401]: accept: No file descriptors available

Нам потребуется доступ к SSH и Веб-интерфейсу LuCI

  1. Установка пакетов на роутере

  2. Получение ключа доступа в Outline Manager

  3. Настройка shadowsocks-libev на роутере

  4. Фикс для OpenWRT 22.03 и выше

  5. Настройка интерфейса с помощью tun2socks

1. Установка пакетов на роутере

Развёртывание Outline VPN на VDS или собственном сервере довольно простое, инструкция есть на официальном сайте проекта:
Outline VPN - Access to the free and open internet (getoutline.org)
и на Хабре:
Outline: Делаем свой личный VPN от Google за 5$ в месяц (и за 1€ для продвинутых) / Хабр (habr.com)

Проблема в том, что официальной инструкции для использования Outline на OpenWRT нету, но так как Outline VPN основан на Shadowsocks мы будет использовать пакеты:

shadowsocks-libev-ss-local
shadowsocks-libev-ss-redir
shadowsocks-libev-ss-rules
shadowsocks-libev-ss-tunnel

И для настройки в интерфейсе LUCI

luci-app-shadowsocks-libev

Устанавливаем пакеты:

opkg update
opkg install shadowsocks-libev-ss-local shadowsocks-libev-ss-redir shadowsocks-libev-ss-rules shadowsocks-libev-ss-tunnel
opkg install luci-app-shadowsocks-libev

Далее нам потребуется ключ доступа к Outline

2. Получение ключа доступа в Outline Manager

Запускаем Outline Manager

Добавляем ключ либо используем существующий

Копируем ключ доступа, в нём содержатся IP адрес сервера и порт подключения и пароль в зашифрованном виде

ss://[пароль-шифрованный]@IP:Port/?outline=1

3. Настройка shadowsocks-libev на роутере

Далее на примере LUCI (OpenWRT 19.07)

Переходим в раздел Службы - Shadowsocks-libev

Переходим во вкладку Remote Servers (Удаленные серверы)

Сюда вставляем IP адрес, порт сервера

Для получения пароля нужен декодер формата Base64, например Base64 Decode and Encode - Online

Красным подчеркнут пароль, слева от него метод шифрования
Красным подчеркнут пароль, слева от него метод шифрования

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

Применяем изменения.

В версиях OpenWRT 21.02 и выше в разделе Remote Servers есть опция Ссылка на импорт, туда просто вставляем наш код доступа из Outline и получаем готовую запись в конфиге.

Далее возвращаемся на вкладку Local Instances (Локальные экземпляры)

ss_redir отвечает за перенаправление трафика в прокси согласно правилам ss-rules

ss_local поднимает socks5 прокси на выбранном порту

ss_server поднимает shadowsocks сервер

ss_tunnel поднимает туннель до заданного узла (например можно настроить туннель до DNS Google по адресу 8.8.8.8:53 и перенаправлять запросы DNS на локальный адрес, например 127.0.0.1#8053, а запросы через shadowsocks будут уходить к Google, будет аналог DNS-over-HTTPS)

Для переадресации трафика в Outline нужен шаблон ss_redir

SS-redir отвечает за перенаправление трафика в прокси согласно правилам ss-rules

Для начала перейдем в ss_redir.hj (или ss_redir.hi или можно создать новый, это не принципиально)

Проверяем чтобы в графе Remote Server был сервер с данными Outline, убираем галку напротив Отключить

Далее переходим на вкладку Redir Rules (Правила Redir)

Если вы хотите перенаправлять весь трафик в Outline, то выбираете чтобы ss-redir for TCP и UDP соответствовал выбранному ранее пункту (hj, hi или тому который вы сделали), если вам нужен обход блокировок только для интернет-сайтов, а UDP трафик (например онлайн-игры) должен идти напрямую, то выбираете только ss-redir for TCP, а UDP оставляете пустым.

По умолчанию весь трафик (TCP и UDP в зависимости от того что вы выбрали в предыдущем пункте) будет идти через прокси, поэтому оставляем вариант forward (направлять всё по умолчанию), убеждаемся что нет галки напротив Отключить и переходим на вкладку Source Settings (Настройки источника)

Здесь можно настроить исключения для IP адресов в вашей локальной сети,

Src ip/net bypass позволяет добавленному в этот список IP ходить в интернет напрямую, игнорируя настройки shadowsocks-libev (список исключений)

Src ip/net forward - IP добавленные в этот список будут ходить в интернет согласно настройкам shadowsocks-libev, этот список важен, если вы выберите чтобы через прокси ходили только выбранные устройства (src default в таком случае будет bypass)

Src ip/net checkdst - IP добавленные в этот список будут ходить через прокси только на узлы, которые указаны в Destination Settings (соответственно не указанные адреса, будут использовать политику по умолчанию)

Src default - политика по умолчанию для адресов источника (локальные IP адреса, вида 192.168.1.1 и пр.)

forward - направлять трафик от любых адресов через прокси

bypass - направлять трафик от любых источников напрямую

checkdst - сверяться со списком адресов назначения в Destination Settings и только в этом случае направлять трафик через прокси.

Здесь оставляем настройки по умолчанию, далее переходим в Destination Settings (Настройки назначения)

Dst ip/net bypass - Для указанных адресов назначения трафик будет идти через напрямую, игнорируя прокси (например IP адреса российского сегмента и т.д., каждая подсеть вида 24.88.32.0/24 указывается отдельной строкой) В этот пункт стоит прописать IP вашего сервера Outline для избежания конфликтов

Dst ip/net forward - Для указанных адресов назначения трафик будет идти через прокси (например заблокированные адреса и т.д., каждая подсеть вида 24.88.32.0/24 указывается отдельной строкой)

Dst ip/net bypass file - здесь можно указать путь к файлу списку адресов, доступ к которым будет осуществляться напрямую, игнорируя прокси (его нужно будет создать или скачать на роутер, например в директорию /etc/shadowsocks-libev или /root)

Dst ip/net forward file - здесь можно указать путь к файлу списку адресов, доступ к которым будет осуществляться через прокси (его нужно будет создать или скачать на роутер, например в директорию /etc/shadowsocks-libev или /root)

Для примера настроим весь трафик через прокси:

Задаём для Dst default - forward (по умолчанию весь трафик будет идти через прокси, о других вариантах будет в конце статьи)

Нажимаем Применить и проверяем работу:

wget -qO- http://ipecho.net/plain | xargs echo

Команда выдаст IP адрес сервера Outline.

Так будет выглядеть конфиг /etc/config/shadowsocks-libev (если вы сделали действия описанные выше, ваш конфиг выглядит аналогично)

config server 'sss0'
        option server '$OUTLINE_IP'
        option server_port '$PORT'
        option method 'chacha20-ietf-poly1305'
        option password '$DECRYPTED_PASSWORD'
		
config ss_redir 'hj' #Setting to redirect all traffic by Redir_rules
        option server 'sss0'
        option local_address '0.0.0.0'
        option local_port '1100'
        option mode 'tcp_and_udp'
        option timeout '60'
        option fast_open '1'
        option reuse_port '1'

config ss_rules 'ss_rules' #Rules of traffic redirection
        option src_default 'checkdst'
        option dst_forward_recentrst '0'
        option redir_tcp 'hj'
        option redir_udp 'hj'
        option local_default 'forward'
        option dst_default 'forward' #Forward all traffic

При желании можно использовать Outline только для списка адресов (например списки заблокированных адресов от antifilter.download)

Для этого скачаем файл ipsum.lst (список IP заблокированных РКН с суммаризацией по подсетям, могут быть совпадения с IP адресами не заблокированными)

 wget https://antifilter.download/list/ipsum.lst -O /etc/shadowsocks-libev/ipsum.lst

В этом случае в общих настройках меняем forward на check-dst

В разделе Destination Settings (Настройки назначения) меняем политику по умолчанию Dst default на bypass а в пункт Dst ip/net forward file добавляем путь к файлу /etc/shadowsocks-libev/ipsum.lst которые должны работать через прокси.

В новых версиях OpenWRT вместо указания пути к файлу, браузер предложит загрузить файл с ПК (для этого нужно скачать список ipsum.lst с сайта antifilter.download и загрузить его на роутер)

Нажимаем Применить и проверяем работоспособность.

4. Исправляем ошибку ss-redir на OpenWRT 22.03 и выше

Проблема возникает из-за неправильных настроек по умолчанию у Shadowsocks-libev конфликтующих с обновлённым firewall4 основанным на nftables и вызывающая утечку памяти и зависание роутера.

Для её исправления необходимо перейти в раздел Службы - Shadowsocks-libev - Redir Rules - Основные Настройки (General Settings)

Для новой версии обязательно должны быть заполнены пункты:

Extra tcp expression - здесь указывается диапазон TCP портов направляемых через прокси (даже если это все порты, они должны быть указаны), заполняем:

tcp dport { 80-17214, 17216-65535 } - в моём случае порт Outline - 17215, его я исключил из диапазона, иначе получаю ошибку ss-redir. Обязательно напишите диапазоны с учётом вашего порта Outline или оставьте строку - tcp dport { 80, 443 } чтобы проксировались только порты 80 и 443.

Extra udp expression - здесь указывается диапазон UDP портов направляемых через прокси (даже если это все порты, они должны быть указаны), заполняем

udp dport { 53-65535 } здесь я указываю все порты от 53 (DNS) до последнего, добавлять порт Outline в исключения не нужно, т.к. shadowsocks работает через TCP.

Сохраните и Примените изменения.

Этого достаточно чтобы shadowsocks-libev работал на OpenWRT 22.03 и выше.

На этом основная настройка прокси закончена, следующий раздел опциональный и позволит получить более простую маршрутизацию как в случае с OpenVPN и Wireguard.

5. Настройка интерфейса с помощью tun2socks

Этот раздел не обязательный для работы прокси и несколько сложнее чем предыдущие.

Если вам нужен tun2socks и Outline клиент, но без shadowsocks-libev, можете воспользоваться вариантом с установкой по скрипту

раздел далее предусматривает использование shadowsocks-libev ss_local (socks5 прокси)

Вам понадобится около 9Мб свободной памяти роутера.

Для настройки маршрутов с помощью iptables (nftables) будет удобнее использовать shadowsocks в качестве интерфейса tun, для этого необходимо определить архитектуру вашего устройства и скачать пакет с github:

Скачиваем файл:

ARCH=$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}')
wget https://github.com/1andrevich/outline-install-wrt/releases/download/v2.5.1/tun2socks-linux-$ARCH -O /tmp/tun2socks

Проверяем работу программы:

chmod +x /tmp/tun2socks
/tmp/tun2socks --help

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

Далее для настройки маршрутов нужно перейти в Local Instances (Локальные экземпляры)

Выбираем внизу ss-local, вводим название, в моём случае tunnel и жмём добавить.

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

Нажимаем Cохранить.

Далее отключаем ss-redir:

Нажимаем Применить.

Согласно документации tun2socks рекомендуется присвоить интерфейсу ip адрес (на практике маршрутизация работает и перенаправлением в dev tun2)

Для этого в /etc/config/network добавим следующее содержание:

config interface 'tunnel'
        option device 'tun2'
        option proto 'static'
        option ipaddr '172.16.10.1'
        option netmask '255.255.255.252'

Диапазон 172.16.10.0/30 выбран случайно, может быть любой диапазон частных адресов

Так же создаём зону и правило в /etc/config/firewall

config zone
        option name 'proxy'
        option forward 'REJECT'
        option output 'ACCEPT'
        option input 'REJECT'
        option masq '1'
        option mtu_fix '1'
        option device 'tun2'
        option family 'ipv4'

config forwarding
        option name 'lan-proxy'
        option dest 'proxy'
        option src 'lan'
        option family 'ipv4'

Перезагружаем сеть

/etc/init.d/network restart

Далее проверяем работоспособность туннеля tun2socks:

/tmp/tun2socks -device tun2 -proxy 127.0.0.1:1080 -loglevel debug

Запустится туннель с логированием:

Где tun2 наименование туннеля

proxy - адрес socks туннеля указывающий на shadowsocks на порту 1080 (если вы меняли порт в ss-local, укажите свой).

Проверяем доступность интерфейса:

ping -n 172.16.10.2

Для проверки работоспособности можно временно добавить маршрут к сайту ipecho.net (не закрывая tun2socks, в параллельной вкладке).

ip route add 34.160.111.0/24 dev tun2

Обращаемся к сайту и смотрим логи:

wget -qO- http://ipecho.net/plain | xargs echo

Если всё работает, команда вернёт IP вашего прокси.

Можно закрывать tun2socks и удалить маршрут:

ip route del 34.160.111.0/24

Теперь перенесём файл в постоянную память устройства (Это потребует свободного места около 9Мб на роутере)

mv /tmp/tun2socks /usr/bin/tun2socks

Во избежание последующих проблем маршрутизации добавим статический маршрут до сервера Outline в LuCI

Переходим в Сеть - Статические маршруты

И добавляем маршрут до вашего сервера

Не забываем проверить доступность сервера после добавления маршрута

ping $Ваш_Сервер_Outline_IP

Теперь настроим службу, чтобы интерфейс начинал работать при загрузке роутера.

Здесь хочу выразить огромную благодарность пользователю itdog за информацию по настройке службы tun2socks (и за обзор темы впринципе).

В файл /etc/init.d/tun2socks вносим следующее содержание, например при помощи vi:

vi /etc/init.d/tun2socks
#!/bin/sh /etc/rc.common
USE_PROCD=1

# starts after network starts
START=99
# stops before networking stops
STOP=89

PROG=/usr/bin/tun2socks
IF="tun2"
HOST="127.0.0.1"
PORT="1080"


start_service() {
  procd_open_instance
  procd_set_param user root
  procd_set_param command "$PROG" -device "$IF" -proxy "$HOST":"$PORT"
  procd_set_param stdout 1
  procd_set_param stderr 1
  procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
  procd_close_instance
#    ip route add "$OUTLINEIP" via "$DEFGW" #Adds route to OUTLINE Server
#	echo 'route to Outline Server added'
    #ip route save default > /tmp/defroute.save  #Saves existing default route
    echo "tun2socks is working!"
}

service_started() {
    # This function checks if the default gateway is Outline, if no changes it
     echo 'Replacing default gateway for Outline...'
     sleep 2s
     #if ip link show $IF | grep -q "UP" ; then
         #ip route del default #Deletes existing default route
         #ip route add default via 172.16.10.2 dev $IF #Creates default route through the proxy
     #fi
}
start() {
    start_service
    service_started
}
boot() {
    # This gets run at boot-time.
    start
}

shutdown() {
    # This gets run at shutdown/reboot.
    stop
}

stop_service() {
    service_stop "$PROG"
    #ip route restore default < /tmp/defroute.save #Restores saved default route
#    ip route del "$OUTLINEIP" via "$DEFGW" #Removes route to OUTLINE Server
    echo "tun2socks has stopped!"
}

reload_service() {
    stop
    sleep 3s
    echo "tun2socks restarted!"
    start
}

Где IF - интерфейс, в данном примере tun2 (вместо tun0) чтобы избежать конфликтов с существующими туннелями.

PORT - Порт настроенный в ss-local

Если требуется перенаправлять весь трафик в shadowsocks, уберите # перед строками 25, 33, 34, 35, 36, и 54.

Для правильной работы скрипта (сохранение и восстановление маршрута по умолчанию) потребуется установить пакет ip-full

opkg install ip-full

Делаем файл исполняемым:

chmod +x /etc/init.d/tun2socks

Делаем автозапуск:

ln -s /etc/init.d/tun2socks /etc/rc.d/S99tun2socks

Запускаем:

/etc/init.d/tun2socks start

Проверяем, что интерфейс заработал:

ip a | grep 'tun2'

Если заработал, выдаст подобный результат:

tun2: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    inet 172.16.10.1/30 brd 172.16.10.3 scope global tun2

Если нет, ответ будет пустым.

Далее необходимо настроить маршруты к которым роутер будет обращаться через прокси.

Можно настроить маршрут по умолчанию для всего трафика (убрать # перед строками), либо настроить точечный обход блокировок (в конце статьи)

для настройки маршрута по умолчанию необходимо сначала создать маршрут до сервера Outline через ваш шлюз по умолчанию

Если настроен маршрут по умолчанию, проверяем работоспособность:

wget -qO- http://ipecho.net/plain | xargs echo

Команда вернёт IP адрес сервера Outline.

Для точечного обхода блокировок и настройки таких маршрутов:

Точечный обход блокировок на роутере OpenWrt c помощью BGP / Хабр (habr.com) С помощью BGP (bird2).

Точечный обход блокировок PKH на роутере с OpenWrt с помощью WireGuard и DNSCrypt / Хабр (habr.com) (путём скачивания списков и настройкой маршрутов в iptables, nftables).

P.S. Для замены уже не самого свежего shadowsocks-libev (и переставшего обновляться), если позволяет оборудование, можно использовать требующие больше 16Мб памяти и 128 Мб ОЗУ, но гораздо более функциональные Passwall и Homeproxy.

Tags:
Hubs:
Total votes 9: ↑9 and ↓0+9
Comments15

Articles