Skip to content

Tor — sing-box

sing-box's Tor outbound spawns a Tor binary as a child process and proxies through its built-in SOCKS port. The protocol options here configure how sing-box launches and steers that process — Tor itself has to be installed separately.

Outbound

type: "tor":

FieldTypeDefaultAllowed valuesDescription
executable_pathstring(PATH lookup)<file path>Path to the Tor binary. When unset, sing-box searches PATH for `tor`.
extra_args[]string[]<arg>Additional command-line arguments passed to Tor on launch. Useful for `--use-bridges`, `--ClientTransportPlugin`, etc.
data_directorystring(temp dir)<dir path>Tor's working directory (cached descriptors, consensus, …). Persisting it across restarts speeds up bootstrap.
torrcmap[string]string{}{<option>: <value>}Inline torrc options passed via Tor's control protocol. Standard torrc keys like `ExcludeNodes`, `ExitNodes`, `StrictNodes` work here.

Source: option/tor.go:3-9 · pinned at v1.13.11 (553cfa1)

Embeds DialerOptions for the underlying socket — bind_interface, detour, etc.

Examples

Minimal — let sing-box find tor on PATH and use defaults:

json
{
  "outbounds": [
    { "type": "tor", "tag": "tor" }
  ]
}

Pinned binary and persistent data directory:

json
{
  "outbounds": [
    {
      "type": "tor",
      "tag": "tor-persistent",
      "executable_path": "/usr/local/bin/tor",
      "data_directory": "/var/lib/sing-box/tor",
      "torrc": {
        "ExitNodes": "{de},{nl}",
        "StrictNodes": "1"
      }
    }
  ]
}

With obfs4 bridges:

json
{
  "outbounds": [
    {
      "type": "tor",
      "tag": "tor-bridged",
      "torrc": {
        "UseBridges": "1",
        "ClientTransportPlugin": "obfs4 exec /usr/bin/obfs4proxy",
        "Bridge": "obfs4 1.2.3.4:443 ABCDEF... cert=... iat-mode=0"
      }
    }
  ]
}

Notes

  • The Tor binary is required at runtime. sing-box does not vendor it. Most distros ship tor as a package; on macOS use Homebrew.
  • data_directory defaults to a fresh temp dir at startup. That's the slowest possible setup — every launch re-bootstraps the consensus. Persisting this directory saves several seconds at startup.
  • torrc keys are passed through Tor's control protocol; the value has to be exactly the string Tor expects (no auto-quoting). For multiline torrc values, repeat the key in extra_args.
  • The outbound has no network field — Tor itself doesn't speak UDP, so the outbound is TCP-only by definition.

Cross-core notes

  • Xray-core has no Tor outbound. The workaround is to point a SOCKS outbound at the system Tor's SOCKS port. See Tor — Xray-core.
  • mihomo has no Tor outbound. See Tor — mihomo.

Source: option/tor.go:3-9 · v1.13.11 (553cfa1)

Core Tutorial by Argsment