В данном гайде будем устанавливать пакет sing-box на OpenWRT на примере стабильной 22.03.5 и 23.05.0. Рекомендуется роутер минимум с 128 МБ RAM (256 предпочтительно) и памятью более 16 Мб, так же будет описан способ установки sing-box в оперативную память (подходит для устройств с малым количеством ПЗУ <16 Мб)
Sing-Box — это бесплатная прокси-платформа с открытым исходным кодом, которая позволяет пользователям обходить интернет-цензуру и получать доступ к заблокированным веб-сайтам. Это альтернатива v2ray-core и xray-core. Его можно использовать с различными клиентами таких платформах, как Windows, macOS, Linux, Android и iOS.
Помимо поддержки протоколов Shadowsocks (в т.ч. 2022), Trojan, Vless, Vmess и Socks, он также поддерживает ShadowTLS, Hysteria и NaiveProxy.
Руководство будет включать:
-
Установку из репозитория
-
Настройку sing-box для shadowsocks, vless, vmess, trojan и обход блокировок с помощью SagerNet GeoIP, Geosite
-
Настройку обхода блокировок с помощью GeoIP, Geosite от L11R
-
Установку sing-box в оперативную память и настройку автозапуска
1. Установка sing-box
UPD 13.10.2023 Репозиторий lrdrdn/my-opkg-repo переориентировался на версию 23.05.0, претерпел изменения, потеряв большую часть пакетов необходимых для установки на 22.03.5, включая sing-box, поэтому заменил репозиторий.
Для версии OpenWRT 22.03.5 необходимо скачать и установить актуальную версию sing-box:
cd /tmp wget https://downloads.openwrt.org/releases/23.05.0/packages/$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}')/packages/sing-box_1.8.4-1_$(grep "OPENWRT_ARCH" /etc/os-release | awk -F '"' '{print $2}').ipk opkg install sing-box_*.ipk rm sing-box_*.ipk
Начиная с версии 23.05.0 sing-box есть в стандартном репозитории OpenWRT.
Обновляем список пакетов:
opkg update
Далее устанавливаем необходимые для работы sing-box модули ядра и пакет совместимости с iptables:
opkg install kmod-inet-diag kmod-netlink-diag kmod-tun iptables-nft
Ждём завершения установки, пакеты заняли около 1Мб памяти.
Далее переходим к установке sing-box
opkg install sing-box
Пакет занимает около 10Мб, поэтому установить его на устройства с 16 Мб ПЗУ не удастся без дополнительных манипуляций (об этом в п.3 этой статьи).
Если пакет успешно установлен, переходим к настройке соединения, если нет — переходим к п.3.
2. Настройка sing-box для shadowsocks, reality, vmess, trojan и обход блокировок с помощью SagerNet GeoIP, Geosite
UPD 12.11.2023 Далее переходим к файлу конфигурации, по умолчанию это /etc/sing-box/config.json, но при установке доступен /etc/sing-box/config.json.example В версии 1.6.0 доступен /etc/sing-box/config.json по умолчанию, файла /etc/sing-box/config.json.example при установке больше нету
Удаляем дефолтный /etc/sing-box/config.json:
> /etc/sing-box/config.json
Я приведу пример файла config.json для настройки как Outline VPN (выпуск ключей и их расшифровку на пароль и тип шифрования из формата base64 я рассматривал здесь) так и XTLS-Reality, VMess TLS и Trojan Websocket. В конфигурации используется selector выбирающий только рабочие прокси с помощью urltest. На сайте проекта sing-box, Github юзера malikshi и vpnrouter.homes доступны многочисленные примеры конфигураций для различных протоколов.
Пример config.json:
{ "log": { "disabled": false, "level": "warn", "output": "/tmp/sing-box.log", "timestamp": true }, "dns": { "servers": [ { "tag": "google", "address": "tls://8.8.8.8" }, { "tag": "block", "address": "rcode://success" } ], "final": "google", "strategy": "prefer_ipv4", "disable_cache": false, "disable_expire": false }, "inbounds": [ { "type": "mixed", "tag": "mixed-in", "listen": "127.0.0.1", "listen_port": 1080, "tcp_fast_open": false, "sniff": true, "sniff_override_destination": true, "set_system_proxy": false }, { "type": "tun", "tag": "tun-in", "interface_name": "singtun0", "inet4_address": "172.19.16.1/30", "stack": "gvisor", "mtu": 9000, "auto_route": true, "strict_route": false, "endpoint_independent_nat": false, "sniff": true, "sniff_override_destination": true } ], "outbounds": [ { "type": "selector", "tag": "Proxy-out", "outbounds": [ "URL-Test", "direct", "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "default": "URL-Test" }, { "type": "urltest", "tag": "URL-Test", "outbounds": [ "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "url": "http://www.gstatic.com/generate_204", "interval": "1m", "tolerance": 50 }, { "type": "shadowsocks", "tag": "shadowsocks-out", "server": "IP", "server_port": 15000, "method": "chacha20-ietf-poly1305", "password": "password" }, { "type": "vless", "tag": "reality-out", "server": "IP", "server_port": 8442, "uuid": "UUID", "flow": "xtls-rprx-vision", "network": "tcp", "tls": { "enabled": true, "insecure": false, "server_name": "SERVERNAME", "utls": { "enabled": true, "fingerprint": "chrome" }, "reality": { "enabled": true, "public_key": "AP24JYROAB8odK5glVW_KLnsWl3UZ-voaGq_9ihQgTL" } } }, { "type": "trojan", "tag": "trojan-WebSocket-out", "server": "IP", "server_port": 8443, "password": "PASSWORD", "transport": { "type": "ws", "path": "/", "early_data_header_name": "Sec-WebSocket-Protocol" }, "tls": { "enabled": true, "disable_sni": false, "server_name": "d43f429a97e4ea6d.gstatic.com" }, "multiplex": { "enabled": true, "max_connections": 4, "min_streams": 4, "max_streams": 0 } }, { "type": "vmess", "tag": "vmess-tls-out", "server": "IP", "server_port": 8444, "uuid": "UUID", "security": "auto", "alter_id": 0, "global_padding": false, "authenticated_length": true, "tls": { "enabled": true, "disable_sni": false, "server_name": "google.com", "insecure": false, "alpn": [ "http/1.1" ] }, "multiplex": { "enabled": true, "protocol": "smux", "max_connections": 5, "min_streams": 4, "max_streams": 0 }, "connect_timeout": "5s" }, { "type": "direct", "tag": "direct" }, { "type": "block", "tag": "block" }, { "type": "dns", "tag": "dns-out" } ], "route": { "geoip": { "path": "/tmp/geoip.db", "download_url": "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db", "download_detour": "Proxy-out" }, "geosite": { "path": "/tmp/geosite.db", "download_url": "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db", "download_detour": "Proxy-out" }, "rules": [ { "protocol": "dns", "outbound": "dns-out" }, { "protocol": [ "quic" ], "outbound": "block" }, { "geosite": [ "private", "youtube", "google", "yandex" ], "geoip": [ "private", "ru" ], "ip_cidr": [ "94.100.180.201/32", "94.100.180.202/32" ], "domain_keyword": [ "mail.ru", "vk.com" ], "domain_suffix": [ ".ru" ], "outbound": "direct" } ], "final": "Proxy-out", "auto_detect_interface": true } }
Конфигурация пишет в лог /tmp/sing-box.log предупреждения и ошибки, поднимает socks5 proxy на порту 1080, поднимает туннель singtun0 с помощью kmod-tun и gvisor.
Раздел outbounds содержит конфигурации для XTLS-Reality, VMess TLS и Trojan Websocket:
{ "type": "shadowsocks", "tag": "shadowsocks-out", .... }, { "type": "vless", "tag": "reality-out", .... }, { "type": "trojan", "tag": "trojan-WebSocket-out", .... }, { "type": "vmess", "tag": "vmess-tls-out", ..... },
При необходимости замените или удалите лишние записи, не забыв убрать или добавить их в разделах selector и urltest
"type": "selector", "tag": "Proxy-out", "outbounds": [ "URL-Test", "direct", "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "default": "URL-Test" }, { "type": "urltest", "tag": "URL-Test", "outbounds": [ "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out"
В разделе «route» «rules« прописаны правила для прямого подключения к сайтам в зоне .ru и другим незаблокированным ресурсам:
«geosite»: «private», «youtube», «google», «yandex» — обозначает домены: частных адресов (включая .local), YouTube и поддомены, сервисы Google, сервисы Яндекса.
«geoip»: «private», «ru» — обозначает диапазоны IP адресов: частные адреса, диапазоны IP адресов сегмента .RU
«ip_cidr» — в этом разделе можно указать диапазоны IP адресов которые должны подключаться напрямую минуя прокси
«domain_suffix»
Правило соответствует, если домен запроса соответствует суффиксу. Например: «google.com» соответствует «www.google.com», «mail.google.com» и «google.com», но не соответствует «content-google.com».
«domain_keyword»
Правило соответствует, если домен запроса содержит ключевое слово.
При редактировании json файлов можно пользоваться инструментами вроде JSON Online Validator для проверки форматирования
В раздел outbounds нужно ввести параметры вашего (ваших) прокси: IP, порт, пароль, uuid, public key (если применимо).
параметр download_detour используется для указания способа скачивания баз, в случае конфигурации — через прокси
Для работы используются списки SagerNet от разработчика sing-box, они не содержат списков заблокированных в РФ ресурсов и поэтому многие незаблокированные сайты могут открываться через прокси.
Для работы sing-box необходимо прописать настройки файрволла, для этого:
В файл /etc/config/network добавим:
config interface 'proxy' option proto 'none' option device 'singtun0'
В файл /etc/config/firewall :
config zone option name 'proxy' list network 'tunnel' option forward 'REJECT' option output 'ACCEPT' option input 'REJECT' option masq '1' option mtu_fix '1' option device 'singtun0' option family 'ipv4' config forwarding option name 'lan-proxy' option dest 'proxy' option src 'lan' option family 'ipv4'
После чего перезагружаем сеть:
/etc/init.d/network restart
Далее проверяем работоспособность конфигурации:
sing-box check -c /etc/sing-box/config.json
Если всё правильно команда не выдаст ошибок.
Далее проверяем работу прокси:
sing-box run -c /etc/sing-box/config.json
Работоспособность можно проверить открыв нужный вам сайт.
Если всё сработало, можем добавить sing-box в автозапуск, для этого вводим команды:
Добавим sing-box в автозапуск:
/etc/init.d/sing-box enable /etc/init.d/sing-box start
На этом настройка sing-box завершена.
В случае настройки sing-box на маршрутизацию с помощью firewall4, то есть классическими маршрутами к singtun0, конфигурация /etc/sing-box/config.json будет упрощена и выглядеть так:
{ "log": { "disabled": false, "level": "warn", "output": "/tmp/sing-box.log", "timestamp": true }, "dns": { "servers": [] }, "inbounds": [ { "type": "tun", "tag": "tun-in", "interface_name": "singtun0", "inet4_address": "172.19.16.1/30", "stack": "gvisor", "mtu": 9000, "auto_route": false, "strict_route": false, "endpoint_independent_nat": false, "sniff": true, "sniff_override_destination": true } ], "outbounds": [ { "type": "selector", "tag": "Proxy-out", "outbounds": [ "URL-Test", "direct", "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "default": "URL-Test" }, { "type": "urltest", "tag": "URL-Test", "outbounds": [ "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "url": "http://www.gstatic.com/generate_204", "interval": "1m", "tolerance": 50 }, { "type": "shadowsocks", "tag": "shadowsocks-out", "server": "IP", "server_port": 15000, "method": "chacha20-ietf-poly1305", "password": "password" }, { "type": "vless", "tag": "reality-out", "server": "IP", "server_port": 8442, "uuid": "UUID", "flow": "xtls-rprx-vision", "network": "tcp", "tls": { "enabled": true, "insecure": false, "server_name": "SERVERNAME", "utls": { "enabled": true, "fingerprint": "chrome" }, "reality": { "enabled": true, "public_key": "AP24JYROAB8odK5glVW_KLnsWl3UZ-voaGq_9ihQgTL" } } }, { "type": "trojan", "tag": "trojan-WebSocket-out", "server": "IP", "server_port": 8443, "password": "PASSWORD", "transport": { "type": "ws", "path": "/", "early_data_header_name": "Sec-WebSocket-Protocol" }, "tls": { "enabled": true, "disable_sni": false, "server_name": "d43f429a97e4ea6d.gstatic.com" }, "multiplex": { "enabled": true, "max_connections": 4, "min_streams": 4, "max_streams": 0 } }, { "type": "vmess", "tag": "vmess-tls-out", "server": "IP", "server_port": 8444, "uuid": "UUID", "security": "auto", "alter_id": 0, "global_padding": false, "authenticated_length": true, "tls": { "enabled": true, "disable_sni": false, "server_name": "google.com", "insecure": false, "alpn": [ "http/1.1" ] }, "multiplex": { "enabled": true, "protocol": "smux", "max_connections": 5, "min_streams": 4, "max_streams": 0 }, "connect_timeout": "5s" }, { "type": "direct", "tag": "direct" }, { "type": "block", "tag": "block" } ], "route": { "rules": [], "final": "Proxy-out", "auto_detect_interface": true } }
Для настройки самих маршрутов или BGP рекомендую статьи:
Точечный обход блокировок на роутере OpenWrt c помощью BGP / Хабр (habr.com) С помощью BGP (bird2).
Точечный обход блокировок PKH на роутере с OpenWrt с помощью WireGuard и DNSCrypt / Хабр (habr.com) (путём скачивания списков и настройкой маршрутов в iptables, nftables).
3. Настройка обхода блокировок с помощью GeoIP, Geosite от L11R
Данный способ с GeoIP и Geosite содержащие весь дамп базы РКН (автор данных файлов @L11R, огромная ему за это благодарность). К сожалению данный способ требователен к количеству ОЗУ, у меня запустилось минимум с 384 МБ, иначе срабатывал memory killer. Удобство способа в том, что является заменой BGP (или скачивания списков), трафик на адреса из баз идёт через прокси, всё остальное напрямую.
Пример такого config.json:
{ "log": { "disabled": false, "level": "warn", "output": "/tmp/sing-box.log", "timestamp": true }, "dns": { "servers": [ { "tag": "google", "address": "tls://8.8.8.8" }, { "tag": "block", "address": "rcode://success" } ], "final": "google", "strategy": "prefer_ipv4", "disable_cache": false, "disable_expire": false }, "inbounds": [ { "type": "mixed", "tag": "mixed-in", "listen": "127.0.0.1", "listen_port": 1080, "tcp_fast_open": false, "sniff": true, "sniff_override_destination": true, "set_system_proxy": false }, { "type": "tun", "tag": "tun-in", "interface_name": "singtun0", "inet4_address": "172.19.16.1/30", "stack": "gvisor", "mtu": 9000, "auto_route": true, "strict_route": false, "endpoint_independent_nat": false, "sniff": true, "sniff_override_destination": true } ], "outbounds": [ { "type": "selector", "tag": "Proxy-out", "outbounds": [ "URL-Test", "direct", "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "default": "URL-Test" }, { "type": "urltest", "tag": "URL-Test", "outbounds": [ "shadowsocks-out", "vmess-tls-out", "trojan-WebSocket-out", "reality-out" ], "url": "http://www.gstatic.com/generate_204", "interval": "1m", "tolerance": 50 }, { "type": "shadowsocks", "tag": "shadowsocks-out", "server": "IP", "server_port": 15000, "method": "chacha20-ietf-poly1305", "password": "password" }, { "type": "vless", "tag": "reality-out", "server": "IP", "server_port": 8442, "uuid": "UUID", "flow": "xtls-rprx-vision", "network": "tcp", "tls": { "enabled": true, "insecure": false, "server_name": "SERVERNAME", "utls": { "enabled": true, "fingerprint": "chrome" }, "reality": { "enabled": true, "public_key": "AP24JYROAB8odK5glVW_KLnsWl3UZ-voaGq_9ihQgTL" } } }, { "type": "trojan", "tag": "trojan-WebSocket-out", "server": "IP", "server_port": 8443, "password": "PASSWORD", "transport": { "type": "ws", "path": "/", "early_data_header_name": "Sec-WebSocket-Protocol" }, "tls": { "enabled": true, "disable_sni": false, "server_name": "d43f429a97e4ea6d.gstatic.com" }, "multiplex": { "enabled": true, "max_connections": 4, "min_streams": 4, "max_streams": 0 } }, { "type": "vmess", "tag": "vmess-tls-out", "server": "IP", "server_port": 8444, "uuid": "UUID", "security": "auto", "alter_id": 0, "global_padding": false, "authenticated_length": true, "tls": { "enabled": true, "disable_sni": false, "server_name": "google.com", "insecure": false, "alpn": [ "http/1.1" ] }, "multiplex": { "enabled": true, "protocol": "smux", "max_connections": 5, "min_streams": 4, "max_streams": 0 }, "connect_timeout": "5s" }, { "type": "direct", "tag": "direct" }, { "type": "block", "tag": "block" }, { "type": "dns", "tag": "dns-out" } ], "route": { "geoip": { "path": "/etc/sing-box/geoip.db", "download_url": "https://github.com/savely-krasovsky/antizapret-sing-box/releases/latest/download/geoip.db", "download_detour": "Proxy-out" }, "geosite": { "path": "/etc/sing-box/geosite.db", "download_url": "https://github.com/savely-krasovsky/antizapret-sing-box/releases/latest/download/geosite.db", "download_detour": "Proxy-out" }, "rules": [ { "protocol": "dns", "outbound": "dns-out" }, { "geoip": "antizapret", "geosite": "antizapret", "outbound": "Proxy-out" }, { "protocol": "quic", "outbound": "block" } ], "final": "direct", "auto_detect_interface": true } }
Если из конфигурации убрать строки:
{ "type": "mixed", "tag": "mixed-in", "listen": "127.0.0.1", "listen_port": 1080, "tcp_fast_open": false, "sniff": true, "sniff_override_destination": true, "set_system_proxy": false },
и "path": "/etc/sing-box/geoip.db" , "path": "/etc/sing-box/geosite.db",
То конфигурацию можно использовать и в клиенте sing-box на Android и других платформах
4. Установка sing-box в оперативную память
Если установить sing-box в ПЗУ не удалось (а это вполне вероятный сценарий для большинства роутеров среднего ценового сегмента), возможно произвести установку в ОЗУ и подгружать пакет при запуске устройства.
Установленный и запущенный sing-box занимает около 35 Мб ОЗУ.
Для начала нам необходимо установить в ПЗУ модули ядра и iptables-nft
opkg install kmod-inet-diag kmod-netlink-diag kmod-tun iptables-nft
Это должно занять около 1Мб памяти, после чего установим sing-box в ОЗУ:
opkg install sing-box -d ram
Если всё успешно установилось, далее нужно будет создать папку конфигурации:
mkdir /etc/sing-box
После чего помещаете ваш файл config.json из п.2 в /etc/sing-box/config.json
Проверяем работу прокси (более подробно в п.2):
/tmp/usr/bin/sing-box run -c /etc/sing-box/config.json
Если всё заработало, далее настраиваем автозапуск sing-box.
Для автоматической установки пакета при загрузке системы в файл /etc/rc.local добавляем строки перед exit 0
opkg update opkg install sing-box -d ram exit 0
при помощи текстового редактора, либо через Luci

Сохраняем изменения и создаём службу автозапуска для sing-box.
Создаём файл /etc/init.d/sing-box следующего содержания:
#!/bin/sh /etc/rc.common # # Copyright (C) 2022 by nekohasekai <contact-sagernet@sekai.icu> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # START=99 USE_PROCD=1 ##### ONLY CHANGE THIS BLOCK ###### PROG=/tmp/usr/bin/sing-box # Положение sing-box в ОЗУ RES_DIR=/etc/sing-box/ # resource dir / working dir / the dir where you store ip/domain lists CONF=./config.json # where is the config file, it can be a relative path to $RES_DIR ##### ONLY CHANGE THIS BLOCK ###### start_service() { sleep 10 # Ожидание скачивания пакета sing-box при загрузке системы procd_open_instance procd_set_param command $PROG run -D $RES_DIR -c $CONF procd_set_param user root procd_set_param limits core="unlimited" procd_set_param limits nofile="1000000 1000000" 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 iptables -I FORWARD -o singtun+ -j ACCEPT #Эта строка будет выдавать ошибку, если iptables-nft не установлен echo "sing-box is started!" } stop_service() { service_stop $PROG iptables -D FORWARD -o singtun+ -j ACCEPT echo "sing-box is stopped!" } reload_service() { stop sleep 5s echo "sing-box is restarted!" start }
Делаем файл исполняемым:
chmod +x /etc/init.d/sing-box
После чего добавляем в автозапуск:
/etc/init.d/sing-box enable /etc/init.d/sing-box start
На этом настройка окончена.
P.S. 35 Мб это достаточно большой объём занимаемой оперативной памяти для роутера со 128 Мб, так что решение что называется на грани.
ссылка на оригинал статьи https://habr.com/ru/articles/756178/
Добавить комментарий