Redirect & TProxy — sing-box
sing-box has two dedicated inbound types for Linux transparent proxying: redirect (iptables REDIRECT, TCP only) and tproxy (iptables/nftables TPROXY, TCP+UDP).
type: "redirect"
json
{
"inbounds": [{
"type": "redirect",
"tag": "redir-in",
"listen": "127.0.0.1",
"listen_port": 12345
}]
}Only the embedded ListenOptions fields apply (listen, listen_port, tcp_fast_open, netns, …). REDIRECT is TCP only.
Pair with iptables:
sh
iptables -t nat -N SING_BOX
iptables -t nat -A SING_BOX -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SING_BOX -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SING_BOX -p tcp -j REDIRECT --to-ports 12345
iptables -t nat -A OUTPUT -p tcp -j SING_BOXtype: "tproxy"
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
network | NetworkList | (tcp+udp) | tcp | udp | | Restrict to TCP-only or UDP-only. TPROXY supports both; REDIRECT is TCP-only. |
udp_mapping | UDPNATBehavior | endpoint_independent | endpoint_independent | address_dependent | address_and_port_dependent | UDP NAT mapping: reuse one mapping per source address and port for all destinations (default), or a separate mapping per destination address / address and port. |
udp_filtering | UDPNATBehavior | endpoint_independent | endpoint_independent | address_dependent | address_and_port_dependent | UDP NAT filtering: accept packets from any remote endpoint (default), or only from addresses / address-and-port pairs already sent to. |
udp_nat_max | uint32 | 0 (auto) | <uint32> | Maximum number of UDP NAT sessions; the least recently used one is closed when full. 0 means 4096 on iOS, otherwise 4096–16384 based on total memory (16384 if it can't be detected). |
Source: option/redir.go:7-13 · pinned at v1.14.2 (af6e64c)
Plus the embedded ListenOptions.
json
{
"inbounds": [{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "0.0.0.0",
"listen_port": 12345,
"network": "tcp,udp"
}]
}The matching iptables mangle rules:
sh
iptables -t mangle -N SING_BOX
iptables -t mangle -A SING_BOX -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A SING_BOX -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A SING_BOX -m mark --mark 0x100 -j RETURN
iptables -t mangle -A SING_BOX -p tcp -j TPROXY --on-port 12345 --tproxy-mark 0x1
iptables -t mangle -A SING_BOX -p udp -j TPROXY --on-port 12345 --tproxy-mark 0x1
iptables -t mangle -A PREROUTING -j SING_BOX
ip rule add fwmark 0x1 table 100
ip route add local 0.0.0.0/0 dev lo table 100The escape mark (0x100 above) should match a corresponding fwmark on sing-box's outbound sockets — set via the outbound's routing_mark field or route.default_mark.
Notes
- Both inbound types need
CAP_NET_ADMIN. Run sing-box as root or set the capability on the binary withsetcap. tproxyis preferred for new setups because it handles UDP and works without NAT translation (the original destination is read cleanly from the socket).- These are Linux-only inbound types. On other platforms, use TUN for transparent proxying.
Cross-core notes
- Xray-core uses the Dokodemo-door inbound with
streamSettings.sockopt.tproxyto achieve the same. See Redirect/TProxy — Xray-core. - mihomo has the same kernel-side mechanics under top-level
redir-port/tproxy-portshortcuts andlisteners:entries withtype: redir/type: tproxy. See Redirect/TProxy — mihomo.
Source: option/redir.go:7-13 · v1.14.2 (af6e64c)
