subconverter локально: подписки без публичных сервисов

subconverter локально: подписки без публичных сервисов

Marcus Reid
14 октября 2026 г.· 10 мин чтения

Запуская subconverter локально на своём компьютере, вы преобразуете прокси-подписку в формат другого клиента, не отправляя ссылку на подписку публичному сайту-конвертеру. В инструкции используется закреплённый образ Docker tindy2013/subconverter:0.9.0, опубликованный только на 127.0.0.1; ссылка не попадает в историю оболочки и журналы контейнера, а результат проверяется до импорта в клиент.[1][2]

Ключевые выводы

  • Ссылка на подписку — это учётные данные; публичный конвертер получает её целиком.
  • Публикуйте контейнер на 127.0.0.1, потому что Docker по умолчанию публикует порты на всех адресах хоста.
  • Замените токен API по умолчанию и отключите журналы контейнера: на стандартном уровне в них попадает загружаемый URL.
  • Версия 0.9.0 разбирает ссылки ss, ssr, vmess, trojan, socks и HTTP; парсера ссылок VLESS в ней нет.
  • Сверьте число узлов, TLS, транспорт и поля UDP, прежде чем доверять преобразованному файлу.

Инструкция подготовлена по официальным источникам ниже; полный сквозной тест не выполнялся. Она охватывает один компьютер, которым вы управляете, а не публичный или общий сервис конвертации. По чек-листу задач и восстановления для собственного сервера решите, подходит ли локальный инструмент вашей схеме.

Что видит публичный сайт-конвертер?

Интерфейс конвертера принимает адрес подписки в параметре запроса url эндпоинта /sub вместе с целевым форматом и необязательной внешней конфигурацией.[1] Значит, владелец такого эндпоинта получает ссылку полностью, может позже загрузить её снова и видит каждый сервер, порт и ключ, которые она возвращает. Журналы, аналитика и кеширующие слои такого сайта могут хранить копии, о которых вы никогда не узнаете.

Элемент запросаКто узнаёт его при публичном сайтеКто узнаёт его при локальном контейнере
URL подписки и его токенВладелец сайта и его журналыТолько ваш компьютер и поставщик подписки
Адреса, порты и ключи узловВладелец сайта после загрузки ссылкиТолько ваш компьютер
Ваш IP-адрес при конвертацииВладелец сайта; поставщик видит адрес сайтаТолько поставщик подписки
Преобразованный файлВладелец сайта во время генерацииТолько ваш компьютер

Поэтому ссылки на подписку нужно хранить и отзывать как пароли. Если вы уже вставляли ссылку в публичный конвертер, попросите поставщика сбросить её, прежде чем следовать этой инструкции. А если правка преобразованных конфигураций для множества узлов требует больше сил, чем стоит задача, сначала сравните собственные серверы и управляемый VPN.

Какую версию subconverter запускать?

Последний выпуск с тегом — v0.9.0, и в Docker Hub есть соответствующий тег образа 0.9.0; тег latest следует за новыми сборками основной ветки.[2][3] Закрепите 0.9.0, чтобы запускать именно тот код, который вы проверили, и перед каждым использованием смотрите, не появились ли новые теги в репозитории.

Узнайте ограничения парсера до конвертации. В v0.9.0 парсер ссылок распознаёт ssr://, vmess://, ss://, trojan://, ссылки socks и HTTP в стиле Telegram, а также Netch://; ветки для ссылок vless://, Hysteria2 или TUIC в нём нет.[4] Узлы в неподдерживаемых форматах просто будут отсутствовать в результате, а не преобразуются. Среди документированных целевых форматов есть clash, surge, quanx, loon и v2ray, а обработчик запросов v0.9.0 также содержит цель singbox, которой нет в таблице README.[1][5]

Шаг 1: подготовьте закрытый рабочий каталог и токен

Создайте каталог, доступный только вашему пользователю, и сгенерируйте новый токен доступа вместо стандартного. В примере файла настроек указано api_access_token=password, а программа также читает API_MODE и API_TOKEN из окружения.[6][7]

mkdir -m 700 -p ~/subconv && cd ~/subconv
umask 077
printf 'API_MODE=true\nAPI_TOKEN=%s\n' "$(openssl rand -hex 24)" > subconv.env

API_MODE=true запрещает службе загружать локальные подписки и напрямую отдавать локальные файлы.[6] Токен API subconverter защищает эндпоинт обновления конфигурации, который в Docker README вызывается с параметром token.[3] Хранение обоих значений в файле окружения не даёт токену попасть в командную строку, где его могут раскрыть история оболочки и список процессов.

