commit b6c038d5f586d69167038c31524fd09caf7703a2 Author: naudachu Date: Thu Apr 2 18:00:43 2026 +0500 :fire: diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..039fa42 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,176 @@ +--- +name: singboxed +description: "sing-box proxy platform specialist. Helps configure sing-box JSON configs, tune system settings (TUN, nftables, DNS), design routing rules, select protocols, and troubleshoot connectivity. /singboxed [topic] for help, /singboxed audit to review a config, /singboxed template to generate configs." +user-invocable: true +argument-hint: " [args]" +--- + +# sing-box Configuration Specialist + +You are a sing-box expert (v1.13.x stable / v1.14.x alpha). You have deep knowledge of sing-box's configuration format, all supported protocols, routing engine, DNS resolution, TUN networking, and platform-specific system tuning. + +## Setup — Load References + +Before performing ANY operation, read the relevant reference files from `~/.claude/skills/singboxed/references/`: + +1. **Always read**: `ref-overview.md` (config structure, protocol list, version info) +2. **For routing/rules**: `ref-routing.md` +3. **For DNS**: `ref-dns.md` +4. **For TUN/system**: `ref-tun-system.md` +5. **For protocols**: `ref-protocols.md` +6. **For TLS/transport**: `ref-tls-transport.md` + +Read files in parallel. Only load what's relevant to the user's question. + +## Argument Parsing + +Parse the user's arguments after `/singboxed`: + +- **No arguments**: Show capabilities summary and ask what they need help with +- **`audit`** or **`audit `**: Validate and review a sing-box config file +- **`template client`**: Generate a client proxy config +- **`template server`**: Generate a server config +- **`template tun`**: Generate a TUN transparent proxy config +- **`template dns`**: Generate a DNS-focused config +- **`template wireguard`**: Generate a WireGuard endpoint config +- **`template urltest`**: Generate auto-select proxy group config +- **Any other text**: Treat as a question/topic about sing-box configuration + +--- + +## Audit Procedure + +When auditing a config: + +### Step 1 — Load Config + +Read the config file (default: look for `config.json`, `sing-box.json`, or `*.json` in cwd). + +### Step 2 — Validate Structure + +Check for: + +| Check | Severity | Description | +|-------|----------|-------------| +| STRUCT-01 | CRITICAL | Valid JSON with correct top-level keys | +| STRUCT-02 | CRITICAL | All inbound/outbound tags are unique | +| STRUCT-03 | CRITICAL | Route rules reference existing outbound tags | +| STRUCT-04 | CRITICAL | DNS rules reference existing DNS server tags | +| STRUCT-05 | WARNING | No deprecated fields (geoip/geosite → rule_set, legacy DNS format) | +| STRUCT-06 | WARNING | No removed features (dns outbound type removed in 1.13.0) | + +### Step 3 — Check Security + +| Check | Severity | Description | +|-------|----------|-------------| +| SEC-01 | CRITICAL | No plaintext passwords in non-local configs | +| SEC-02 | WARNING | TLS enabled for remote connections where supported | +| SEC-03 | WARNING | Clash API `secret` set if `external_controller` is non-localhost | +| SEC-04 | INFO | ECH or Reality used for anti-censorship setups | +| SEC-05 | WARNING | `strict_route` enabled when using TUN with `auto_route` | + +### Step 4 — Check Performance + +| Check | Severity | Description | +|-------|----------|-------------| +| PERF-01 | WARNING | DNS cache enabled (not disabled) | +| PERF-02 | INFO | Multiplex (mux) configured for high-throughput scenarios | +| PERF-03 | INFO | `gvisor` or `mixed` stack for TUN (not `system` unless needed) | +| PERF-04 | WARNING | `auto_detect_interface` or `default_interface` set to prevent routing loops | +| PERF-05 | INFO | `urltest` interval not too aggressive (≥1m recommended) | + +### Step 5 — Check Routing Logic + +| Check | Severity | Description | +|-------|----------|-------------| +| ROUTE-01 | WARNING | `final` outbound specified in route | +| ROUTE-02 | WARNING | DNS hijack rule present when using TUN | +| ROUTE-03 | INFO | Private IP bypass rule for LAN access | +| ROUTE-04 | INFO | Rule sets preferred over inline geoip/geosite | +| ROUTE-05 | WARNING | `sniff` action configured for protocol detection | + +### Step 6 — Report + +``` +═══ sing-box Config Audit ═══ +File: +Version compatibility: v1.X.X+ + +CRITICAL: N issues +WARNING: N issues +INFO: N suggestions + +Issues: +[SEVERITY] [CHECK-ID]: description + → Fix: suggested remediation + +Recommendations: +1. Most impactful improvement +2. ... +``` + +--- + +## Topic Help + +When answering questions about sing-box, follow these principles: + +### Always Provide Complete JSON + +Never give partial snippets without context. Show where the JSON fits in the overall config structure. Use comments to explain non-obvious fields. + +### Version Awareness + +- Note when features require specific versions (e.g., `anytls` requires v1.12.0+, endpoints require v1.11.0+) +- Flag deprecated features and suggest modern alternatives +- Key deprecations: + - `geoip`/`geosite` → `rule_set` (since 1.8.0) + - `dns` outbound → `hijack-dns` rule action (removed in 1.13.0) + - Per-inbound `sniff`/`domain_strategy` → route rule actions (since 1.11.0) + - WireGuard outbound → WireGuard endpoint (since 1.11.0) + - ACME in TLS → `certificate_providers` (since 1.14.0) + +### Platform-Specific Guidance + +When the user's platform is known, tailor advice: +- **Linux**: TUN + auto_route + auto_redirect (nftables), iptables redirect/tproxy, routing marks, UID filtering, systemd service +- **macOS**: TUN + auto_route, platform HTTP proxy, find_neighbor +- **Windows**: TUN + auto_route + strict_route (WFP-based) +- **Android**: TUN with include/exclude_package, android_user filtering +- **iOS**: TUN with platform HTTP proxy, network strategy for cellular/wifi + +### System Tuning Topics + +When asked about system settings, cover: +- **nftables/iptables**: redirect vs tproxy modes, mark-based routing, auto_redirect marks +- **iproute2**: custom table index, rule index, policy routing +- **DNS**: system resolver configuration, DNS hijacking setup +- **Network namespaces**: netns support for containerized setups +- **systemd**: service file, auto-restart, capabilities (CAP_NET_ADMIN, CAP_NET_RAW) +- **sysctl**: IP forwarding, rp_filter, TCP optimizations +- **File descriptors**: ulimit for high-connection scenarios + +--- + +## Template Generation + +When generating templates, read the appropriate template from `~/.claude/skills/singboxed/templates/` and customize based on user requirements. Ask clarifying questions if needed: + +- Protocol preference +- Client or server role +- Platform (Linux/macOS/Windows/Android/iOS) +- Use case (bypass censorship, privacy, LAN proxy, VPN replacement) +- Whether they need TUN (transparent proxy) or explicit proxy (SOCKS/HTTP) + +--- + +## Key sing-box Concepts to Always Remember + +1. **Tags are identifiers** — inbound/outbound/DNS server tags must be unique and are referenced by route rules +2. **Route rules are ordered** — first match wins; `final` is the fallback +3. **Rule actions replace inbound options** — sniffing, DNS resolution, domain strategy are now route rule actions (v1.11.0+) +4. **`auto_detect_interface: true`** is almost always needed in route to prevent routing loops +5. **DNS rules and route rules are separate** — DNS rules route DNS queries to DNS servers; route rules route connections to outbounds +6. **`hijack-dns` action** replaces the old `dns` outbound type for intercepting DNS in TUN mode +7. **Listable fields** accept both single values and arrays (e.g., `"address": "172.19.0.1/30"` or `"address": ["172.19.0.1/30", "fdfe:dcba:9876::1/126"]`) +8. **Rule sets** come in `source` (JSON) and `binary` (.srs) formats; remote rule sets auto-update diff --git a/references/ref-dns.md b/references/ref-dns.md new file mode 100644 index 0000000..0a94032 --- /dev/null +++ b/references/ref-dns.md @@ -0,0 +1,363 @@ +# sing-box DNS Reference + +## DNS Configuration Structure + +```json +{ + "dns": { + "servers": [], + "rules": [], + "final": "dns-default", + "strategy": "", + "disable_cache": false, + "disable_expire": false, + "independent_cache": false, + "cache_capacity": 0, + "reverse_mapping": false, + "client_subnet": "" + } +} +``` + +## DNS Server Types (13) + +### `local` — System DNS resolver +```json +{ + "type": "local", + "tag": "dns-local" +} +``` + +### `udp` — Plain UDP DNS +```json +{ + "type": "udp", + "tag": "dns-udp", + "server": "8.8.8.8", + "server_port": 53 +} +``` + +### `tcp` — Plain TCP DNS +```json +{ + "type": "tcp", + "tag": "dns-tcp", + "server": "8.8.8.8", + "server_port": 53 +} +``` + +### `tls` — DNS over TLS (DoT) +```json +{ + "type": "tls", + "tag": "dns-dot", + "server": "dns.google", + "server_port": 853 +} +``` + +### `quic` — DNS over QUIC (DoQ) +```json +{ + "type": "quic", + "tag": "dns-doq", + "server": "dns.adguard-dns.com", + "server_port": 853 +} +``` + +### `https` — DNS over HTTPS (DoH) +```json +{ + "type": "https", + "tag": "dns-doh", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query" +} +``` + +### `h3` — DNS over HTTP/3 +```json +{ + "type": "h3", + "tag": "dns-h3", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query" +} +``` + +### `dhcp` — DHCP-provided DNS +```json +{ + "type": "dhcp", + "tag": "dns-dhcp", + "interface": "eth0" +} +``` + +### `fakeip` — Fake IP DNS +```json +{ + "type": "fakeip", + "tag": "dns-fakeip", + "inet4_range": "198.18.0.0/15", + "inet6_range": "fc00::/18" +} +``` + +### `hosts` — Static hosts file +```json +{ + "type": "hosts", + "tag": "dns-hosts", + "path": "/etc/hosts" +} +``` + +### `rcode` — Return specific response code +```json +{ + "type": "rcode", + "tag": "dns-block", + "rcode": "success" +} +``` +Rcodes: `success`, `format_error`, `server_failure`, `name_error` (NXDOMAIN), `not_implemented`, `refused` + +### `tailscale` — Tailscale MagicDNS +```json +{ + "type": "tailscale", + "tag": "dns-tailscale" +} +``` + +### `resolved` — Reference to resolved service +```json +{ + "type": "resolved", + "tag": "dns-resolved", + "service_tag": "resolved-service" +} +``` + +## DNS Server Common Fields + +All DNS server types support: +```json +{ + "type": "...", + "tag": "unique-tag", + "detour": "outbound-tag", + "domain_resolver": { + "server": "bootstrap-dns-tag", + "strategy": "prefer_ipv4" + }, + "strategy": "prefer_ipv4", + "disable_cache": false, + "disable_expire": false, + "independent_cache": false, + "cache_capacity": 0, + "rewrite_ttl": 0, + "client_subnet": "" +} +``` + +- **`detour`**: Outbound used for DNS transport connection (e.g., send DoH queries through proxy) +- **`domain_resolver`**: Bootstrap DNS for resolving the DNS server's own domain name +- **`strategy`**: `prefer_ipv4`, `prefer_ipv6`, `ipv4_only`, `ipv6_only` +- **`client_subnet`**: EDNS Client Subnet for geo-aware responses + +## DNS Rules + +DNS rules route queries to specific DNS servers. Same match criteria as route rules plus: + +```json +{ + "dns": { + "rules": [ + { + "query_type": ["A", "AAAA"], + "domain_suffix": [".cn"], + "action": "route", + "server": "dns-cn" + } + ] + } +} +``` + +### DNS Rule Actions + +#### `route` — Route to DNS server +```json +{ + "action": "route", + "server": "dns-server-tag", + "strategy": "prefer_ipv4", + "disable_cache": false, + "rewrite_ttl": 0, + "client_subnet": "" +} +``` + +#### `route-options` — Modify DNS options +```json +{ + "action": "route-options", + "disable_cache": true +} +``` + +#### `reject` — Reject DNS query +```json +{ + "action": "reject" +} +``` + +#### `predefined` — Return predefined response +```json +{ + "action": "predefined", + "rcode": "success", + "answer": [], + "ns": [], + "extra": [] +} +``` + +## Common DNS Patterns + +### Pattern: Split DNS (domestic + foreign) +```json +{ + "dns": { + "servers": [ + { + "type": "https", + "tag": "dns-google", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query", + "detour": "proxy" + }, + { + "type": "https", + "tag": "dns-alidns", + "server": "dns.alidns.com", + "server_port": 443, + "path": "/dns-query", + "detour": "direct" + }, + { + "type": "udp", + "tag": "dns-bootstrap", + "server": "223.5.5.5" + } + ], + "rules": [ + { + "rule_set": ["geosite-cn"], + "action": "route", + "server": "dns-alidns" + } + ], + "final": "dns-google" + } +} +``` + +### Pattern: FakeIP for TUN +```json +{ + "dns": { + "servers": [ + { + "type": "https", + "tag": "dns-remote", + "server": "dns.google", + "path": "/dns-query", + "detour": "proxy" + }, + { + "type": "fakeip", + "tag": "dns-fakeip", + "inet4_range": "198.18.0.0/15", + "inet6_range": "fc00::/18" + }, + { + "type": "udp", + "tag": "dns-local", + "server": "223.5.5.5" + } + ], + "rules": [ + { + "rule_set": ["geosite-cn"], + "action": "route", + "server": "dns-local" + }, + { + "query_type": ["A", "AAAA"], + "action": "route", + "server": "dns-fakeip" + } + ], + "final": "dns-remote" + } +} +``` + +### Pattern: Ad-blocking DNS +```json +{ + "dns": { + "rules": [ + { + "rule_set": ["adblock-domains"], + "action": "predefined", + "rcode": "name_error" + } + ] + } +} +``` + +### Pattern: DNS Bootstrap Chain +When a DoH server needs DNS to resolve its own hostname: +```json +{ + "servers": [ + { + "type": "https", + "tag": "dns-secure", + "server": "dns.google", + "domain_resolver": { + "server": "dns-bootstrap", + "strategy": "ipv4_only" + } + }, + { + "type": "udp", + "tag": "dns-bootstrap", + "server": "8.8.8.8" + } + ] +} +``` + +### Pattern: EDNS Client Subnet +```json +{ + "type": "https", + "tag": "dns-with-subnet", + "server": "dns.google", + "client_subnet": "1.2.3.0/24" +} +``` diff --git a/references/ref-overview.md b/references/ref-overview.md new file mode 100644 index 0000000..e5820a2 --- /dev/null +++ b/references/ref-overview.md @@ -0,0 +1,171 @@ +# sing-box Configuration Overview + +## Version Info +- **Stable**: v1.13.3 (March 2026) +- **Alpha**: v1.14.0-alpha.6 +- **Repository**: github.com/SagerNet/sing-box (31.8k stars) +- **Docs**: https://sing-box.sagernet.org + +## Top-Level Config Structure + +```json +{ + "$schema": "", + "log": { + "disabled": false, + "level": "info", + "output": "", + "timestamp": true + }, + "dns": {}, + "ntp": { + "enabled": false, + "server": "time.apple.com", + "server_port": 123, + "interval": "30m" + }, + "certificate": {}, + "certificate_providers": [], + "endpoints": [], + "inbounds": [], + "outbounds": [], + "route": {}, + "services": [], + "experimental": {} +} +``` + +## All Inbound Protocol Types (17) + +| Type | Description | Platform | +|------|-------------|----------| +| `direct` | Direct/injectable forwarding | All | +| `mixed` | SOCKS + HTTP combined proxy | All | +| `socks` | SOCKS4/4a/5 proxy server | All | +| `http` | HTTP/HTTPS proxy server | All | +| `shadowsocks` | Shadowsocks server (incl. 2022 ciphers) | All | +| `vmess` | VMess protocol server | All | +| `vless` | VLESS server (XTLS-Vision flow) | All | +| `trojan` | Trojan server with fallback | All | +| `naive` | NaiveProxy server | All | +| `hysteria` | Hysteria QUIC-based server | All | +| `hysteria2` | Hysteria2 with masquerade | All | +| `shadowtls` | ShadowTLS server | All | +| `tuic` | TUIC QUIC-based server | All | +| `anytls` | AnyTLS server (v1.12.0+) | All | +| `tun` | TUN virtual interface | All | +| `redirect` | TCP redirect transparent proxy | Linux | +| `tproxy` | Full transparent proxy (TCP+UDP) | Linux | + +## All Outbound Protocol Types (20) + +| Type | Description | +|------|-------------| +| `direct` | Direct connection | +| `block` | Block/reject traffic | +| `socks` | SOCKS proxy client | +| `http` | HTTP proxy client | +| `shadowsocks` | Shadowsocks client | +| `vmess` | VMess client | +| `vless` | VLESS client (XTLS-Vision) | +| `trojan` | Trojan client | +| `naive` | NaiveProxy client | +| `wireguard` | WireGuard (deprecated → endpoint) | +| `hysteria` | Hysteria client | +| `hysteria2` | Hysteria2 client (port hopping) | +| `shadowtls` | ShadowTLS client | +| `tuic` | TUIC client | +| `anytls` | AnyTLS client (v1.12.0+) | +| `tor` | Tor network client | +| `ssh` | SSH tunnel client | +| `dns` | DNS outbound (removed in 1.13.0) | +| `selector` | Manual proxy selection group | +| `urltest` | Auto latency-based selection group | + +## Endpoint Types + +| Type | Description | Since | +|------|-------------|-------| +| `wireguard` | WireGuard VPN endpoint (replaces outbound) | v1.11.0 | +| `tailscale` | Tailscale integration | v1.11.0 | + +## Experimental Section + +```json +{ + "experimental": { + "cache_file": { + "enabled": true, + "path": "cache.db", + "cache_id": "", + "store_fakeip": false, + "store_rdrc": false, + "rdrc_timeout": "7d" + }, + "clash_api": { + "external_controller": "127.0.0.1:9090", + "external_ui": "", + "external_ui_download_url": "", + "external_ui_download_detour": "", + "secret": "", + "default_mode": "" + }, + "v2ray_api": { + "listen": "127.0.0.1:8080", + "stats": { + "enabled": true, + "inbounds": ["in-tag"], + "outbounds": ["out-tag"], + "users": ["user"] + } + } + } +} +``` + +## Services (v1.13.0+) + +Background services configured in the `services` array: +- **resolved** — Built-in DNS resolver service +- **ccm** — Client Configuration Manager +- **ocm** — Outbound Configuration Manager +- **ssmapi** — SSM API service +- **derp** — DERP relay service +- **oom_killer** — OOM killer service + +## CLI Commands + +```bash +sing-box run -c config.json # Run with config +sing-box run -C /etc/sing-box/ # Run with config directory (merges all .json) +sing-box check -c config.json # Validate config +sing-box format -c config.json -w # Format config (pretty-print, -w writes back) +sing-box merge output.json -C dir/ # Merge multiple configs into one +sing-box version # Show version +sing-box generate tls-keypair # Generate TLS key pair +sing-box generate reality-keypair # Generate Reality key pair +sing-box generate rand --base64 32 # Generate random bytes +``` + +## Key Deprecations Timeline + +| Version | Deprecated | Replacement | +|---------|-----------|-------------| +| v1.8.0 | `geoip`, `geosite` databases | `rule_set` (local/remote) | +| v1.11.0 | Inbound `sniff`, `domain_strategy` | Route rule actions | +| v1.11.0 | WireGuard outbound | WireGuard endpoint | +| v1.11.0 | Separate `inet4_address`/`inet6_address` | Unified `address` | +| v1.13.0 | `dns` outbound type | `hijack-dns` rule action | +| v1.14.0 | ACME in TLS inbound | `certificate_providers` | + +## Shadowsocks Cipher Methods + +**Modern (recommended):** +- `2022-blake3-aes-128-gcm` +- `2022-blake3-aes-256-gcm` +- `2022-blake3-chacha20-poly1305` + +**Legacy:** +- `aes-128-gcm`, `aes-192-gcm`, `aes-256-gcm` +- `chacha20-ietf-poly1305`, `xchacha20-ietf-poly1305` +- `none` (no encryption) diff --git a/references/ref-protocols.md b/references/ref-protocols.md new file mode 100644 index 0000000..0a4e4a5 --- /dev/null +++ b/references/ref-protocols.md @@ -0,0 +1,409 @@ +# sing-box Protocol Reference + +## Shadowsocks + +### Client +```json +{ + "type": "shadowsocks", + "tag": "ss-out", + "server": "server.example.com", + "server_port": 8388, + "method": "2022-blake3-aes-256-gcm", + "password": "base64-encoded-key", + "plugin": "", + "plugin_opts": "", + "network": "tcp", + "udp_over_tcp": false, + "multiplex": {} +} +``` + +### Server +```json +{ + "type": "shadowsocks", + "tag": "ss-in", + "listen": "::", + "listen_port": 8388, + "method": "2022-blake3-aes-256-gcm", + "password": "base64-encoded-key", + "users": [ + { + "name": "user1", + "password": "user-key" + } + ] +} +``` + +Key generation: +```bash +# For 2022-blake3-aes-256-gcm (32 bytes) +sing-box generate rand --base64 32 +# For 2022-blake3-aes-128-gcm (16 bytes) +sing-box generate rand --base64 16 +``` + +## VMess + +### Client +```json +{ + "type": "vmess", + "tag": "vmess-out", + "server": "server.example.com", + "server_port": 443, + "uuid": "uuid-here", + "security": "auto", + "alter_id": 0, + "global_padding": true, + "authenticated_length": true, + "tls": {}, + "transport": {}, + "multiplex": {} +} +``` + +### Server +```json +{ + "type": "vmess", + "tag": "vmess-in", + "listen": "::", + "listen_port": 443, + "users": [ + { + "name": "user1", + "uuid": "uuid-here", + "alterId": 0 + } + ], + "tls": {}, + "transport": {} +} +``` + +## VLESS + +### Client +```json +{ + "type": "vless", + "tag": "vless-out", + "server": "server.example.com", + "server_port": 443, + "uuid": "uuid-here", + "flow": "xtls-rprx-vision", + "tls": { + "enabled": true, + "server_name": "example.com", + "utls": { + "enabled": true, + "fingerprint": "chrome" + } + }, + "transport": {}, + "multiplex": {} +} +``` + +### Server +```json +{ + "type": "vless", + "tag": "vless-in", + "listen": "::", + "listen_port": 443, + "users": [ + { + "name": "user1", + "uuid": "uuid-here", + "flow": "xtls-rprx-vision" + } + ], + "tls": {}, + "transport": {} +} +``` + +## Trojan + +### Client +```json +{ + "type": "trojan", + "tag": "trojan-out", + "server": "server.example.com", + "server_port": 443, + "password": "password", + "tls": { + "enabled": true, + "server_name": "example.com" + }, + "transport": {}, + "multiplex": {} +} +``` + +### Server +```json +{ + "type": "trojan", + "tag": "trojan-in", + "listen": "::", + "listen_port": 443, + "users": [ + { + "name": "user1", + "password": "password" + } + ], + "tls": {}, + "fallback": { + "server": "127.0.0.1", + "server_port": 8080 + }, + "fallback_for_alpn": { + "h2": { + "server": "127.0.0.1", + "server_port": 8081 + } + } +} +``` + +## Hysteria2 + +### Client +```json +{ + "type": "hysteria2", + "tag": "hy2-out", + "server": "server.example.com", + "server_port": 443, + "up_mbps": 100, + "down_mbps": 200, + "password": "password", + "obfs": { + "type": "salamander", + "password": "obfs-password" + }, + "tls": { + "enabled": true, + "server_name": "example.com" + } +} +``` + +### Server +```json +{ + "type": "hysteria2", + "tag": "hy2-in", + "listen": "::", + "listen_port": 443, + "up_mbps": 0, + "down_mbps": 0, + "users": [ + { + "name": "user1", + "password": "password" + } + ], + "obfs": { + "type": "salamander", + "password": "obfs-password" + }, + "masquerade": "https://example.com", + "tls": {} +} +``` + +## TUIC + +### Client +```json +{ + "type": "tuic", + "tag": "tuic-out", + "server": "server.example.com", + "server_port": 443, + "uuid": "uuid-here", + "password": "password", + "congestion_control": "bbr", + "udp_relay_mode": "quic", + "zero_rtt_handshake": false, + "heartbeat": "10s", + "tls": { + "enabled": true, + "server_name": "example.com" + } +} +``` +Congestion control: `cubic` (default), `new_reno`, `bbr` +UDP relay: `native` (default), `quic` + +## ShadowTLS + +### Client (chained with another outbound) +```json +{ + "type": "shadowtls", + "tag": "shadowtls-out", + "server": "server.example.com", + "server_port": 443, + "version": 3, + "password": "password", + "tls": { + "enabled": true, + "server_name": "www.microsoft.com" + } +} +``` + +### Chaining ShadowTLS + Shadowsocks +```json +{ + "outbounds": [ + { + "type": "shadowsocks", + "tag": "ss-out", + "detour": "shadowtls-out", + "method": "2022-blake3-aes-256-gcm", + "password": "ss-key" + }, + { + "type": "shadowtls", + "tag": "shadowtls-out", + "server": "server.example.com", + "server_port": 443, + "version": 3, + "password": "stls-password", + "tls": { + "enabled": true, + "server_name": "www.microsoft.com" + } + } + ] +} +``` + +## AnyTLS (v1.12.0+) + +### Client +```json +{ + "type": "anytls", + "tag": "anytls-out", + "server": "server.example.com", + "server_port": 443, + "password": "password", + "idle_timeout": "15m", + "min_idle_session": 2, + "padding_scheme": "", + "tls": { + "enabled": true, + "server_name": "example.com" + } +} +``` + +## WireGuard (Endpoint) + +```json +{ + "endpoints": [ + { + "type": "wireguard", + "tag": "wg-ep", + "system": false, + "name": "wg0", + "mtu": 1420, + "address": [ + "10.0.0.2/32", + "fd00::2/128" + ], + "private_key": "private-key-base64", + "listen_port": 51820, + "peers": [ + { + "address": "server.example.com", + "port": 51820, + "public_key": "peer-public-key-base64", + "pre_shared_key": "", + "allowed_ips": ["0.0.0.0/0", "::/0"], + "persistent_keepalive_interval": "25s", + "reserved": [0, 0, 0] + } + ] + } + ] +} +``` + +## SSH Tunnel + +```json +{ + "type": "ssh", + "tag": "ssh-out", + "server": "server.example.com", + "server_port": 22, + "user": "username", + "password": "password", + "private_key": "", + "private_key_path": "~/.ssh/id_ed25519", + "private_key_passphrase": "", + "host_key_algorithms": [], + "client_version": "SSH-2.0-OpenSSH_8.9" +} +``` + +## Selector (Manual Proxy Group) + +```json +{ + "type": "selector", + "tag": "proxy", + "outbounds": ["hy2-hk", "vless-jp", "ss-us", "direct"], + "default": "hy2-hk", + "interrupt_exist_connections": true +} +``` + +## URLTest (Auto Proxy Group) + +```json +{ + "type": "urltest", + "tag": "auto", + "outbounds": ["hy2-hk", "vless-jp", "ss-us"], + "url": "https://www.gstatic.com/generate_204", + "interval": "3m", + "tolerance": 50, + "idle_timeout": "30m", + "interrupt_exist_connections": true +} +``` + +## Multiplex (Mux) — Shared Options + +```json +{ + "multiplex": { + "enabled": true, + "protocol": "h2mux", + "max_connections": 4, + "min_streams": 4, + "max_streams": 0, + "padding": true, + "brutal": { + "enabled": true, + "up_mbps": 100, + "down_mbps": 200 + } + } +} +``` +Protocols: `smux`, `yamux`, `h2mux` (default, recommended) diff --git a/references/ref-routing.md b/references/ref-routing.md new file mode 100644 index 0000000..07ebccc --- /dev/null +++ b/references/ref-routing.md @@ -0,0 +1,316 @@ +# sing-box Routing Reference + +## Route Options + +```json +{ + "route": { + "rules": [], + "rule_set": [], + "final": "direct", + "auto_detect_interface": true, + "override_android_vpn": false, + "default_interface": "", + "default_mark": 0, + "find_process": false, + "find_neighbor": false, + "default_domain_resolver": { + "server": "dns-tag", + "strategy": "prefer_ipv4" + }, + "default_network_strategy": "", + "default_network_type": [], + "default_fallback_network_type": [], + "default_fallback_delay": "300ms" + } +} +``` + +## Route Rule Structure + +Each rule has **match criteria** and an **action**. First matching rule wins. + +### Default Rule (flat criteria) + +```json +{ + "type": "default", + "action": "route", + + // --- Match criteria (all are optional, combined with AND) --- + + // Traffic source + "inbound": ["tun-in"], + "auth_user": ["user1"], + "client": ["client-tag"], + + // Network + "ip_version": 4, + "network": ["tcp", "udp"], + + // Domain matching + "domain": ["example.com"], + "domain_suffix": [".cn", ".ir"], + "domain_keyword": ["google"], + "domain_regex": ["^ad\\."], + + // IP matching + "ip_cidr": ["10.0.0.0/8"], + "source_ip_cidr": ["192.168.1.0/24"], + "ip_is_private": false, + "source_ip_is_private": false, + + // Port matching + "port": [80, 443], + "port_range": ["1000:2000"], + "source_port": [1234], + "source_port_range": [], + + // Protocol detection (requires sniff action first) + "protocol": ["http", "tls", "quic", "stun", "dns", "bittorrent"], + + // Process matching (requires find_process: true) + "process_name": ["curl"], + "process_path": ["/usr/bin/curl"], + "process_path_regex": [], + + // Android + "package_name": ["com.android.chrome"], + + // Linux + "user": ["proxy"], + "user_id": [1000], + + // Network type + "wifi_ssid": ["HomeWiFi"], + "wifi_bssid": [], + "network_type": ["wifi", "cellular", "ethernet"], + "network_is_expensive": false, + "network_is_constrained": false, + + // Rule sets + "rule_set": ["geoip-cn", "geosite-cn"], + "rule_set_ip_cidr_match_source": false, + + // Clash mode + "clash_mode": "Rule", + + // Invert match + "invert": false, + + // --- Action --- + "action": "route", + "outbound": "proxy" +} +``` + +### Logical Rule (nested with AND/OR) + +```json +{ + "type": "logical", + "mode": "and", + "rules": [ + { "network": "udp" }, + { "port": [443] } + ], + "invert": false, + "action": "route", + "outbound": "block" +} +``` + +## Rule Actions + +### `route` — Route to outbound +```json +{ + "action": "route", + "outbound": "proxy", + "override_address": "", + "override_port": 0, + "network_strategy": "", + "network_type": [], + "fallback_network_type": [], + "fallback_delay": "300ms", + "udp_disable_domain_unmapping": false, + "udp_connect": false, + "tls_fragment": { + "enabled": true, + "size": "10-30", + "sleep": "2-8", + "fallback_delay": "300ms" + }, + "tls_record_fragment": { + "enabled": true, + "size": "100-200" + } +} +``` + +### `route-options` — Modify routing options without changing outbound +```json +{ + "action": "route-options", + "network_strategy": "prefer_ipv4", + "udp_disable_domain_unmapping": true, + "udp_connect": true +} +``` + +### `direct` — Direct connection with custom dialer +```json +{ + "action": "direct", + "override_address": "1.2.3.4", + "override_port": 53 +} +``` + +### `reject` — Reject connection +```json +{ + "action": "reject", + "method": "default", + "no_drop": false +} +``` +Methods: `default` (TCP RST / ICMP unreachable), `drop` (silent drop), `reply` (for DNS) + +### `hijack-dns` — Intercept DNS queries +```json +{ + "action": "hijack-dns" +} +``` + +### `sniff` — Protocol sniffing +```json +{ + "action": "sniff", + "sniffer": ["http", "tls", "quic", "stun", "dns", "bittorrent", "dtls", "ssh", "rdp"], + "timeout": "300ms" +} +``` + +### `resolve` — DNS resolution +```json +{ + "action": "resolve", + "server": "dns-server-tag", + "strategy": "prefer_ipv4", + "disable_cache": false, + "rewrite_ttl": 0, + "client_subnet": "" +} +``` + +## Rule Sets + +### Remote rule set (auto-updating) +```json +{ + "type": "remote", + "tag": "geoip-cn", + "format": "binary", + "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs", + "download_detour": "direct", + "update_interval": "1d" +} +``` + +### Local rule set +```json +{ + "type": "local", + "tag": "custom-rules", + "format": "source", + "path": "/etc/sing-box/rules/custom.json" +} +``` + +### Inline rule set +```json +{ + "type": "inline", + "tag": "my-rules", + "rules": [ + { "domain_suffix": [".example.com"] } + ] +} +``` + +### Rule set source format (.json) +```json +{ + "version": 1, + "rules": [ + { + "domain_suffix": [".cn", ".中国"], + "ip_cidr": ["223.5.5.5/32"] + } + ] +} +``` + +## Common Routing Patterns + +### Pattern: DNS Hijack for TUN mode +```json +{ + "route": { + "rules": [ + { "action": "sniff" }, + { "protocol": "dns", "action": "hijack-dns" }, + // ... other rules + ] + } +} +``` + +### Pattern: Bypass LAN +```json +{ "ip_is_private": true, "action": "route", "outbound": "direct" } +``` + +### Pattern: Block ads via rule set +```json +{ "rule_set": ["adblock"], "action": "reject", "method": "default" } +``` + +### Pattern: Route by process +```json +{ + "route": { + "find_process": true, + "rules": [ + { "process_name": ["telegram"], "action": "route", "outbound": "proxy" } + ] + } +} +``` + +### Pattern: Split tunnel by domain +```json +{ + "rules": [ + { "rule_set": ["geosite-cn"], "action": "route", "outbound": "direct" }, + { "rule_set": ["geosite-category-ads-all"], "action": "reject" } + ], + "final": "proxy" +} +``` + +### Pattern: TLS fragment for anti-censorship +```json +{ + "domain_keyword": ["blocked-site"], + "action": "route", + "outbound": "direct", + "tls_fragment": { + "enabled": true, + "size": "1-5", + "sleep": "10-20" + } +} +``` diff --git a/references/ref-tls-transport.md b/references/ref-tls-transport.md new file mode 100644 index 0000000..632dd90 --- /dev/null +++ b/references/ref-tls-transport.md @@ -0,0 +1,320 @@ +# sing-box TLS & Transport Reference + +## TLS Outbound (Client) + +```json +{ + "tls": { + "enabled": true, + "disable_sni": false, + "server_name": "example.com", + "insecure": false, + "alpn": ["h2", "http/1.1"], + "min_version": "1.2", + "max_version": "1.3", + "cipher_suites": [], + "certificate": [], + "certificate_path": "", + + // uTLS fingerprinting + "utls": { + "enabled": true, + "fingerprint": "chrome" + }, + + // Reality protocol + "reality": { + "enabled": true, + "public_key": "public-key", + "short_id": "short-id" + }, + + // Encrypted Client Hello + "ech": { + "enabled": true, + "pq_signature_schemes_enabled": false, + "dynamic_record_sizing_disabled": false, + "config": [], + "config_path": "" + } + } +} +``` + +### uTLS Fingerprints + +| Fingerprint | Description | +|-------------|-------------| +| `chrome` | Latest Chrome (recommended) | +| `firefox` | Latest Firefox | +| `safari` | Latest Safari | +| `edge` | Latest Edge | +| `ios` | iOS Safari | +| `android` | Android Chrome | +| `random` | Random from all | +| `randomized` | Randomized parameters | +| `chrome_auto` | Auto-update Chrome | +| `360_auto` | 360 Browser | +| `qq_auto` | QQ Browser | + +## TLS Inbound (Server) + +```json +{ + "tls": { + "enabled": true, + "server_name": "example.com", + "alpn": ["h2", "http/1.1"], + "min_version": "1.2", + "max_version": "1.3", + "cipher_suites": [], + "certificate": [], + "certificate_path": "/path/to/cert.pem", + "key": [], + "key_path": "/path/to/key.pem", + + // Client certificate auth + "client_auth": { + "enabled": true, + "mode": "require-and-verify", + "certificate": [], + "certificate_path": "" + }, + + // Reality server + "reality": { + "enabled": true, + "private_key": "private-key", + "short_id": ["short-id"], + "handshake": { + "server": "www.microsoft.com", + "server_port": 443 + }, + "max_time_difference": "1m" + }, + + // ECH server + "ech": { + "enabled": true, + "pq_signature_schemes_enabled": false, + "dynamic_record_sizing_disabled": false, + "key": [], + "key_path": "" + }, + + // Kernel TLS (Linux 5.1+) + "kernel_tx": false, + "kernel_rx": false + } +} +``` + +### Client Auth Modes +- `no` — No client certificate required +- `request` — Request but don't require +- `require-any` — Require any client certificate +- `verify-if-given` — Verify only if provided +- `require-and-verify` — Require and verify against CA + +### Reality Key Generation +```bash +sing-box generate reality-keypair +# Output: +# PrivateKey: xxxx +# PublicKey: xxxx +``` + +## V2Ray Transport Layer + +Supported by: VMess, VLESS, Trojan + +### HTTP Transport +```json +{ + "transport": { + "type": "http", + "host": ["example.com"], + "path": "/", + "method": "PUT", + "headers": { + "X-Custom": ["value"] + }, + "idle_timeout": "15s", + "ping_timeout": "15s" + } +} +``` + +### WebSocket Transport +```json +{ + "transport": { + "type": "ws", + "path": "/ws-path", + "headers": { + "Host": "example.com" + }, + "max_early_data": 2048, + "early_data_header_name": "Sec-WebSocket-Protocol" + } +} +``` + +### gRPC Transport +```json +{ + "transport": { + "type": "grpc", + "service_name": "GunService", + "idle_timeout": "15s", + "ping_timeout": "15s", + "permit_without_stream": false + } +} +``` + +### QUIC Transport +```json +{ + "transport": { + "type": "quic" + } +} +``` + +### HTTPUpgrade Transport +```json +{ + "transport": { + "type": "httpupgrade", + "host": "example.com", + "path": "/upgrade-path", + "headers": { + "X-Custom": ["value"] + } + } +} +``` + +## Anti-Censorship Techniques + +### TLS Fragment (in route rule action) +Splits TLS ClientHello into small fragments to evade DPI: +```json +{ + "action": "route", + "outbound": "direct", + "tls_fragment": { + "enabled": true, + "size": "1-5", + "sleep": "10-20", + "fallback_delay": "300ms" + } +} +``` +- `size`: Fragment size range (bytes) +- `sleep`: Delay between fragments (ms) +- Only works with TCP, mutually exclusive with `tls_record_fragment` + +### TLS Record Fragment (in route rule action) +Splits TLS records into smaller records: +```json +{ + "action": "route", + "outbound": "direct", + "tls_record_fragment": { + "enabled": true, + "size": "100-200" + } +} +``` +- Lower overhead than TLS fragment +- Mutually exclusive with `tls_fragment` + +### VLESS + Reality (anti-probing) +Makes the server look like a legitimate website: +```json +{ + "inbounds": [{ + "type": "vless", + "listen_port": 443, + "users": [{ "uuid": "...", "flow": "xtls-rprx-vision" }], + "tls": { + "enabled": true, + "reality": { + "enabled": true, + "private_key": "...", + "short_id": ["abcd1234"], + "handshake": { + "server": "www.microsoft.com", + "server_port": 443 + } + } + } + }] +} +``` + +### ShadowTLS v3 + Shadowsocks (stealth) +Traffic looks like normal TLS to a legitimate site: +```json +{ + "inbounds": [{ + "type": "shadowtls", + "listen_port": 443, + "version": 3, + "users": [{ "name": "user1", "password": "stls-pass" }], + "handshake": { + "server": "www.google.com", + "server_port": 443 + }, + "handshake_for_server_name": { + "www.google.com": { + "server": "www.google.com", + "server_port": 443 + } + }, + "detour": "ss-in" + }], + "outbounds": [...] +} +``` + +### Hysteria2 + Salamander Obfuscation +```json +{ + "type": "hysteria2", + "obfs": { + "type": "salamander", + "password": "obfs-password" + } +} +``` + +## CDN-Compatible Transports + +For routing through CDN (Cloudflare, etc.): +- **WebSocket** (`ws`) — most widely supported +- **gRPC** — good CDN support, efficient +- **HTTPUpgrade** — lightweight alternative to WebSocket + +Example: VLESS + WebSocket behind CDN: +```json +{ + "type": "vless", + "server": "cdn-domain.example.com", + "server_port": 443, + "uuid": "...", + "tls": { + "enabled": true, + "server_name": "cdn-domain.example.com" + }, + "transport": { + "type": "ws", + "path": "/vless-ws", + "headers": { + "Host": "cdn-domain.example.com" + } + } +} +``` diff --git a/references/ref-tun-system.md b/references/ref-tun-system.md new file mode 100644 index 0000000..d1a8954 --- /dev/null +++ b/references/ref-tun-system.md @@ -0,0 +1,318 @@ +# sing-box TUN & System Settings Reference + +## TUN Inbound Configuration + +```json +{ + "type": "tun", + "tag": "tun-in", + + "interface_name": "", + "mtu": 9000, + "gso": false, + "address": [ + "172.19.0.1/30", + "fdfe:dcba:9876::1/126" + ], + "auto_route": true, + "auto_redirect": false, + "strict_route": true, + "route_address": [], + "route_address_set": [], + "route_exclude_address": [], + "route_exclude_address_set": [], + + "stack": "mixed", + "udp_timeout": "5m", + + // Linux nftables (auto_redirect) + "auto_redirect_input_mark": "0x2023", + "auto_redirect_output_mark": "0x2024", + "auto_redirect_reset_mark": "0x2025", + "auto_redirect_nfqueue": 100, + "auto_redirect_iproute2_fallback_rule_index": 32768, + "exclude_mptcp": false, + + // Linux iproute2 + "iproute2_table_index": 2022, + "iproute2_rule_index": 9000, + + // Linux UID filtering + "include_uid": [], + "include_uid_range": ["1000:65534"], + "exclude_uid": [0], + "exclude_uid_range": [], + + // Interface filtering + "include_interface": [], + "exclude_interface": ["docker0", "br-*"], + + // Android + "include_android_user": [0], + "include_package": [], + "exclude_package": ["com.android.captiveportallogin"], + + // Apple (iOS/macOS) + "platform": { + "http_proxy": { + "enabled": false, + "server": "127.0.0.1", + "server_port": 1080, + "match_domain": [] + } + }, + + // Network namespace (Linux) + "netns": "" +} +``` + +## TCP/IP Stack Options + +| Stack | Description | Best For | +|-------|-------------|----------| +| `system` | Uses OS network stack | Compatibility, low overhead | +| `gvisor` | Userspace TCP/IP (Google gVisor) | Stability, no kernel dependency | +| `mixed` | TCP=system, UDP=gvisor | **Recommended default** — best balance | + +## TUN auto_route Behavior + +When `auto_route: true`: +- **Linux**: Creates iproute2 rules and routes in table `iproute2_table_index` (default 2022) +- **macOS**: Adds routes via `route` command +- **Windows**: Uses WFP (Windows Filtering Platform) for traffic redirect + +When `strict_route: true` (recommended with auto_route): +- **Linux**: Adds rules to prevent traffic leaking outside TUN +- **Windows**: Blocks non-TUN traffic via WFP +- Prevents DNS and other leaks + +## auto_redirect (Linux nftables) + +Alternative to `tproxy` inbound. Uses nftables to redirect all traffic to TUN: + +```json +{ + "type": "tun", + "auto_route": true, + "auto_redirect": true, + "auto_redirect_input_mark": "0x2023", + "auto_redirect_output_mark": "0x2024" +} +``` + +Requires: `nftables` available, `CAP_NET_ADMIN` capability. + +## Linux Transparent Proxy Alternatives + +### Option 1: TUN (recommended) +```json +{ + "inbounds": [ + { + "type": "tun", + "tag": "tun-in", + "address": ["172.19.0.1/30", "fdfe:dcba:9876::1/126"], + "auto_route": true, + "strict_route": true, + "stack": "mixed" + } + ] +} +``` + +### Option 2: redirect (TCP only) +```json +{ + "inbounds": [ + { + "type": "redirect", + "tag": "redirect-in", + "listen": "::", + "listen_port": 12345 + } + ] +} +``` +Requires iptables rule: +```bash +iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 12345 +``` + +### Option 3: tproxy (TCP + UDP) +```json +{ + "inbounds": [ + { + "type": "tproxy", + "tag": "tproxy-in", + "listen": "::", + "listen_port": 12345, + "network": "udp" + }, + { + "type": "tproxy", + "tag": "tproxy-in-tcp", + "listen": "::", + "listen_port": 12345, + "network": "tcp" + } + ] +} +``` +Requires iptables TPROXY rules and ip rule/route for marking. + +## System Tuning — Linux + +### sysctl settings +```bash +# Enable IP forwarding (for gateway/router mode) +sysctl -w net.ipv4.ip_forward=1 +sysctl -w net.ipv6.conf.all.forwarding=1 + +# Disable reverse path filtering (needed for tproxy/TUN) +sysctl -w net.ipv4.conf.all.rp_filter=0 +sysctl -w net.ipv4.conf.default.rp_filter=0 + +# TCP optimizations +sysctl -w net.core.rmem_max=16777216 +sysctl -w net.core.wmem_max=16777216 +sysctl -w net.ipv4.tcp_fastopen=3 # Enable TFO client+server +sysctl -w net.ipv4.tcp_mtu_probing=1 # For Hysteria/QUIC MTU discovery + +# Increase conntrack for high-connection scenarios +sysctl -w net.netfilter.nf_conntrack_max=131072 + +# BBR congestion control (recommended) +sysctl -w net.core.default_qdisc=fq +sysctl -w net.ipv4.tcp_congestion_control=bbr +``` + +### Persist sysctl +```bash +# /etc/sysctl.d/99-sing-box.conf +net.ipv4.ip_forward = 1 +net.ipv6.conf.all.forwarding = 1 +net.ipv4.conf.all.rp_filter = 0 +net.core.default_qdisc = fq +net.ipv4.tcp_congestion_control = bbr +net.ipv4.tcp_fastopen = 3 +``` + +### File descriptor limits +```bash +# /etc/security/limits.d/sing-box.conf +* soft nofile 65535 +* hard nofile 131072 + +# Or for systemd service +# [Service] +# LimitNOFILE=131072 +``` + +### Required capabilities +```bash +# Instead of running as root: +sudo setcap cap_net_admin,cap_net_raw,cap_net_bind_service+ep /usr/bin/sing-box +``` + +### systemd service +```ini +# /etc/systemd/system/sing-box.service +[Unit] +Description=sing-box service +Documentation=https://sing-box.sagernet.org +After=network.target nss-lookup.target + +[Service] +Type=simple +ExecStart=/usr/bin/sing-box run -c /etc/sing-box/config.json +Restart=on-failure +RestartSec=10s +LimitNOFILE=131072 +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE +AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE +NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target +``` + +### systemd with config directory +```ini +ExecStart=/usr/bin/sing-box run -C /etc/sing-box/ +``` + +## System Tuning — macOS + +```bash +# Enable IP forwarding +sudo sysctl -w net.inet.ip.forwarding=1 +sudo sysctl -w net.inet6.ip6.forwarding=1 +``` + +## Network Namespace (Linux) + +Run sing-box in an isolated network namespace: +```json +{ + "type": "tun", + "netns": "sing-box-ns" +} +``` +Or use a path: `"netns": "/run/netns/custom-ns"` + +## Routing Mark (Linux) + +Prevent routing loops by marking sing-box's own traffic: +```json +{ + "route": { + "default_mark": 255 + } +} +``` +Or per-outbound: +```json +{ + "type": "direct", + "tag": "direct", + "routing_mark": 255 +} +``` + +## Dial Fields (Common to All Outbounds) + +```json +{ + "bind_interface": "", + "inet4_bind_address": "", + "inet6_bind_address": "", + "routing_mark": 0, + "reuse_addr": false, + "connect_timeout": "5s", + "tcp_fast_open": false, + "tcp_multi_path": false, + "udp_fragment": false, + "domain_strategy": "", + "network_strategy": "", + "network_type": [], + "fallback_network_type": [], + "fallback_delay": "300ms" +} +``` + +## Listen Fields (Common to All Inbounds) + +```json +{ + "listen": "0.0.0.0", + "listen_port": 1080, + "tcp_fast_open": false, + "tcp_multi_path": false, + "udp_fragment": false, + "udp_timeout": "5m", + "proxy_protocol": false, + "proxy_protocol_accept_no_header": false +} +``` diff --git a/templates/client.json b/templates/client.json new file mode 100644 index 0000000..a50843c --- /dev/null +++ b/templates/client.json @@ -0,0 +1,66 @@ +{ + "log": { + "level": "info", + "timestamp": true + }, + "dns": { + "servers": [ + { + "type": "https", + "tag": "dns-remote", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query", + "detour": "proxy", + "domain_resolver": { + "server": "dns-bootstrap", + "strategy": "ipv4_only" + } + }, + { + "type": "udp", + "tag": "dns-bootstrap", + "server": "8.8.8.8" + } + ], + "final": "dns-remote" + }, + "inbounds": [ + { + "type": "mixed", + "tag": "mixed-in", + "listen": "127.0.0.1", + "listen_port": 1080 + } + ], + "outbounds": [ + { + "type": "{{PROTOCOL}}", + "tag": "proxy", + "server": "{{SERVER}}", + "server_port": "{{PORT}}" + }, + { + "type": "direct", + "tag": "direct" + }, + { + "type": "block", + "tag": "block" + } + ], + "route": { + "rules": [ + { "action": "sniff" }, + { "protocol": "dns", "action": "hijack-dns" }, + { "ip_is_private": true, "action": "route", "outbound": "direct" } + ], + "final": "proxy", + "auto_detect_interface": true + }, + "experimental": { + "cache_file": { + "enabled": true + } + } +} diff --git a/templates/server.json b/templates/server.json new file mode 100644 index 0000000..81337a9 --- /dev/null +++ b/templates/server.json @@ -0,0 +1,38 @@ +{ + "log": { + "level": "info", + "timestamp": true + }, + "inbounds": [ + { + "type": "{{PROTOCOL}}", + "tag": "{{PROTOCOL}}-in", + "listen": "::", + "listen_port": 443, + "users": [ + { + "name": "user1", + "password": "{{PASSWORD_OR_UUID}}" + } + ], + "tls": { + "enabled": true, + "certificate_path": "/etc/sing-box/cert.pem", + "key_path": "/etc/sing-box/key.pem" + } + } + ], + "outbounds": [ + { + "type": "direct", + "tag": "direct" + } + ], + "route": { + "rules": [ + { "action": "sniff" }, + { "ip_is_private": true, "action": "reject" } + ], + "final": "direct" + } +} diff --git a/templates/tun.json b/templates/tun.json new file mode 100644 index 0000000..77b894c --- /dev/null +++ b/templates/tun.json @@ -0,0 +1,92 @@ +{ + "log": { + "level": "info", + "timestamp": true + }, + "dns": { + "servers": [ + { + "type": "https", + "tag": "dns-remote", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query", + "detour": "proxy", + "domain_resolver": { + "server": "dns-bootstrap", + "strategy": "ipv4_only" + } + }, + { + "type": "fakeip", + "tag": "dns-fakeip", + "inet4_range": "198.18.0.0/15", + "inet6_range": "fc00::/18" + }, + { + "type": "udp", + "tag": "dns-local", + "server": "223.5.5.5" + }, + { + "type": "udp", + "tag": "dns-bootstrap", + "server": "8.8.8.8" + } + ], + "rules": [ + { + "query_type": ["A", "AAAA"], + "action": "route", + "server": "dns-fakeip" + } + ], + "final": "dns-remote" + }, + "inbounds": [ + { + "type": "tun", + "tag": "tun-in", + "address": [ + "172.19.0.1/30", + "fdfe:dcba:9876::1/126" + ], + "mtu": 9000, + "auto_route": true, + "strict_route": true, + "stack": "mixed", + "exclude_interface": [] + } + ], + "outbounds": [ + { + "type": "{{PROTOCOL}}", + "tag": "proxy", + "server": "{{SERVER}}", + "server_port": "{{PORT}}" + }, + { + "type": "direct", + "tag": "direct" + }, + { + "type": "block", + "tag": "block" + } + ], + "route": { + "rules": [ + { "action": "sniff" }, + { "protocol": "dns", "action": "hijack-dns" }, + { "ip_is_private": true, "action": "route", "outbound": "direct" } + ], + "final": "proxy", + "auto_detect_interface": true + }, + "experimental": { + "cache_file": { + "enabled": true, + "store_fakeip": true + } + } +} diff --git a/templates/urltest.json b/templates/urltest.json new file mode 100644 index 0000000..26ed119 --- /dev/null +++ b/templates/urltest.json @@ -0,0 +1,99 @@ +{ + "log": { + "level": "info", + "timestamp": true + }, + "dns": { + "servers": [ + { + "type": "https", + "tag": "dns-remote", + "server": "dns.google", + "server_port": 443, + "path": "/dns-query", + "detour": "auto", + "domain_resolver": { + "server": "dns-bootstrap", + "strategy": "ipv4_only" + } + }, + { + "type": "udp", + "tag": "dns-bootstrap", + "server": "8.8.8.8" + } + ], + "final": "dns-remote" + }, + "inbounds": [ + { + "type": "mixed", + "tag": "mixed-in", + "listen": "127.0.0.1", + "listen_port": 1080 + } + ], + "outbounds": [ + { + "type": "selector", + "tag": "proxy", + "outbounds": ["auto", "node-hk", "node-jp", "node-us", "direct"], + "default": "auto", + "interrupt_exist_connections": true + }, + { + "type": "urltest", + "tag": "auto", + "outbounds": ["node-hk", "node-jp", "node-us"], + "url": "https://www.gstatic.com/generate_204", + "interval": "3m", + "tolerance": 50, + "idle_timeout": "30m", + "interrupt_exist_connections": true + }, + { + "type": "{{PROTOCOL}}", + "tag": "node-hk", + "server": "hk.example.com", + "server_port": 443 + }, + { + "type": "{{PROTOCOL}}", + "tag": "node-jp", + "server": "jp.example.com", + "server_port": 443 + }, + { + "type": "{{PROTOCOL}}", + "tag": "node-us", + "server": "us.example.com", + "server_port": 443 + }, + { + "type": "direct", + "tag": "direct" + }, + { + "type": "block", + "tag": "block" + } + ], + "route": { + "rules": [ + { "action": "sniff" }, + { "protocol": "dns", "action": "hijack-dns" }, + { "ip_is_private": true, "action": "route", "outbound": "direct" } + ], + "final": "proxy", + "auto_detect_interface": true + }, + "experimental": { + "cache_file": { + "enabled": true + }, + "clash_api": { + "external_controller": "127.0.0.1:9090", + "secret": "" + } + } +}