Skip to content

Direct — sing-box

Direct is sing-box's passthrough outbound and a useful "test echo" inbound. The outbound side has been deliberately trimmed in recent releases — what used to be override_address / override_port on the outbound is now a route-engine concern.

Inbound

type: "direct":

FieldTypeDefaultAllowed valuesDescription
networkNetworkList(tcp+udp)tcp | udp | Restrict to TCP-only or UDP-only.
override_addressstring(unset)<host>Rewrite the destination address of every accepted connection.
override_portuint16(unset)<port>Rewrite the destination port of every accepted connection.

Source: option/direct.go:10-15 · pinned at v1.13.11 (553cfa1)

Embeds ListenOptions (listen address, port, sniff, …). The Direct inbound is mostly used as a port-forwarder — accept on one port, rewrite the destination, route through any outbound.

Outbound

type: "direct":

FieldTypeDefaultAllowed valuesDescription
override_addressstring(rejected)(use route actions)Removed in sing-box 1.13. Setting it now produces a startup error pointing at route actions.
override_portuint16(rejected)(use route actions)Same as override_address — removed; use route actions.
proxy_protocoluint8(removed)0Removed entirely. Set to anything non-zero and the parser flags the deprecated-removal error.

Source: option/direct.go:17-25 · pinned at v1.13.11 (553cfa1)

The outbound now consists only of the embedded DialerOptions (bind_interface, routing_mark, detour, …). All three legacy fields above are rejected at config load:

destination override fields in direct outbound are deprecated in
sing-box 1.11.0 and removed in sing-box 1.13.0, use route options
instead

Examples

Bare direct outbound (the most common case — just give traffic an exit):

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

Direct outbound bound to a specific interface:

json
{
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct-eth0",
      "bind_interface": "eth0"
    }
  ]
}

Inbound port-forwarder (accept on 8080, rewrite destination to internal:80):

json
{
  "inbounds": [
    {
      "type": "direct",
      "tag": "forward-8080",
      "listen": "0.0.0.0",
      "listen_port": 8080,
      "override_address": "10.0.0.5",
      "override_port": 80
    }
  ]
}

Notes

  • The route-action replacement for override_address / override_port looks like:

    json
    {
      "route": {
        "rules": [
          {
            "inbound": ["forward-8080"],
            "action": "route",
            "outbound": "direct",
            "override_address": "10.0.0.5",
            "override_port": 80
          }
        ]
      }
    }

    That moves the same behavior from the protocol layer to the routing rule, which composes more cleanly with the rest of the routing surface.

Cross-core notes

  • Xray-core calls this Freedom. The outbound exposes a much richer feature set — TCP/TLS fragmentation, noise injection, the redirect field — see Freedom — Xray-core.
  • mihomo has the same minimal Direct shape and auto-injects a built-in DIRECT named proxy. See Direct — mihomo.

Source: option/direct.go:10-25 · v1.13.11 (553cfa1)

Core Tutorial by Argsment