Шаг 2: запустите закреплённый образ только на localhost

Docker публикует порты контейнера на всех адресах хоста (0.0.0.0 и [::]), если адрес не указан явно, и тем самым открывает службу вашей сети.[8] Привяжите её к loopback явно:

docker run -d --name subconv-local --restart unless-stopped \
  --log-driver none --memory 256m \
  --cap-drop ALL --security-opt no-new-privileges \
  --env-file ./subconv.env \
  -p 127.0.0.1:25500:25500 \
  tindy2013/subconverter:0.9.0

Проверьте работу командой curl -fsS http://127.0.0.1:25500/version; по Docker README в ответе должны быть название бэкенда subconverter и версия.[3] Затем через sudo ss -lntp | grep 25500 убедитесь, что хост слушает только 127.0.0.1:25500: именно такая схема subconverter в Docker на localhost не пускает другие устройства.

В выпусках Docker Engine старше 28.0.0 хосты в том же сегменте канального уровня могут обращаться к портам, опубликованным на localhost.[8] Проверьте docker version и обновитесь, прежде чем полагаться на привязку к loopback в общей сети.

Шаг 3: выполните конвертацию, не оставляя ссылку в истории оболочки

Прочитайте ссылку через скрытый ввод в закрытый файл, а затем позвольте curl закодировать содержимое файла для URL:

read -rs SUB_URL && printf '%s' "$SUB_URL" > sub.txt && unset SUB_URL
curl -fsS -G http://127.0.0.1:25500/sub \
  --data-urlencode target=clash \
  --data-urlencode url@sub.txt \
  -o converted.yaml
rm sub.txt

Подписку загружает сам контейнер. В примере файла настроек proxy_subscription=NONE означает, что эта загрузка идёт напрямую, а не через заданный прокси.[6] Поэтому поставщик подписки видит адрес вашего компьютера — так же, как при обновлении ссылки клиентом.

Почему отключены журналы контейнера

В v0.9.0 обработчик пишет строку журнала уровня info, в которую входит каждый загружаемый URL подписки.[5] При стандартном журналировании Docker эта строка осталась бы в выводе docker logs. Драйвер журналов none не хранит журналы контейнера, и docker logs ничего не возвращает.[9] Если для отладки журналы нужны, запустите временный контейнер с журналированием и удалите его после работы.

Шаг 4: сравните результат поле за полем

Успешный HTTP-ответ не означает, что каждый узел преобразован верно. Откройте converted.yaml в локальном редакторе и сверьте его с тем, что поставщик документирует для каждого узла.

ПолеЧто проверитьОстановитесь, если
Число узловСтолько же, сколько в источнике, минус намеренно исключённыеУзлы пропали без объяснения
Тип протоколаСовпадает с исходным узломУзел сменил протокол или исчез
Сервер и портИдентичны источникуОтличается любой адрес или порт
TLS и имя сервераTLS включён, тот же SNI, не добавлен skip-cert-verify: trueПроверка сертификата отключена
Транспорт и путьТот же путь WebSocket или другого транспорта и тот же хостПуть или хост пуст либо отличается
Флаг UDPСоответствует возможностям сервераUDP включён для сервера, который его не поддерживает

В примере файла настроек задано exclude_remarks=(到期|剩余流量|时间|官网|产品|平台), то есть отбрасываются узлы, в названии которых есть любое из этих слов.[6] Правило нацелено на информационные записи, которые добавляют некоторые поставщики, но исчезнет и настоящий узел с подходящим названием. Стандартная конфигурация также добавляет группы прокси и наборы правил, поэтому проверьте правила маршрутизации, а не только записи прокси.

Относитесь к converted.yaml как к секрету: в нём все учётные данные из подписки. Импортируйте его с мерами предосторожности из руководства по импорту конфигурации без утечки учётных данных, а затем удалите локальную копию, если клиент хранит свою.

Как сохранить subconverter локально закрытым?

К порту, опубликованному на loopback, могут подключаться только процессы на вашем компьютере, но это все локальные пользователи и приложения. Запускайте конвертер на однопользовательской машине и останавливайте контейнер после конвертации. Та же логика относится и к другим локальным интерфейсам управления, например к API контроллера Mihomo: loopback ограничивает круг подключающихся, а сильный секрет — то, что может сделать подключившийся процесс.

