# Upstream Changes ## UserManager — External Authentication & Traffic Tracking A new `user_manager` service that turns sing-box into a universal proxy server for external auth servers. ### New files - `adapter/user_manager.go` — `UserManager` interface: `Authenticate`, `GetCredentials`, `ReportTraffic`, `GetTraffic`, `ListTraffic`, `KickUser` - `option/user_manager.go` — `UserManagerOptions`: `auth_server`, `cache_ttl`, `refresh_interval`, `report_interval`, `report_traffic`, `api_secret`, `api_listen`, `timeout` - `service/usermanager/manager.go` — full implementation: - On-demand HTTPS auth (`POST /api/auth`) with in-memory TTL cache - Periodic credential sync (`GET /api/credentials`) populates per-protocol user lists - Per-user traffic counters (`atomic.Int64`) reported via `POST /api/traffic` - `ConnectionTracker` impl wrapping conns with byte counters (`RoutedConnection`/`RoutedPacketConnection`) - HTTP API on configurable `api_listen`: - `GET /traffic` — all users traffic - `GET /traffic/{user}` — single user - `POST /kick/{user}` — evict user from auth cache - Bearer token auth on all API endpoints via `api_secret` - `service/usermanager/registry.go` — service registration - `include/usermanager.go` — include build hook - `constant/proxy.go` — `TypeUserManager` constant ### Modified files — Protocol inbound integration All 10 protocol inbounds detect the global `user_manager` from service context and use it when present: | Protocol | Type | Approach | |----------|------|----------| | hysteria2 | Service-based | `service.UpdateUsers` with password credentials, 30s refresh loop | | tuic | Service-based | `service.UpdateUsers` with UUID+password (format `"uuid:password"`), 30s refresh loop | | vless | Service-based | `service.UpdateUsers` with UUID credentials, 30s refresh loop | | vmess | Service-based | `service.UpdateUsers` with UUID credentials, 30s refresh loop | | trojan | Service-based | `service.UpdateUsers` with password credentials, 30s refresh loop | | shadowsocks (multi) | Service-based | `service.UpdateUsersWithPasswords` with password credentials, 30s refresh loop | | http | Authenticator-based | `*auth.Authenticator` rebuilt from `GetCredentials`, 30s refresh loop | | socks | Authenticator-based | `*auth.Authenticator` rebuilt from `GetCredentials`, 30s refresh loop | | mixed | Authenticator-based | `*auth.Authenticator` rebuilt from `GetCredentials`, 30s refresh loop | | naive | Authenticator-based | `*auth.Authenticator` rebuilt from `GetCredentials`, 30s refresh loop; skips `"missing users"` check when user_manager is configured | Each inbound falls back to its original static config when no `user_manager` service is registered. ### Credential format per protocol | Protocol | `UserInfo.Credential` format | |------------|------------------------------| | hysteria2 | password | | tuic | `uuid:password` | | vless | uuid | | vmess | uuid | | trojan | password | | shadowsocks| password (method from static config) | | http | password (username from `UserInfo.Username`) | | socks | password (username from `UserInfo.Username`) | | mixed | password (username from `UserInfo.Username`) | | naive | password (username from `UserInfo.Username`) | ### Auth server API contract The auth server (`auth_server`) must implement: - `POST /api/auth` — body `{"protocol":"...", "credential":"...", "addr":"..."}`, returns `{"ok":true, "id":"username"}` - `GET /api/credentials` — returns `{"credentials":[{"protocol":"...", "credential":"...", "username":"..."}]}` - `POST /api/traffic` (optional, when `report_traffic=true`) — body `{"traffic":{"user1":{"tx":123,"rx":456}}}`