English · Русский
Панель управления прокси-сервисами, которая уживается с 3x-ui на одном сервере
MTProxy, NaiveProxy и Mieru под одной панелью — с транзакционным установщиком, который либо доводит установку до конца, либо возвращает сервер как было.
Что это · Порт 443 · Установка · Протоколы · Эксплуатация · Безопасность
Warning
Текущий публичный выпуск — v0.1.0 Beta. Используйте его на новых или изолированных установках либо только после резервного копирования текущей конфигурации сервера.
Important
Проект рассчитан на людей, которые понимают, что такое DNS, TLS, Nginx и Docker. Установщик берёт на себя рутину и не даст сделать опасный шаг молча, но он не заменяет понимания того, как устроен ваш сервер.
Proxy Control — самостоятельная панель-компаньон для 3x-ui, которая управляет другими протоколами и доступами. Это не форк 3x-ui и не попытка заменить его интерфейс.
Главная идея: вы не обязаны выбирать между Proxy Control и 3x-ui. Оба работают на одном сервере, за одним общим портом 443, не мешая друг другу.
Что вы получаете:
| Контур | Для чего он нужен |
|---|---|
| MTProxy / Telemt | Прокси для Telegram. Панель выдаёт tg://-ссылки и QR-коды, ставит лимиты и срок действия, показывает состояние сервиса. |
| NaiveProxy | HTTPS-прокси, который снаружи выглядит обычным сайтом. Один доступ работает и как HTTPS, и как HTTP/2. Есть квота на пользователя и учёт трафика. |
| Mieru | Обфусцированный прокси со своим протоколом поверх TCP и UDP. Панель выдаёт одноразовую mierus://-ссылку и QR. |
| 3x-ui | VLESS Reality (TCP и XHTTP) и Hysteria2. В режиме existing установщик принимает уже установленный 3x-ui, делит с ним порт 443 и не меняет его файлы. В режиме managed-new на чистом сервере он сам ставит 3x-ui 3.7.0 и создаёт эти инбаунды. |
| Панель | Роли владельца, администратора и наблюдателя. Аудит без секретов, разовая выдача доступов, управление квотами. |
| Fleet (опционально) | Инвентаризация и ограниченное управление удалёнными узлами по mTLS. Ставится вручную. |
Учёт трафика у протоколов разный, и панель этого не скрывает: Telemt разделяет
счётчик процесса и расход квоты, Naive считает полезные байты только после
успешно закрытого туннеля, а Mieru честно показывает unavailable, когда
безопасного счётчика на пользователя нет.
Публичный порт 443 остаётся у Nginx. Nginx смотрит только на имя домена в TLS-приветствии (SNI) и раздаёт соединения нужной службе. Proxy Control не забирает 443 себе — он просит Nginx добавить пару маршрутов и ничего больше.
Клиент ── TCP/443 ──► Nginx stream + SNI
├──► 3x-ui и его протоколы
├──► MTProxy / Telemt
├──► NaiveProxy
├──► другие ваши сайты
└──► панель Proxy Control
Поэтому установщик добавляет в вашу карту SNI только свои строки и никогда не переписывает её целиком. Если он не может однозначно понять вашу конфигурацию Nginx — он останавливается, а не угадывает.
Куда что слушает:
| Граница | Адрес | Кто имеет доступ |
|---|---|---|
| Публичный вход | TCP/443 | Только ваш Nginx stream, маршрутизация по SNI |
| Telemt / MTProxy | 127.0.0.1:8445 |
Только Nginx и локальная система |
| Панель | 127.0.0.1:8787 (HTTP) |
Локально; наружу — через TLS-vhost на 127.0.0.1:8443 |
| NaiveProxy (Caddy) | 127.0.0.1:4443 |
Только Nginx |
| Telemt API | mtproxy:9091 |
Только внутри сети Compose, наружу не публикуется |
| Mieru | Ваши TCP- и UDP-порты | Публично; порт 443 не используется |
| Управление Mieru | /run/mita/mita.sock |
Только локальный Unix-сокет |
| Fleet ingress | TCP/8790 | Только HTTPS с mTLS, если контур включён |
Контейнеры называются proxy-control-*. Имя проекта Compose (mtproxy) и
существующие тома сохраняются — это нужно, чтобы безопасно обновлять уже
работающие установки.
- Сервер на x86-64 — это то, на чём работает подавляющее большинство VPS. Другие архитектуры установщик отвергает при аудите, а не в середине установки: релиз собирается только под x86-64, и только он проверяется стендом.
- Ubuntu 24.04 с
systemd, доступrootилиsudo. - DNS-записи A/AAAA для всех ваших имён указывают напрямую на сервер. Для MTProto проксирование CDN нужно выключить — только режим DNS-only.
- Свободный TCP/80 — по нему Let's Encrypt проверяет домены.
- В режиме
coexist— уже работающий Nginx соstream, который владеет публичным 443, и ровно одна понятная карта$ssl_preread_server_nameв файле маршрутов. В режимеfreshустановщик ставит и настраивает Nginx сам; чужого владельца порта 443 быть не должно. - Свободные локальные порты из таблицы выше.
- Резервная копия Nginx, служб, маршрутов и состояния Docker — своя, отдельная.
Установщик остановится и ничего не тронет, если увидит: несовпадение DNS с
адресом сервера, NAT, CDN перед raw MTProto, неоднозначную карту Nginx, занятый
порт, владельца 443 не-Nginx или ошибку nginx -t. Это не повод «продолжить
всё равно» — это повод сначала разобраться.
Если в профиле есть Mieru, заранее положите два пакета в
/var/lib/proxy-control/ — установщик принципиально ничего не скачивает за вас:
mita_3.36.0_<arch>.deb— сервер;mieru_3.36.0_<arch>.deb— официальный клиент, которым установщик проверит, что трафик реально ходит.
URL и контрольные суммы обоих — в
release/external-artifacts.json.
Установщик сверит их и откажется работать при несовпадении.
Это место, где установка чаще всего останавливается, поэтому разберём его подробно.
Полный beta-комплект — профиль full, режим managed-new для 3x-ui и отдельный домен подписки — требует 9 разных доменов: панель Proxy Control, Fake-TLS MTProxy, NaiveProxy, Mieru, панель 3x-ui, VLESS Reality TCP, VLESS Reality XHTTP, Hysteria2 и subscription 3x-ui. Все должны иметь корректные DNS-записи на VPS; сертификаты нужны не всем.
Зависит от профиля. Домен нужен не всем протоколам:
| Домен | Когда нужен | Нужен ли сертификат |
|---|---|---|
panel — панель |
Всегда | Да |
mtproxy — MTProxy |
Всегда | Да |
naive — NaiveProxy |
В профилях с Naive | Да |
mieru — Mieru |
В профилях с Mieru | Нет |
three_xui.panel_domain |
В режиме 3x-ui | Да |
three_xui.hysteria_domain |
В режиме 3x-ui | Да |
three_xui.vless_tcp_domain |
В режиме 3x-ui | Нет |
three_xui.vless_xhttp_domain |
В режиме 3x-ui | Нет |
three_xui.subscription_domain |
managed-new, если нужна отдельная subscription |
Да |
Mieru и VLESS Reality сертификатов Let's Encrypt не требуют: Mieru работает по собственному протоколу, а Reality маскируется под чужой сайт и использует его сертификат. Домен им всё равно нужен — он попадает в клиентские конфигурации.
Для каждого имени, которому нужен сертификат, установщик сам разрешает DNS и требует четыре вещи:
- Есть запись A и хотя бы один её адрес совпадает с адресом этого сервера. Домен, указывающий «куда-то ещё», — жёсткая остановка.
- Записи AAAA либо нет, либо все её адреса тоже принадлежат этому серверу. Забытая AAAA, ведущая на старый хост, — самая частая причина, по которой выпуск сертификата проходит, а протокол потом не работает.
- CAA не запрещает Let's Encrypt. Проверяется и сам домен, и его родители.
- Если сертификат уже есть, он должен покрывать это имя. Чужой сертификат установщик не трогает.
Проксирование CDN (оранжевое облако) для домена MTProxy должно быть выключено: нужен режим DNS-only. Иначе A-запись укажет на CDN, а не на сервер, и проверка остановит установку — справедливо.
Установщик группирует домены по службам, и у каждой группы своя линия
(--cert-name):
| Линия | Какие имена покрывает |
|---|---|
proxy-control |
Домен панели и домен MTProxy — один сертификат на оба |
naive |
Домен NaiveProxy |
three-xui-panel |
Домен панели 3x-ui |
three-xui-hysteria |
Домен Hysteria2 |
three-xui-subscription |
Отдельный домен subscription 3x-ui |
Выпуск идёт через certbot certonly --webroot: для каждого имени
используется свой каталог /var/www/<домен>, куда Let's Encrypt кладёт
проверочный файл по TCP/80. Никаких DNS-01 и API вашего регистратора не нужно —
поэтому и требуется свободный порт 80.
Сразу после выпуска установщик выполняет certbot renew --dry-run для этой
линии. Смысл простой: продление проверяется в момент установки, а не через
три месяца, когда сертификат протухнет молча.
Ждать установки не нужно: план проверяет всё это и ничего не меняет. Запускать
его нужно из распакованного релиза — из клона Git он не работает, потому что
там нет release/release.json, а установщик отказывается работать без
идентичности релиза.
python3 -m installer.cli plan --config examples/installer/core.toml --jsonЕсли план проходит, домены и DNS в порядке. Если останавливается — в выводе будет ровно то имя, которое не прошло проверку.
Со страницы релиза заберите все четыре файла из Assets: архив, SHA256SUMS,
release-manifest.json и sbom.spdx.json. У v0.1.0 нет опубликованной GitHub
attestation. Команда ниже сверяет три payload-файла, перечисленные в скачанном
SHA256SUMS; сам файл контрольных сумм остаётся доверенным как файл со страницы
релиза, отдельного доказательства provenance для него нет. После сверки
извлеките bootstrap из проверенного архива и только затем допускайте переход к
root:
sha256sum --check SHA256SUMS
tar -xOf proxy-control-v0.1.0.tar.gz proxy-control/install-bootstrap > install-bootstrap
chmod 700 install-bootstrap
./install-bootstrap --archive proxy-control-v0.1.0.tar.gz --checksum SHA256SUMS --manifest release-manifest.jsonПорядок здесь важен. install-bootstrap сам отказывается работать от root и
перед единственным exec sudo проверяет, что каждый файл принадлежит вам и не
доступен на запись посторонним, что архив совпадает с опубликованной суммой,
что манифест называет тот же архив, что версия в манифесте не содержит
prerelease-суффикса и что внутри архива нет путей, выходящих за его пределы.
Проект принципиально не предлагает «скачать и сразу выполнить одной командой».
Отдельную команду запускать не нужно: проверив архив, install-bootstrap
передаёт управление установщику, и тот без аргументов открывает двуязычный
мастер. На выходе он пишет файл конфигурации — обычный TOML, который вы можете
прочитать и поправить руками.
Вот всё, о чём он спросит, по порядку.
Язык. Русский или английский.
Режим сервера. fresh — сервер ваш целиком, установщик сам поставит и
настроит Nginx. coexist — на сервере уже есть Nginx, который держит порт 443,
и установщик только допишет в него свои маршруты.
Профиль.
| Профиль | Что ставится |
|---|---|
core |
Telemt/MTProxy и панель |
core-naive |
То же плюс NaiveProxy |
core-mieru |
То же плюс Mieru |
full |
Всё вместе |
Режим 3x-ui.
none— 3x-ui не трогаем совсем;existing— принять уже установленный: установщик добавит маршруты для его доменов и не изменит ни одного его файла. Инбаунды в нём вы заводите сами;managed-new— поставить 3x-ui3.7.0самому. Установщик выпишет ему сертификаты, уведёт панель с публичных портов на127.0.0.1под приватный адрес, сменит заводскиеadmin/adminна ваши и сам заведёт инбаунды — VLESS Reality TCP, VLESS Reality XHTTP и Hysteria2. Требует режимаfresh: ставя 3x-ui, установщик берёт на себя и Nginx с сертификатами, а на сервере с уже настроенным Nginx у них есть свой владелец.
Домены. Мастер спрашивает только те, которые нужны выбранному профилю:
| Вопрос | Когда спрашивают | Куда идёт |
|---|---|---|
| Домен панели | всегда | панель Proxy Control |
| Fake-TLS домен MTProxy | всегда | MTProxy |
| Домен NaiveProxy | профили с Naive | NaiveProxy |
| Имя хоста Mieru | профили с Mieru | Mieru (сертификат не нужен) |
| TCP- и UDP-порты Mieru | профили с Mieru | слушатели Mieru |
| Домен панели 3x-ui | режимы existing и managed-new |
панель 3x-ui |
| Домен VLESS Reality TCP | там же | инбаунд VLESS Reality по TCP |
| Домен VLESS Reality XHTTP | там же | инбаунд VLESS Reality по XHTTP |
| Домен Hysteria2 | там же | инбаунд Hysteria2 |
| Домен subscription 3x-ui | В мастер не входит; добавьте subscription_domain в TOML режима managed-new |
выдача подписки 3x-ui по HTTPS |
WARP. В режиме managed-new мастер спрашивает, включать ли WARP для Xray,
а при ответе «да» требует непустой список доменных селекторов; NaiveProxy и
Mieru при таком выборе остаются на direct egress. В режимах 3x-ui none и
existing вопрос задаётся, если профиль включает NaiveProxy или Mieru: ответ
«да» направляет весь их трафик через WARP, а существующий 3x-ui не меняется.
Установщик сам ставит закреплённый официальный клиент Cloudflare и поднимает
принадлежащую Proxy Control точку SOCKS5 127.0.0.1:40000; заранее запущенный
WARP не нужен и, наоборот, считается чужим состоянием. В любом случае сначала
проверьте получившийся план.
Почта для сертификатов. Адрес для Let's Encrypt.
Учётные данные панелей.
- имя первого владельца панели Proxy Control и его пароль;
- имя и пароль панели 3x-ui — только в режиме
managed-new.
Пароль вводится дважды и на экране не отображается. Пустой ответ означает «придумай сам» — тогда установщик создаст случайный пароль, и вы прочитаете его после установки. Требование одно: не короче 12 символов.
Important
Пароли не попадают в файл конфигурации — он читается для построения плана,
план печатается на экран, из тех же значений собираются отчёты. Мастер кладёт
их рядом, в файл <имя-конфигурации>.credentials с правами 0600.
Удалите его сразу после установки. Установщик сам стирает свою рабочую
копию, как только установка завершится — успешно или нет.
Управление UFW. Только на чистом сервере: разрешить ли установщику самому открыть нужные порты в брандмауэре.
В конце мастер показывает всё, что вы ответили, и предлагает исправить любое поле, сохранить конфигурацию или продолжить установку.
Готовые примеры конфигураций лежат в
examples/installer/.
python3 -m installer.cli plan --config examples/installer/full-three-xui.toml --jsonПлан — это полный список того, что произойдёт: какие пакеты будут поставлены, какие файлы созданы, какие маршруты Nginx добавлены, какие сертификаты выписаны, какие службы запущены. Секретов в плане нет и быть не может.
У плана есть digest. Установка не начнётся, пока вы не подтвердите именно его:
sudo python3 -m installer.cli install --config examples/installer/full-three-xui.toml --accept-plan DIGESTЭто защита от «я не то запустил»: если сервер изменился между планом и установкой, digest не совпадёт и установка не пойдёт.
Установщик не считает работу выполненной по факту «контейнер запустился». Он проверяет каждый протокол настоящим клиентом:
- MTProxy — Fake-TLS, Obfuscated2,
req_pq_multiи проверенный ответresPQ; - NaiveProxy — сайт-прикрытие отвечает без пароля, затем аутентифицированный
CONNECT, известная нагрузка, закрытие туннеля и появление записи в учёте; - Mieru — точный статус
RUNNINGи официальный клиент, который реально выходит в интернет через каждый транспорт; - панель — вход, роли, создание и отзыв временного доступа;
- соседние маршруты — каждый чужой SNI продолжает работать.
Если любая проверка не прошла, установщик откатывает сделанное и возвращает сервер в прежнее состояние.
Берёт на себя: пакеты Ubuntu из списка, сертификаты и их продление, маршруты
Nginx и TLS-vhost панели, контейнеры и тома, host-службы NaiveProxy и Mieru,
правила UFW (если вы это разрешили), 3x-ui в выбранном режиме и собственный
закреплённый WARP-контур при warp = true.
Не берёт: DNS, Fleet, ваши собственные сайты, чужие контейнеры, чужой WARP и
чужие маршруты Nginx. Журнал и файлы владения лежат в /var/lib/proxy-control/ —
не удаляйте их руками.
Полная поверхность установщика — все команды, все поля конфигурации, границы владения, жёсткие остановки и восстановление — в справочнике установщика.
Если сертификаты, Nginx и всё окружение вы ведёте сами, базовый контур можно поднять напрямую через Compose: DOCKER_DEPLOYMENT.ru.md. Ручная установка host-служб описана в PANEL.ru.md (NaiveProxy) и MIERU.ru.md (Mieru).
Панель Proxy Control. Если вы задали пароль в мастере — входите с ним на
https://panel.example.com/login. Если оставили поле пустым, установщик создал
случайный пароль и положил его в
/opt/mtproxy-shared443/secrets/panel-bootstrap-password с режимом 0600:
прочитайте его через защищённую консоль, войдите и сразу смените.
Не копируйте этот файл в .env, Git, тикеты, журналы и общие резервные копии.
Панель 3x-ui (только в режиме managed-new). Она слушает не на публичном
порту, а на 127.0.0.1:8451, под приватным адресом вида /<случайные-символы>/
— заводские admin/admin больше не работают. Снаружи она доступна по своему
домену через общий 443, а адрес и учётные данные вы задали в мастере. Если не
задавали — установщик создал их сам, и посмотреть их можно в отчёте:
sudo python3 -m installer.cli status --jsonНе забудьте удалить файл <имя-конфигурации>.credentials, который написал
мастер: он больше не нужен.
Роли:
- owner — администраторы, пользователи, ротация доступов, реестр Fleet;
- admin — пользователи протоколов и аудит в разрешённых границах;
- viewer — только просмотр.
Последнего активного владельца нельзя удалить или понизить. Все изменения требуют CSRF и попадают в аудит — без паролей, токенов, ссылок и QR.
Доступы Naive и Mieru показываются один раз, с Cache-Control: no-store.
В списках пользователей секретов нет. Повторно показать существующий пароль
Mieru нельзя — есть только «Новая ссылка + QR», которая ротирует доступ и
отзывает старый.
Прокси для Telegram. Панель создаёт пользователей, выдаёт tg://-ссылки и QR,
ставит лимиты и срок действия.
После первого запуска источником истины становится том telemt-config: все
дальнейшие изменения идут через внутренний API и переживают пересоздание
контейнера. secrets/users.conf нужен только для первого импорта. Удаление
тома — это полный сброс: entrypoint снова импортирует исходный файл.
Квота и текущий счётчик процесса — разные величины. Ручной сброс квоты не обнуляет счётчик процесса, а аварийная остановка может потерять расход после последнего сохранения. Автоматического календарного сброса нет.
Подробности: DOCKER_DEPLOYMENT.ru.md.
Снаружи домен NaiveProxy выглядит обычным сайтом: запрос без пароля получает страницу-прикрытие, а не «407 Proxy Authentication Required». Прокси отвечает только тому, кто знает учётные данные.
Один и тот же доступ работает и как HTTPS (HTTP/1.1), и как HTTP/2 — панель
выдаёт URL вида https://<user>:<pass>@<домен>, а протокол выбирается при
TLS-рукопожатии. Клиентам, которые показывают «HTTPS» и «HTTP2» как разные
варианты, нужен один и тот же URL; отдельный доступ создавать не надо.
HTTP/3 наружу не опубликован: Nginx stream маршрутизирует по SNI только TCP и
не разбирает QUIC, а публичный UDP-порт проекту не выделяется. Приватный
слушатель Caddy держит HTTP/3 включённым, но добраться до него снаружи нельзя.
Учёт — это полезные байты завершённых туннелей, без накладных расходов TLS и IP. Квота на пользователя отключает доступ по достижении наблюдённого лимита, но это не побайтовый жёсткий лимит: активный туннель может дать перебор.
Подробности: PANEL.ru.md.
Обфусцированный прокси с собственным протоколом поверх TCP и UDP. Порт 443 он не занимает — вы явно выбираете порты и открываете их в облачном и локальном firewall.
Создание пользователя выдаёт одноразовую mierus://-ссылку, QR и команду
импорта. Ротация, отключение и удаление требуют контролируемого перезапуска,
чтобы доступ действительно был отозван.
Квота — приблизительная проверка допуска по прикладным байтам, а не платёжный
счётчик. Безопасного счётчика трафика на пользователя нет, поэтому интерфейс
может показывать unavailable — и это честный ответ, а не сбой.
Если мобильный путь теряет крупные сегменты обратного потока, есть опциональный
deploy/mieru-mss-clamp.service: он фиксирует измеренный TCP MSS только для
слушателя Mieru и не трогает посторонние правила firewall. Ставьте его только
после того, как увидели характерную картину Send-Q/retransmission/RTO.
При восстановлении всегда возвращайте journal.json вместе с исходным
journal.key. Не удаляйте и не генерируйте новый ключ, чтобы «починить» журнал.
Подробности: MIERU.ru.md и выдача доступов.
Отсюда приходят VLESS Reality (TCP и XHTTP) и Hysteria2. Возможны два пути.
Принять уже установленный (existing). Установщик только добавляет
маршруты для его доменов; файлы, база и unit 3x-ui остаются байт в байт
прежними — стенд проверяет это хешем до и после прогона. Инбаунды вы заводите
сами, и они должны слушать на loopback, иначе делить порт 443 будет нечем.
Поставить самому (managed-new). Установщик разворачивает 3x-ui 3.7.0 и
доводит его до рабочего состояния без единого действия руками:
- уводит панель с публичных
*:2053и*:2096на127.0.0.1:8451под приватный адрес; - меняет заводские
admin/adminна ваши учётные данные, причём делает это в изолированном сетевом пространстве — панель ни секунды не доступна снаружи с известным паролем; - создаёт три инбаунда: VLESS Reality TCP (
127.0.0.1:8449), VLESS Reality XHTTP (127.0.0.1:8450) и Hysteria2 (0.0.0.0:443/UDP); - проверяет закреплённую версию, приватный listener панели и наличие listener каждого созданного инбаунда. Это проверка того, что Xray принял конфигурацию, а не полноценная клиентская приёмка VLESS/Hysteria2.
Ключи Reality создаёт тот самый Xray, который потом их и обслуживает, а прикрытием служит локальный TLS-сайт панели: чужой сайт может сменить сертификат или исчезнуть, и тогда Reality разом отваливается у всех клиентов.
Note
Подписка 3x-ui публикуется только когда в TOML режима managed-new задан
отдельный subscription_domain. Установщик выпускает для него сертификат,
направляет этот SNI через общий TCP/443 на loopback-listener 127.0.0.1:2096
и сохраняет URL подписки в root-only состоянии. Записи внутри подписки
содержат публичные имена протоколов и порт 443, а не приватные backend-порты.
Без subscription_domain подписка наружу не публикуется.
Обновление уже установленного 3x-ui подготовлено в адаптере отдельной транзакцией, но отдельной команды для него пока нет — обновляйте его штатными средствами самого 3x-ui.
3x-ui остаётся отдельной панелью со своим интерфейсом — Proxy Control не дублирует его управление, а следит, чтобы вы оба жили на одном 443 без конфликтов.
Необязательный контур: инвентаризация и ограниченное управление удалёнными узлами через исходящие соединения. Установщик его не разворачивает.
Запись узла в панели со статусом unenrolled — это ещё не регистрация. Нужны
локальный ключ и CSR на узле, подпись offline-CA, привязка сертификата в центре,
mTLS-авторизация и успешная команда инвентаризации.
Fleet v1 работает только с Telemt: разрешены обновление инвентаря, включение, отключение, изменение лимитов и сброс квоты. Операции Mieru, удалённые create/delete/rotate/reveal и передача secret-bearing конфигурации отклоняются.
Полная процедура: FLEET.ru.md.
WARP — одна loopback-точка SOCKS5 на 127.0.0.1:40000 по умолчанию.
При warp = true установщик сам загружает официальный клиент Cloudflare
закреплённой версии, проверяет SHA-256, регистрирует его, включает warp-svc
и настраивает proxy mode. Это внешняя проприетарная зависимость: клиент не
входит в MIT-лицензию проекта и не включён в релизный архив.
Параметры находятся в [three_xui]; warp_port по умолчанию равен 40000
и передаётся всем потребителям. Явно заданный другой порт сохраняется.
Существующий чужой WARP не присваивается и не перенастраивается: установка
останавливается с требованием отдельной миграции.
| Протокол | Что уходит через WARP |
|---|---|
| Xray / управляемый 3x-ui | Домены из warp_domains; правило добавляется после блокирующих. Маршрутизация принятого экземпляра (existing) не изменяется. |
| NaiveProxy | При пустом warp_domains — весь туннелируемый трафик через upstream socks5://127.0.0.1:40000. При заданных селекторах остаётся direct. |
| Mieru | При пустом warp_domains — всё egress-соединение через WARP; при заданных селекторах остаётся DIRECT. |
При warp = false WARP не устанавливается. Приёмка включённого WARP требует
полностью установленный пакет, активную службу с автозапуском, принадлежащий
warp-svc loopback-порт и реальный HTTPS-запрос через SOCKS5: warp=on/plus
и внешний IP, отличный от прямого выхода. Открытый порт сам по себе не считается
успехом. Повреждённое владение блокирует изменения; прерванные операции
продолжаются через resume, восстановление остановленной службы — через repair.
cd /opt/mtproxy-shared443
docker compose ps
curl -fsS -H 'Host: panel.example.com' http://127.0.0.1:8787/healthz
sudo nginx -t
ss -lntup
systemctl is-active nginx docker
systemctl is-active caddy-naive mitaЗаголовок Host обязателен: панель принимает только своё публичное имя, и
запрос с Host: 127.0.0.1 она отклонит. Ожидается {"status":"ok"}.
Перед тем как кому-то показать этот вывод, уберите пароли, полные URL доступа, QR, токены, cookies, сертификаты и закрытые ключи.
| Контур | Полная генерация |
|---|---|
| Панель | SQLite через online backup либо база вместе с -wal/-shm при остановленном writer |
| Telemt | Том telemt-config, secrets/users.conf, API-токен и точная версия образа |
| Naive | Весь каталог данных, Caddyfile, users.json, парные backups, transaction.json, база учёта с WAL/SHM, бинарник, unit и права логов |
| Mieru | Каталог состояния, journal.json вместе с исходным journal.key, backups, токен, бинарник, unit и конфигурация mita |
| Fleet | База панели и конфигурация ingress; ключ offline-CA хранится отдельно |
| Nginx | Конфигурации stream/http, сертификаты, владельцы, режимы и manifest владения |
| Развёртывание | Git revision, полный COMPOSE_FILE, digest образов, версии бинарников и unit-файлы |
Безопасная онлайн-копия базы панели:
docker exec -i proxy-control-panel python - <<'PY'
import sqlite3
src = sqlite3.connect('/data/panel.sqlite3')
dst = sqlite3.connect('/data/panel.backup.sqlite3')
with dst:
src.backup(dst)
print(dst.execute('PRAGMA integrity_check').fetchone()[0])
dst.close(); src.close()
PYОжидается ровно ok. Не копируйте один файл SQLite при работающем WAL-писателе.
Подробности: резервное копирование и восстановление.
Панель умеет безопасно обновлять три контура — Telemt, NaiveProxy/Caddy
и Mieru/mita — через отдельную root-службу version-agent. Сама панель не
получает Docker socket, не скачивает бинарники и не принимает URL из браузера.
Обновляются только версии из root-owned каталога, который заполняете вы. Агент
проверяет SHA-256, подменяет бинарник атомарно, перезапускает только нужную
службу и при ошибке возвращает предыдущую версию. Операция доступна только роли
owner и требует указать текущую версию.
Полный протокол и откат: docs/UPGRADING.md.
sudo python3 -m installer.cli status --json
sudo python3 -m installer.cli resume --json
sudo python3 -m installer.cli repair --jsonresume продолжает прерванную установку с сохранённой фазы. repair проверяет,
что всё принадлежащее установщику на месте и не изменено чужими руками, и
перезапускает только свои службы.
Не удаляйте journal.json, journal.key, transaction.json, файлы WAL/SHM и
backups, чтобы «починить» запуск. Если сомневаетесь — восстанавливайте всю
предыдущую генерацию, а не один файл.
sudo python3 -m installer.cli uninstall --jsonУдаление останавливает Compose, убирает только принадлежащие установщику
маршруты, файлы и пакеты, а секреты, сертификаты и каталоги сайтов-прикрытий
сохраняет до отдельной проверки владельца. После удаления проверьте nginx -t,
публичные слушатели и соседние SNI.
Если SSH оборвался с кодом 255 — это говорит только об обрыве связи. Сначала
посмотрите status, фазу, службы и Nginx; не запускайте установку повторно
вслепую.
- Панель не открывается. Проверьте
127.0.0.1:8787,PANEL_ALLOWED_HOSTS,PANEL_COOKIE_SECURE, TLS-vhost на8443, базу SQLite и владельца тома. - MTProxy здоров, но клиент не подключается. Проверьте A/AAAA, отсутствие
CDN перед raw TCP, карту SNI, имя Fake-TLS, каждый секрет и настоящий
resPQ. Здоровый контейнер и открытый порт сами по себе ничего не доказывают. - Naive manager нездоров. Проверьте токен, Unix-сокет, зафиксированную
сборку Caddy,
caddy adapt --validate,transaction.jsonи идентификаторы10002:101и10003:10004. - Учёт Naive не растёт. Запись появляется только после успешно закрытого
CONNECT; активный или оборванный туннель ещё ничего не даёт. - Mieru manager нездоров. Проверьте точный digest и версию
mita,/run/mita/mita.sock, GID сокета, метаданные токена и состояния. Не применяйте рекурсивныйchownвслепую. - Нет QR старого пользователя Mieru. Так и задумано: выдача одноразовая. Используйте «Новая ссылка + QR», понимая, что старая конфигурация будет отозвана.
- Появились orphan-контейнеры. Восстановите полный сохранённый
COMPOSE_FILE; не подтверждайте удаление orphan-контейнеров неполной моделью. - Fleet остаётся
unenrolled. Запись в реестре — не регистрация. Повторите CSR, offline-подпись, привязку сертификата, установку на узел, авторизацию mTLS и инвентаризацию.
Больше случаев: устранение проблем и операционный runbook.
Адаптер packages ставит ровно эти пакеты и никакие другие:
ca-certificates, certbot, curl, docker-compose-v2, docker.io,
nginx-full, openssl, python3.
Их публикуют другие проекты под собственными лицензиями. Установщик никогда не скачивает их за вас: вы размещаете пакет сами, и установщик отказывается продолжать, если digest не совпадает с пином.
| Артефакт | Версия | Лицензия | Назначение |
|---|---|---|---|
mita (enfein/mieru) |
3.36.0 | GPL-3.0-or-later | Сервер Mieru. Устанавливается только исполняемый файл и уведомление о лицензии; сам пакет — никогда. |
mieru (enfein/mieru) |
3.36.0 | GPL-3.0-or-later | Официальный клиент Mieru: из него собирается образ приёмки, который доказывает, что каждый транспорт реально пропускает трафик. |
three_xui (MHSanaei/3x-ui) |
3.7.0 | GPL-3.0-only | Панель 3x-ui и её ядро Xray для VLESS Reality TCP, VLESS Reality XHTTP и Hysteria2. |
Caddy v2.11.4 с модулем http.handlers.forward_proxy не скачивается
бинарником, а собирается по зафиксированному рецепту
docker/Dockerfile.caddy-naive. Все URL, digest и идентификаторы SPDX лежат в
release/external-artifacts.json, который
сборка релиза встраивает в SBOM.
| Dockerfile | Образ | База |
|---|---|---|
panel/Dockerfile |
API и интерфейс панели | python:3.13.5-slim |
naive_manager/Dockerfile |
Менеджер доступов и учёта NaiveProxy | python:3.13.5-slim |
mieru_manager/Dockerfile |
Менеджер доступов и квот Mieru | python:3.13.5-slim |
deploy/Dockerfile.agent |
Агент узла Fleet | python:3.13.5-slim |
deploy/Dockerfile.ingress |
mTLS-ingress Fleet | python:3.13.5-slim |
deploy/mieru-client/Dockerfile |
Официальный клиент Mieru для приёмки | python:3.13.5-slim |
probe/Dockerfile |
Приёмочная проба MTProto на TDLib | node |
docker/Dockerfile.caddy-naive |
Сборка Caddy с forward_proxy |
caddy:2.11.4-builder → scratch |
scripts/lab/Dockerfile.acceptance |
Одноразовый systemd-контейнер стенда | ubuntu |
Каждая база зафиксирована по digest.
Рантайм (panel/requirements.txt): fastapi, starlette, pydantic,
pydantic_core, annotated-types, typing-inspection, typing_extensions,
httpx, httpcore, h11, certifi, idna, anyio, Jinja2, MarkupSafe,
argon2-cffi, argon2-cffi-bindings, cffi, pycparser, uvicorn, click,
qrcode.
Только для разработки (panel/requirements-dev.txt): pytest, pytest-anyio,
iniconfig, packaging, pluggy, Pygments, ruff.
Все версии пинованы точно. Сам установщик и оба менеджера используют только стандартную библиотеку Python.
- Не публикуйте
.env,secrets/, URL доступа, QR, токены, базы, журналы и ключи PKI. - Не публикуйте наружу Telemt API, управляющие Unix-сокеты и Caddy Admin API.
- Не подключайте Docker socket к службам проекта.
- Не меняйте зафиксированные Telemt, Caddy или
mitaбез проверки происхождения, digest и плана отката. - Скрытая кнопка в интерфейсе не заменяет серверную проверку роли.
- Перед боевым развёртыванием прочитайте SECURITY.md и политику совместимости.
python3 -m venv .venv
.venv/bin/python -m pip install -r panel/requirements-dev.txt
.venv/bin/ruff check .
.venv/bin/python -m pytest -q
python3 scripts/check-doc-links.py
git ls-files -z '*.sh' | xargs -0 -r -n1 bash -n
git ls-files -z '*.sh' | xargs -0 -r shellcheck
git diff --checkУстановщик проверяется на настоящем релизном архиве в двух стендах — описание в tests/lab/README.md. Режим, который ставит 3x-ui сам, проверяется отдельно, на одноразовом сервере с настоящим 3x-ui:
sudo bash scripts/lab/managed-xui-acceptance.shПрогон отказывается работать там, где 3x-ui уже стоит, и убирает за собой;
KEEP=1 оставляет поднятую панель, чтобы разобраться в случившемся.
Правила участия — в CONTRIBUTING.md. Обязательный рабочий протокол для AI-агентов — в AGENTS.md.
Вся документация по отдельным границам: карта документации, установка, справочник установщика, полный installer/auditor, панель, MTProto за Nginx, Mieru, выдача Mieru, Fleet, эксплуатация, резервное копирование, обновление, устранение проблем, учёт трафика и проверки.
Подтверждены тесты Python, проверки качества, рендеринг Compose-конфигураций, сборка образов, панели MTProxy/NaiveProxy/Mieru и адаптивный интерфейс.
Полный цикл релиза — установка, повторная установка, repair, восстановление
после перезагрузки, прерванная фаза, отчёт, удаление и сосуществование на общем
443 — прогоняется на настоящем архиве релиза в двух стендах: одноразовый
systemd-контейнер и одноразовый сервер на голом железе. Приёмка каждого
протокола выполняется реальными клиентами.
Подтверждены также public contract subscription 3x-ui (только публичные SNI на
443), живой lifecycle WARP с реальным egress и rollback, а также режим
managed-new на настоящем 3x-ui 3.7.0: установщик создаёт VLESS Reality TCP,
VLESS Reality XHTTP и Hysteria2 и выпускает SSL-сертификаты для панели 3x-ui,
Hysteria2 и отдельной subscription.
Не заявляются как завершённые: регистрация Fleet в боевой среде и бухгалтерская точность учёта трафика.
Proxy Control опирается на работу авторов и сопровождающих upstream-проектов:
| Компонент | За что благодарим | Ссылка |
|---|---|---|
| Telemt | MTProto/MTProxy runtime на Rust | telemt/telemt |
| Mieru и mita | TCP/UDP proxy runtime и manager | enfein/mieru |
| 3x-ui | Xray/3x-ui control plane | MHSanaei/3x-ui |
| Caddy | HTTPS reverse proxy и TLS automation | caddyserver/caddy |
| forwardproxy | HTTP CONNECT module для Caddy | klzgrad/forwardproxy |
| Nginx | shared-443 SNI routing | nginx.org |
| Certbot и Let's Encrypt | ACME HTTP-01 и выпуск/продление сертификатов | Certbot · Let's Encrypt |
| Docker и Compose | изолированное выполнение сервисов | Docker · Compose |
| Python web stack | FastAPI, Starlette, Pydantic, HTTPX, Uvicorn, Argon2, cryptography и qrcode | requirements |
Спасибо всем разработчикам, мейнтейнерам и участникам этих проектов. Точные
версии, лицензии, provenance и отдельные notices приведены в
THIRD_PARTY_NOTICES.md,
release/external-artifacts.json и файлах
panel/requirements*.txt.
Код репозитория распространяется по лицензии MIT; внешние компоненты сохраняют собственные лицензии.
