Skip to content

Bridge — sing-box ​

bridge is the L3 counterpart of the direct outbound. Instead of opening sockets, it forwards L3 traffic — TCP, UDP and ICMP — arriving from a TUN inbound or another L3 endpoint (WireGuard, Tailscale) straight out of a network interface, without translating it to L4 connections first.

Privileges and platforms

bridge requires elevated privileges and is only available on Linux, macOS, Windows (x86 / x64, via WinDivert), rooted Android and jailbroken iOS; on any other platform the outbound fails at startup. In the graphical clients it needs the standalone macOS build with its helper service, root on Android, or a jailbroken iOS device.

Outbound options ​

type: "bridge" under outbounds[]:

FieldTypeDefaultAllowed valuesDescription
interfacestring(default interface)<interface name>Egress interface for forwarded traffic. The default interface is used when unset; traffic is dropped while the chosen interface is unavailable.
bridge_namestringbridge<name prefix>Name prefix of the bridge TUN interface that sing-box creates. Not effective on Apple platforms.
iproute2_table_indexint2200 + instance index<int>Linux only, and only when interface is set: iproute2 routing-table index for the pinned egress routes.
iproute2_rule_indexint100<int>Linux only: starting index of the iproute2 rules the bridge installs.

Source: option/bridge.go:3-8 · pinned at v1.14.2 (af6e64c)

Examples ​

Forward LAN-bound traffic captured by TUN at L3 through bridge, and send everything else through direct:

json
{
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "address": ["172.19.0.1/30"],
      "auto_route": true
    }
  ],
  "outbounds": [
    { "type": "direct", "tag": "direct" },
    { "type": "bridge", "tag": "bridge-out" }
  ],
  "route": {
    "rules": [
      {
        "ip_cidr": ["192.168.0.0/16"],
        "preferred_by": ["bridge-out"],
        "outbound": "bridge-out"
      }
    ],
    "final": "direct"
  }
}

Notes ​

  • bridge only carries L3 traffic. It is reached through a route action that matches during pre-match on an L3 inbound (TUN, WireGuard, Tailscale). Connections from L4 inbounds (SOCKS, HTTP, …), or routed by rules that only match after pre-match, fail with only L3 traffic is supported by bridge.
  • Destinations local to the machine — loopback, unspecified, or any address assigned to its own interfaces — are rejected with a warning. Exclude them in your rules.
  • preferred_by: ["<bridge tag>"] is the recommended gate: for a bridge it matches every non-local destination, and only in pre-match, so it never captures traffic that bridge cannot handle.
  • bridge can also be the default outbound: when no rule matches in pre-match, L3 forwarding still applies (for outbound groups, the currently selected member is used). L4 connections that reach it are rejected.
  • FakeIP destinations must be resolved with a resolve action during pre-match, otherwise the connection is rejected.
  • For ICMP, direct can also forward at L3; for TCP and UDP only bridge and the WireGuard / Tailscale endpoints can.

Cross-core notes ​

  • Xray-core and mihomo have no L3-forwarding outbound: their TUN inbounds always terminate TCP / UDP and re-dial through an outbound (Xray's freedom, mihomo's DIRECT). See TUN — Xray-core and TUN — mihomo.

Source: option/bridge.go:3-8 · v1.14.2 (af6e64c)

Core Tutorial by Argsment