TUN — Xray-core
Xray-core ships a TUN inbound at proxy/tun. It creates a TUN device, reads raw packets, and decodes them with a minimal in-process network stack before dispatching to outbounds. Historically you had to set up routes, DNS, and firewall rules yourself; recent builds add opt-in helpers — gateway, dns, autoSystemRoutingTable, and autoOutboundsInterface — that let Xray install system routing-table entries and bind outbounds to a physical interface automatically.
It is still lighter-weight than the sing-box / mihomo TUN stacks: there is no strict-route, auto-redirect, or UID/package filtering. For those, use sing-box or mihomo as a TUN front-end and route their outbound through Xray.
Inbound
settings for "protocol": "tun":
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
name | string | xray0 | <interface name> | Name of the TUN device. Created at startup. |
mtu | uint32 | 1500 | <bytes> | Maximum transmission unit for the device. |
gateway | []string | — | <ip address> | … | Gateway address(es) assigned to the TUN interface. |
dns | []string | — | <ip address> | … | DNS server address(es) configured on the TUN interface. |
userLevel | uint32 | 0 | <uint32> | Default policy level for connections received on this inbound. |
autoSystemRoutingTable | []string | — | <routing-table entry> | … | When set, Xray automatically installs system routing-table entries that steer traffic into the device. Supplying this list enables auto-routing. |
autoOutboundsInterface | *string | auto | <interface name> | auto | Physical interface that outbound connections bind to, preventing routing loops. Defaults to "auto" when autoSystemRoutingTable is set. |
Source: infra/conf/tun.go:8-16 · pinned at v26.6.1 (94ffd50)
Example
{
"inbounds": [{
"tag": "tun-in",
"protocol": "tun",
"settings": {
"name": "xray0",
"mtu": 9000
}
}]
}To let Xray manage routing itself, add autoSystemRoutingTable (and optionally pin the outbound interface):
{
"inbounds": [{
"tag": "tun-in",
"protocol": "tun",
"settings": {
"name": "xray0",
"mtu": 1500,
"autoSystemRoutingTable": ["main"],
"autoOutboundsInterface": "auto"
}
}]
}Or configure the system networking manually instead:
# Linux example
ip addr add 198.18.0.1/30 dev xray0
ip link set xray0 up
# Route everything through xray0 (skip your management subnet)
ip route add 1/1 dev xray0
ip route add 128/1 dev xray0
# DNS hijack
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-port 5353
# (then have an Xray dokodemo-door inbound on 5353)Notes
- Xray's TUN inbound is a low-level packet reader. It does not parse TCP/IP itself; instead, packets are decoded by a minimal in-process network stack and dispatched to outbounds.
- Common usage on Linux: pair with
dokodemo-doorinbounds and a hand-crafted iptables ruleset for the transparent-proxy parts, or setautoSystemRoutingTableto have Xray install the routes itself. autoSystemRoutingTablemakes Xray manage system routing-table entries automatically; when it is present andautoOutboundsInterfaceis omitted, the outbound interface defaults toauto.gatewayanddnsset the address and resolver(s) on the device.- On Windows/macOS, the Xray TUN inbound creates a wintun / utun device. With
autoSystemRoutingTableit can wire up routing for you; otherwise script it yourself. Many users on those platforms still prefer sing-box or mihomo for the richer TUN feature set.
Cross-core notes
- sing-box has a feature-complete TUN inbound with
auto_route,auto_redirect,strict_route,route_address, UID/package filtering, and per-platform stack choice (gVisor / system / mixed). See TUN — sing-box. - mihomo has an equivalent feature-complete TUN inbound at the top-level
tun:block with the same option set under kebab-case names. See TUN — mihomo.
Source: infra/conf/tun.go:8-16 · v26.6.1 (94ffd50)
