Пользователи входящих на лету
Пользователей входящего из раздела listeners: можно менять, пока он работает: слушатель не пересоздаётся, конфиг не перезагружается, соединения остальных пользователей не рвутся.
- Добавленный пользователь подключается сразу.
- У удалённого пользователя закрываются все установленные соединения (вместе с mux-подпотоками и UDP-сессиями), новые подключения отклоняются, его счётчик трафика удаляется, когда байты забраны.
- Смена секрета (или flow у VLESS) закрывает соединения пользователя, открытые со старым секретом; старый секрет больше не принимается.
- Пользователи, запись которых не менялась, ничего не замечают.
Обновление атомарно: рукопожатие видит либо старый набор пользователей, либо новый, и соединение, которое прошло проверку старым ключом за мгновение до смены, тоже будет закрыто.
Какие входящие поддерживают
Заголовок раздела «Какие входящие поддерживают»| Тип | name |
secret |
flow |
|---|---|---|---|
vless |
username | UUID | xtls-rprx-vision или пусто |
trojan |
username | пароль | — |
anytls |
имя пользователя | пароль | — |
trusttunnel |
username | пароль | — |
tuic (v5) |
UUID пользователя | пароль | — |
shadowsocks |
name | ключ пользователя (uPSK) | — |
socks, http, mixed |
username | пароль | — |
Ограничения:
shadowsocks— только многопользовательский режим (2022-blake3-aes-*сusersв конфиге). Ключи проверяются так же, как в конфиге. При смене пользователей UDP-сессии всех пользователей начинаются заново (клиент видит новую сессию сервера) — клиенты Shadowsocks 2022 это переживают.socks,http,mixed— только если у входящего своиusersв конфиге. Безusersдействует глобальнаяauthentication, аusers: []отключает проверку — менять там нечего. Пустой список пользователей, заданный через API, никого не пускает (а не отключает проверку).- Глобальная
authenticationменяется перезагрузкой конфига — так же для входящихsocks,httpиmixed, которые её используют (и для слушателейsocks-port,port,mixed-port): соединения удалённого пользователя или пользователя со сменённым паролем закрываются, а включение проверки закрывает соединения, пущенные без неё. Если пароль пользователя не менялся, его соединения остаются. tuic— имена хранятся как UUID в нижнем регистре (так их видитIN-USER).hysteria2,mieru,shadowquicи остальные пока не поддерживают: их библиотеки меняют таблицу пользователей без синхронизации или вовсе не умеют её менять. Для них API отвечает409.
Правила для пользователей
Заголовок раздела «Правила для пользователей»Через API у каждого пользователя должно быть непустое уникальное имя и непустой уникальный секрет; иначе — 400, и ничего не меняется. Конфиг по-прежнему допускает пользователей без имени, кроме socks, http, mixed и глобальной authentication: там пустое имя — ошибка конфига, потому что пустое имя для IN-USER, лимитов пользователей и закрытия сессий означает «нет пользователя».
Запросы идут к external-controller с тем же secret, что и остальной API. {name} — имя входящего из listeners:.
| Запрос | Что делает |
|---|---|
GET /inbounds/{name}/users |
Список пользователей: имена и flow, без секретов. |
PUT /inbounds/{name}/users |
Заменить всех: {"users": [{"name": "…", "secret": "…", "flow": "…"}]}. |
POST /inbounds/{name}/users |
Добавить одного: {"name": "…", "secret": "…"}. Ответ 201. |
PATCH /inbounds/{name}/users/{user} |
Сменить секрет и/или flow: {"secret": "…"}. Соединения пользователя закрываются. |
DELETE /inbounds/{name}/users/{user} |
Удалить пользователя и закрыть его соединения. |
Коды: 404 — нет такого входящего или пользователя; 400 — неверные данные (пустое или повторное имя, повторный секрет, неверный ключ или flow); 409 — входящий не умеет менять пользователей на лету, в сообщении указан его тип.
curl -X POST -H "Authorization: Bearer $SECRET" \ -d '{"name":"bob","secret":"b0b0b0b0-0000-4000-8000-000000000000"}' \ http://127.0.0.1:9090/inbounds/vless-in/users
curl -X DELETE -H "Authorization: Bearer $SECRET" \ http://127.0.0.1:9090/inbounds/vless-in/users/alice{ "inbound": "vless-in", "type": "vless", "users": [{ "name": "bob" }] }Перезагрузка конфига
Заголовок раздела «Перезагрузка конфига»Изменения живут в памяти. Источник правды — конфиг: следующая перезагрузка (PUT /configs, перезапуск) снова ставит пользователей из конфига. Панель, которая управляет пользователями через API, хранит свой список и пишет его в конфиг, который применяет.
Перезагрузка тоже стала бережнее: если у входящего в новом конфиге изменились только пользователи, а остальное совпадает, слушатель не пересоздаётся — ему на месте ставятся пользователи из конфига, и рвутся только соединения удалённых и сменивших ключ пользователей. Если конфиг входящего не изменился, но пользователи меняли через API, перезагрузка возвращает пользователей конфига тем же способом. Если поменялось что-то кроме пользователей (порт, TLS, транспорт…), входящий пересоздаётся, как раньше.
Для встраивания ядра, пакет github.com/metacubex/mihomo/listener:
users, err := listener.InboundUsers("vless-in") // []constant.InboundUser, с секретамиerr = listener.SetInboundUsers("vless-in", users) // заменить всехerr = listener.AddInboundUser("vless-in", constant.InboundUser{Name: "bob", Secret: uuid})err = listener.RemoveInboundUser("vless-in", "alice")err = listener.ModifyInboundUser("vless-in", "bob", func(u *constant.InboundUser) error { u.Secret = newUUID return nil})Ошибки: listener.ErrInboundNotFound, listener.ErrInboundUserNotFound, listener.ErrInboundUserExists, constant.ErrInvalidInboundUser, constant.ErrInboundUsersUnsupported (проверяются через errors.Is). Слушатель, который поддерживает обновление, реализует constant.InboundUserUpdater.