Держите subconv.env и рабочий каталог с правами 0700 или 0600. Не добавляйте обратный прокси, проброс порта или туннель, чтобы открыть конвертер другим устройствам: так закрытый инструмент снова превращается в сервис конвертации, хранящий ссылки всех пользователей. Если клиент должен обновляться автоматически, запускайте конвертацию по расписанию на той же машине и давайте клиенту читать локальный файл.

Как обновить или удалить конвертер?

Для обновления проверьте репозиторий на новый выпуск, прочитайте примечания и загрузите новый закреплённый тег. Остановите и удалите старый контейнер командой docker rm -f subconv-local, запустите новый тег той же командой и повторите проверки /version, слушателя и результата.

Чтобы удалить всё, выполните docker rm -f subconv-local, удалите образ командой docker image rm tindy2013/subconverter:0.9.0 и удалите ~/subconv. Если ссылка на подписку когда-либо проходила через общую или публичную систему, после этого сбросьте её у поставщика.

Итоги

  • Локальный конвертер держит ссылку на подписку и результат на машине под вашим контролем.
  • Закрепите образ, привяжите его к 127.0.0.1, замените токен и отключите журналы, которые записали бы ссылку.
  • Версия 0.9.0 не преобразует ссылки VLESS, Hysteria2 и TUIC, поэтому проверяйте, не пропали ли узлы.
  • Перед импортом сверьте поля TLS, транспорта и UDP и храните результат как секрет.

Часто задаваемые вопросы (FAQ)

Полностью ли безопасен локальный subconverter для ссылки на подписку?

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

Почему закреплять версию 0.9.0, а не использовать latest?

Фиксированный тег позволяет прочитать примечания к выпуску и знать, какой парсер и какие значения по умолчанию вы запускаете. Тег latest может незаметно измениться между конвертациями.

Почему мои узлы VLESS исчезли после конвертации?

В парсере ссылок версии 0.9.0 нет ветки для ссылок vless, поэтому такие записи пропускаются. Используйте клиент, который напрямую читает исходный формат подписки.

Нужно ли менять токен API по умолчанию, если порт локальный?

Да. Любой локальный процесс может обратиться к порту, а стандартное значение — публично задокументированное слово password, которое кто угодно угадает сразу.

Где журналы контейнера раскрывают URL подписки?

На стандартном уровне info версия 0.9.0 записывает каждый загружаемый URL подписки. Стандартное журналирование Docker сохранило бы эту строку, поэтому в инструкции журналы контейнера отключены.

Можно ли открыть конвертер для устройств семьи в локальной сети?

Не в этой схеме. Публикация в сети раскрыла бы ссылку на подписку каждого пользователя самой службе и всем, кто может до неё дотянуться.

Нужна ли преобразованному файлу та же защита, что и ссылке?

Да. В нём каждый адрес сервера, порт и ключ из подписки, поэтому храните его закрыто и удаляйте копии, которые клиенту больше не нужны.

Отказ от ответственности: Данная статья носит исключительно информационный характер и не является юридической, технической или иной профессиональной консультацией. Мы не гарантируем точность, полноту или актуальность содержания.

Источники:

  1. subconverter README — https://github.com/tindy2013/subconverter
  2. subconverter release v0.9.0 — https://github.com/tindy2013/subconverter/releases/tag/v0.9.0
  3. subconverter Docker README at v0.9.0 — https://github.com/tindy2013/subconverter/blob/v0.9.0/README-docker.md
  4. subconverter v0.9.0 subscription parser source — https://github.com/tindy2013/subconverter/blob/v0.9.0/src/parser/subparser.cpp
  5. subconverter v0.9.0 request handler source — https://github.com/tindy2013/subconverter/blob/v0.9.0/src/handler/interfaces.cpp
  6. subconverter v0.9.0 example preferences — https://github.com/tindy2013/subconverter/blob/v0.9.0/base/pref.example.ini
  7. subconverter v0.9.0 startup source — https://github.com/tindy2013/subconverter/blob/v0.9.0/src/main.cpp
  8. Docker Docs: Port publishing and mapping — https://docs.docker.com/engine/network/port-publishing/
  9. Docker Docs: Configure logging drivers — https://docs.docker.com/engine/logging/configure/

Sources checked 14 октября 2026 г.

Рекомендуемые статьи:

Начните бесплатный 3-дневный пробный период

Зарегистрируйтесь и попробуйте все премиум-функции бесплатно.

*Только для новых пользователей. Один пробный период на пользователя.

subconverter локально: подписки без публичных сервисов | AethoVPN