| name | sing-box-ubuntu-setup |
| description | Configures sing-box on Ubuntu for split-routing of system traffic through a TUN interface. Use when the user wants selective proxying (some apps through VPN, others direct), automatic failover between multiple VPN servers, DNS leak prevention, and global mode switching via Clash API. |
sing-box Ubuntu Setup
Context & Purpose
Use this skill when an agent needs to install, configure, or troubleshoot a sing-box deployment on Ubuntu that:
- Captures all system traffic through a TUN interface (not per-app proxies).
- Routes some domains and CIDR ranges through one or more VPN outbounds and the rest directly.
- Uses curated geosite and geoip lists to decide the route for each connection.
- Has automatic failover between multiple VPN servers.
- Exposes a "panic button" to force all traffic direct when every VPN server is down.
- Coexists with other network-namespaced tools (Tailscale, WireGuard, Docker).
The skill assumes the user already has one or more VPN outbounds (VLESS, VMess, Trojan, Shadowsocks, Hysteria2, WireGuard, etc.) supplied by their own server. The skill does not provide VPN credentials.
Target Directory Architecture
./skills/sing-box-ubuntu-setup/
├── SKILL.md # Router (this file)
├── README.md # Public-facing overview
├── references/
│ ├── architecture.md # Runtime model, TUN lifecycle, IP rule coexistence
│ ├── initialization.md # Install, directories, first config, systemd unit
│ ├── migration.md # sing-box 1.11 → 1.12 → 1.13 breaking changes
│ ├── recipes/
│ │ ├── setup-split-routing.md # rule_set + .srs files + route ordering
│ │ ├── configure-split-dns.md # direct-dns + proxy-dns + dns.rules
│ │ ├── add-failover-and-panic-button.md # urltest outbound + clash_mode
│ │ ├── keep-tailscale-working.md # IP rule priority + fwmark coexistence
│ │ ├── preset-global-proxy.md # The reference deployment in one file
│ │ ├── schedule-rule-updates.md # cron job for .srs refresh
│ │ └── verify-routing-decisions.md # Clash API: /rules, /connections, /traffic
│ └── troubleshooting.md # Errors, symptoms, fixes
└── scripts/
├── install-sing-box.sh # apt or binary download + user creation
├── download-geo.sh # Pull .srs files from a CDN (parameterized)
├── preset-global-proxy.sh # Fetch the canonical .srs bundle in one call
├── update-geo.sh # Refresh + reload sing-box (cron-friendly)
├── mode-switch.sh # Switch clash_mode via PATCH /configs
└── backup-config.sh # Snapshot config.json with timestamp
Routing Map
| Question | Read |
|---|
| How does sing-box intercept traffic? What does it own? | references/architecture.md |
| How do I install and start it for the first time? | references/initialization.md |
| I run an old version. What changed? | references/migration.md |
| I want to route specific sites through VPN, others direct. | references/recipes/setup-split-routing.md |
| DNS leaks or wrong resolver for proxy domains. | references/recipes/configure-split-dns.md |
| Multiple VPN servers, automatic failover, panic button. | references/recipes/add-failover-and-panic-button.md |
| Tailscale stops working after sing-box starts. | references/recipes/keep-tailscale-working.md |
| I want a working "global proxy + curated direct lists" preset. | references/recipes/preset-global-proxy.md |
| I want .srs files to refresh automatically. | references/recipes/schedule-rule-updates.md |
| How do I see what rule matched a request? | references/recipes/verify-routing-decisions.md |
| Some specific error or behaviour is wrong. | references/troubleshooting.md |
Reading Order
references/architecture.md — understand TUN, IP rules, the DNS path, and outbound chains before touching the config.
references/initialization.md — install the binary, create directories, deploy a minimal config, enable systemd.
- Recipe files — read only the one matching the user's current task. For the most common "global proxy + curated direct lists" deployment, start with
references/recipes/preset-global-proxy.md and use scripts/preset-global-proxy.sh to fetch the .srs bundle.
references/migration.md — read only when upgrading between minor or major versions.
references/troubleshooting.md — read only when something that should work does not.
Critical Constraints
- Do not invent VPN credentials, server names, or UUIDs. The user supplies these.
- Do not hard-code any user-specific paths in shared files. The config snippets use
/etc/sing-box and /var/lib/sing-box as the standard layout.
- Do not bypass
sing-box check before restarting the service. The daemon aborts on a bad config and the user loses connectivity.
- Do not put
clash_mode rules below rule_set rules. Mode overrides must be above geo rules to be honoured.
- Do not use
strict_route: true unless the user has no other virtual interfaces (Tailscale, WireGuard, Docker). Strict mode rewrites the main routing table and can break neighbours.
- Do not delete the .srs files referenced by
route.rule_set without first removing the matching rule_set entry. sing-box fails to start if a referenced file is missing.
- For shared/public publication: replace any real domain, IP, UUID, or server name in the snippets with placeholders like
<your-vpn-host>, <your-uuid>, <your-public-key>.
Top-Level Skeleton
A minimal config that this skill expands upon:
{
"log": { "level": "info", "timestamp": true },
"dns": {
"servers": [
{ "tag": "direct-dns", "type": "udp", "server": "<local-dns>" },
{ "tag": "proxy-dns", "type": "tls", "server": "<remote-dns>" }
],
"rules": [
{ "rule_set": ["geosite-proxy"],
The real value is in how the route.rules list is composed. The recipes show the exact order and the rationale for each line.