Skip to content

About

Build, deploy, and distribute sing-box with an authenticated portal and cross-platform clients

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

72 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sing-box-manager

Checked on 2026-10-22.

Deploy, package and distribute sing-box.

The primary deployment target is a single VPS that runs:

  • one sing-box.service with Trojan, Hysteria2 and optional Naive and Snell v6 inbounds
  • the authenticated download portal behind nginx
  • certbot-nginx for CA-signed certificates

One Django/PostgreSQL service provides the portal and control plane. It manages operators, proxy accounts (Account), and protocol credentials (Credential). Users open their subscription pages. Operators manage accounts and traffic through SSH-tunnelled Django Admin. There is no separate public password-login portal. See the control-plane guide for enablement and recovery.

Public source and private operations

The public GitHub repository is xiaosq2000/sing-box-manager; the Go module uses the matching path. The project and its commands remain sing-box-manager, sbm, and sbc.

This repository contains code, example configuration, and synthetic test fixtures. It does not include a runtime inventory or generated releases. Keep deployment inventory, credentials, TLS keys, signing keys, and user data in an operator-owned location or a separate private repository. See secret handling and contributing before adding configuration or test data.

CI uses standard GitHub-hosted runners on Linux, macOS, and Windows. Do not route untrusted public pull requests to a persistent self-hosted runner.

Setup

The build and deploy environment targets Linux x86-64. Install Pixi and run commands from the repository root.

The code-built configurations target sing-box 1.14.3. Pixi provides Python 3.12 and Go 1.25.5 or later in the 1.25 series for custom server builds and the sbc client.

pixi install

Copy .sops.example.yaml to the ignored .sops.yaml and set your own public Age recipient. Create or edit your encrypted inventory using the secret-handling guide. Copying the example to a .sops.yaml filename does not encrypt it. For local development, use a plaintext .yaml outside the checkout and pass its path with --config.

This repo tracks bundled font files with Git LFS. If your clone was created on a host that does not already have Git LFS configured, run this once per checkout before starting the app or building releases:

git lfs install --local
git lfs pull

git lfs install --local stores the filter configuration in .git/config instead of your user-level ~/.gitconfig.

This applies to the machine you build and deploy from. The server needs neither git nor Git LFS: sbm deploy ships the real font bytes over rsync, and refuses to start if this clone still holds LFS pointer stubs.

Configuration

See config/inventory/example.yaml for the full config shape. Select infrastructure settings and legacy inventory with --config <path> or SBM_CONFIG. In authoritative mode, PostgreSQL owns proxy accounts and credentials. Manage them in Django Admin, not in the inventory.

deployment.client_region optionally sets the time zone and language clients present for the node; see the client guide. Clients opt in with sbc privacy region on for one account or sbc privacy region on --system for the whole machine. sbc privacy browser language on separately matches Linux Chrome's language preferences without changing the system locale. See Chrome language matching. sbc privacy browser geolocation on separately blocks website location requests with a system-wide Linux Chrome policy. IP-based location estimates remain possible. See geolocation blocking.

On native Linux, sbc tun on runs a root-owned TUN service instead of mixed mode. It needs systemd, /dev/net/tun, and sudo, and it refuses remote SSH sessions. sbc route and sbc protocol control active TUN without restarting capture. sbc ip, sbc check, and sbc speed download diagnose the active mixed or TUN path without changing selections. See network diagnostics.

sbm serve runs Django on loopback at control_plane.port (default 47071). It requires control_plane.enabled and control_plane.secret_key. Retain web.session_secret for installed legacy clients' machine tokens. See server configuration.

web.subscription_secret keys the subscription links the sbc client fetches its config from. Without it, sbm serve turns those links off.

The Trojan, Hysteria2, Naive and Snell renderers build configurations in code and keep real deployment secrets in an operator-owned encrypted runtime inventory. See docs/SECRET_HANDLING.md before editing any user credentials, obfs secrets, or TLS values.

default_protocol controls the initial protocol for new client installs and mobile profile imports. When omitted, it prefers Snell if its infrastructure is configured, or Trojan otherwise. An explicit value overrides this default. Explicit Snell requires both deployment.snell_port and snell.psk. Subscriptions use the account's first enabled protocol when it lacks the configured default. This is not connection-failure fallback. Install parameters and saved client selections take precedence. Saved choices survive refresh, upgrade and restart. A client without a saved choice follows the new default, even if it is already installed.

The server installer enables all packaged protocol inbounds by default. A Naive inbound is omitted when its roster is empty or entirely disabled.

Snell v6 uses deployment.snell_port, a shared snell.psk, and independent PostgreSQL userkeys. No enabled users means no Snell listener. It supports all existing client platforms without changing routing rules. See Snell setup and acceptance, including the explicit existing-account backfill and device-test limits.

If traffic_stats.enabled is turned on in the config file, sbm release builds a custom Linux server sing-box binary from the upstream source tag with with_v2ray_api, while client download archives continue using the official upstream release assets.

