Клиенты прокси (steer-proxy)#
Этот документ описывает модуль steer-proxy — клиенты протоколов trojan, shadowsocks, socks, http и
vmess. Модуль есть только в пакете steer-proxy; в мета-пакет steer-extended он не входит, как и
steer-hysteria2.
Зачем он нужен: коннектор sing-box (steer-box-connector) даёт немодифицированным роутерам podkop и
forkop работать поверх steer. Он переводит конфиг sing-box в спеку steer v2, а каждый прокси-outbound
становится выходом kind: tunnel с одним из этих протоколов; узел берётся из файла подписки (одна
share-ссылка на файл), который пишет коннектор.
Клиент поднимает TUN-устройство и несёт через него TCP и, где протокол это умеет, UDP. Дальше
устройство ничем не отличается от wg0 для остальной части ядра: метки, таблицы, каналы и failover
работают с ним так же. Строение общее с клиентами VLESS и hysteria2 — docs/vless.md,
docs/hysteria2.md и раздел «Туннели» в docs/architecture.md: тот же
стек туннеля (src/tunnel) и, у протоколов поверх потока, тот же транспорт с TLS/Reality
(src/proto/transport).
Что поддерживается#
| Протокол | Транспорт и безопасность | TCP | UDP |
|---|---|---|---|
trojan |
tcp, grpc, xhttp, ws, httpupgrade; tls или reality (как у vless) | да | да (в потоке) |
shadowsocks |
голый tcp (шифрует сам протокол) | да | да, кроме 2022 |
socks |
голый tcp | да | socks5 (ASSOCIATE), не socks4 |
http |
tcp или tls (CONNECT) | да | нет |
vmess |
tcp, grpc, xhttp, ws, httpupgrade; tls (как у vless) | да | да (в потоке) |
- trojan: пароль на проводе —
SHA-224(пароль)в hex; адрес назначения — SOCKS5. UDP — пакеты[адрес][длина][CRLF][данные]в потоке. Поддержаны те же транспорты и безопасность, что у VLESS (reality в том числе), так как слой транспорта общий. - shadowsocks: AEAD-шифры
aes-128-gcm,aes-256-gcm,chacha20-ietf-poly1305(ключ из пароля — EVP_BytesToKey на MD5, подключ сессии — HKDF-SHA1); SIP0222022-blake3-aes-128-gcm,2022-blake3-aes-256-gcm,2022-blake3-chacha20-poly1305, включая многопользовательскийiPSK:uPSK(EIH на один уровень реле);none/plainбез шифрования. PSK у 2022 — base64 (16 или 32 байта). - socks: socks5 с авторизацией имя/пароль и без; socks4 и socks4a. У socks5 работает UDP ASSOCIATE (управляющее TCP-соединение плюс сокет к ретранслятору).
- http: прокси HTTP CONNECT, по желанию поверх TLS (
https://), с базовой авторизацией (user:pass@). - vmess: AEAD-заголовок (alterId 0), шифр тела
aes-128-gcmилиchacha20-poly1305(auto— aes-128-gcm); те же транспорты, что у VLESS.
ICMP не пересылается: всё, что не TCP и не UDP, получает ICMP «порт недостижим», как у VLESS.
Что НЕ поддерживается и почему#
- shadowsocks 2022 UDP: формат UDP у 2022 иной (сессии, счётчик пакетов, заголовок под AES-ECB и XChaCha для chacha-варианта) и существенно сложнее потокового. TCP у таких узлов работает; UDP такого узла отклоняется с причиной в журнале, датаграммы через него не идут.
- socks4/4a UDP: socks4 не знает UDP вовсе — датаграммы отклоняются.
- http CONNECT UDP: у CONNECT нет UDP — датаграммы отклоняются.
- vmess security
noneиzero: тело без AEAD; podkop и коннектор их не выдают, а без шифра тела у vmess нет и проверки. Такой узел пропускается с причиной. - vmess alterId ≠ 0: старый формат заголовка (MD5) снят в самом vmess; поддержан только AEAD (alterId 0).
- shadowsocks
?plugin=: обфускаторы ss (v2ray-plugin, obfs) — отдельная связка, которой нет; узел сplugin=пропускается с причиной, а не идёт на сервер, который плагина ждёт.
Форматы узла (share-ссылки)#
Подписка — список share-ссылок по строкам, тот же список в base64. Чужие ссылки считаются (в
foreign) и не мешают; узлы наших протоколов, которые клиент не потянет, получают причину пропуска
(proxy-nodes, поле skipped_reasons).
trojan#
trojan://пароль@хост:порт?security=tls&sni=&type=&path=&host=&…#имя
Та же форма и те же параметры транспорта, что у vless:// (docs/vless.md): type (tcp,
grpc, xhttp, ws, httpupgrade), security (tls, reality: pbk, sid), sni, fp, path, host,
serviceName, pcs/vcn (проверка сертификата), allowInsecure. Пароль — весь userinfo до @, с
процентным кодированием. trojan без TLS не бывает. Узел с allowInsecure пригоден, только если у выхода
стоит insecure: true, иначе пропускается с причиной «allowInsecure: включите insecure у выхода явно» —
как у VLESS.
shadowsocks (SIP002)#
ss://base64url(метод:пароль)@хост:порт#имя
ss://метод:пароль@хост:порт#имя (userinfo процентно, без base64)
Для 2022 пароль — base64 PSK (ss://2022-blake3-aes-128-gcm:<base64-16-байт>@…), многопользовательский
— iPSK:uPSK (…:<base64>:<base64>@…). Параметр ?plugin= отвергается с причиной.
socks#
socks5://[user:pass@]хост:порт#имя
socks://хост:порт (= socks5)
socks4://хост:порт#имя
socks4a://хост:порт#имя
У socks4 пароля нет (ссылка с паролем пропускается).
http#
http://[user:pass@]хост:порт#имя
https://[user:pass@]хост:порт?sni=#имя (CONNECT поверх TLS)
У https:// — те же параметры проверки сертификата, что у trojan (sni, pcs/vcn, allowInsecure), и
то же правило для allowInsecure: узел пригоден только при insecure: true у выхода. Без sni имя
берётся из адреса; адрес-IP без sni — пропуск («tls по адресу без sni: нечем сверить»).
vmess (v2rayN)#
vmess://base64(JSON)
JSON v2rayN: add, port, id, aid (только 0), scy (auto, aes-128-gcm, chacha20-poly1305),
net (tcp, ws, grpc, httpupgrade; h2 читается как xhttp), type, host, path, tls, sni,
fp, ps (имя). alpn не читается. Признака allowInsecure у ссылки vmess ядро не читает: сертификат
узла vmess не проверяется только при insecure: true у выхода.
Выход в спеке#
outputs:
nl: { kind: tunnel, protocol: trojan, subscription: sub/nl, nodes: [0, 2], over: wg0 }
ss: { kind: tunnel, protocol: shadowsocks, subscription: sub/ss }
vm: { kind: tunnel, protocol: vmess, subscription: sub/vm, insecure: true }
Ключи те же, что у VLESS: subscription, nodes (номера пригодных узлов; пусто — первый
отвечающий), device, over, exclude и exclude_name (какие узлы не брать: страна по флагу в
имени, кусок имени; spec-v2.md), active, by, interval, silence (пул узлов:
сколько узлов работают сразу, как делятся соединения, как клиент за ними следит —
docs/spec-v2.md, «Пул узлов туннеля»). Ключа transport у прокси нет — транспорт берётся из ссылки узла.
insecure есть только у протоколов с TLS (trojan, vmess, http) — у ss и socks его нет. Без пакета
steer-proxy спека отвергается словами «kind … требует пакет steer-proxy».
Подъём, перебор узлов, слежка#
steer proxy <выход> читает спеку и подписку, берёт кандидатов (nodes либо все пригодные) и
проверяет их по порядку: рукопожатие и запрос через узел к 1.1.1.1:80, срок — 8 секунд на узел.
Первый отвечающий — узел выхода. Затем поднимается устройство, демону уходит up с именем устройства
(маршрут ставит демон), заводится слежка — тем же пулом узлов, что у VLESS
(docs/vless.md, «Узлы выхода: сколько сразу и как за ними следят»): active узлов сразу,
проверка каждого раз в interval, обрыв повисших соединений по порогу silence, мёртвый узел —
сброс его соединений и замена следующим кандидатом без перезапуска процесса; down демону — когда
живых узлов не осталось.
Команды: steer proxy-nodes <выход|/файл> [--insecure] — узлы подписки JSON-ом; steer proxy-probe
<выход|/файл> [--node N] [--timeout С] [--insecure] — проверка узлов с задержкой и причиной отказа.
По файлу номера узлов сквозные по пяти протоколам, у выхода — внутри его протокола (порядок внутри
протокола один). --insecure — только с файлом: узлы trojan и https с allowInsecure входят в
перечень, как у выхода с insecure: true, и номера совпадают с его номерами; с именем выхода — отказ.
У узла печатаются, кроме общих полей, transport, у shadowsocks — method (шифр), у vmess — cipher
(шифр тела), у узлов с TLS или Reality — fp, если задан, и "insecure":true у узла с allowInsecure
(contract-v1.md, раздел 6).
status и diag#
В steer status у выхода — nodes и объект proxy (пока клиент жив): node (первый активный),
protocol, up, want, slots, by и active — активные узлы с номерами и именами, как у
объекта vless (docs/vless.md). steer diag проверяет, что клиент запущен и соединение
поднято, и предупреждает, пока активных узлов меньше active.
Ограничения#
- Адрес назначения — IPv4 клиента; имён клиент не передаёт (сервер видит адрес).
- Телефонная сборка (профиль android) модуля не содержит — как и
steer-hysteria2.