Desktop and mobile profiles offer china-direct (the default), gfw-proxy, ai-only, global, and direct routes. china-direct proxies unknown destinations. gfw-proxy proxies GFWList and AI destinations and sends other traffic directly. direct sends all allowed application traffic and its DNS directly, including AI. Desktop configs retain china, gfw, and ai as aliases. Mobile shows only the five canonical names. See the CLI guide for route descriptions and diagnostics. Every client profile keeps the exact deployment.host and optional deployment.direct_domain_suffixes direct, with matching direct DNS rules. Suffixes cover the apex and subdomains.

Desktop and mobile proxy strategies send community-listed Anthropic and AI traffic through the proxy before China-direct rules. direct sends these connections and their DNS directly. The dedicated Anthropic set and broader AI set replace local domain maintenance. See community AI rules for sources and coverage limits.

iOS and Android use one unified remote profile with all enabled account protocols behind a selector. The portal provides one import button and QR code. Per-protocol mobile URLs are not supported. Reimport from the subscription page. Mobile DNS returns real answers, without FakeIP. See the mobile guide for migration and device acceptance.

The sbc downloads include initial rule files, so the proxy can start before rule downloads succeed. DNS answers persist across service restarts, with normal DNS expiry. See the release guide for build requirements.

sbc enables automatic configuration refresh and signed binary upgrades by default, with separate 6h intervals. Active Linux TUN only checks and reports updates. Manual sbc refresh or sbc upgrade republishes TUN under its current policy. Use sbc refresh auto off or sbc upgrade auto off to disable either policy. See automatic maintenance for intervals, saved preferences, and migration from older clients.

sbc lang saves the language of sbc messages as en, zh, or auto; SBC_LANG overrides it. See CLI language.

sbm release can also read a repo-root .env for local operator secrets such as SOPS_AGE_KEY and GITHUB_TOKEN; the secret-handling doc covers the tradeoffs.

sbm release uses the current files in config/ as-is; it does not pin, reset, or check out config state with git.

Docs

Common Commands

Every sbm operation requires --config <path> or exported SBM_CONFIG. Put the global --config option before the subcommand. --help works without a config. Use the same inventory for a release build and its deploy. When the control plane is enabled, deployment installs /usr/local/bin/sbm on the VPS. This wrapper sets SBM_CONFIG to the deployed runtime inventory if unset, changes to the deployment root, and disables Python bytecode writes. An explicit --config still overrides SBM_CONFIG.

Build release artifacts:

pixi run sbm --config config/inventory/runtime.sops.yaml release

Start Django after database migration and static-file collection:

pixi run sbm --config config/inventory/runtime.sops.yaml serve

Collect per-user traffic stats from the local sing-box node service:

pixi run sbm --config config/inventory/runtime.sops.yaml stats-collect

Collect the per-domain breakdown. This subscribes to the sing-box 1.14.0 API service and runs until stopped, because sing-box drops connection events while nobody is listening:

pixi run sbm --config config/inventory/runtime.sops.yaml stats-stream

Django operators with control_plane.view_traffic can open /admin/traffic/ and /admin/traffic/connections/ through an SSH tunnel. This permission does not permit account edits. The legacy inventory admin flag grants no Django permissions.

After building a release, deploy to a fresh VPS. Replace vpn-host with your SSH host alias:

pixi run sbm --config config/inventory/runtime.sops.yaml deploy --hostname vpn-host --bootstrap

Deploy subsequent releases to an already-provisioned host:

pixi run sbm --config config/inventory/runtime.sops.yaml deploy --hostname vpn-host

Deploy uses rsync over SSH, and Pixi provides the local rsync binary. It ships the code and existing release; it does not build a release. See the deploy options for protocol selection, custom paths, bootstrap email, and dry runs.

Manage the control plane on the VPS after deployment:

sudo -u sbm sbm control-plane migrate
sudo -u sbm sbm control-plane createsuperuser
# Initial import only, before enabling authoritative mode:
sudo -u sbm sbm control-plane import
sudo sbm control-plane sync

For import restrictions, account switches, and deployment modes, see the control-plane guide.

The full action names create-admin, import-inventory, and sync-node also work. Other actions are collect-static, serve, health, check, and backfill-snell. Only backfill-snell accepts --dry-run. Omitting the action runs check. Existing control-plane --action ACTION commands remain supported. Use one action form per command.

From a workstation, both concise and full action names support remote execution:

pixi run sbm --config /path/to/runtime.sops.yaml control-plane sync --remote vpn-host --remote-root /opt/sing-box-manager

See the control-plane guide for permissions and recovery.

Development

pixi install
pixi run test tests/test_cli.py

See DEVELOPMENT.md for checks appropriate to the change.

About

Build, deploy, and distribute sing-box with an authenticated portal and cross-platform clients

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages