Tunnel — mihomo
mihomo offers two equivalent ways to declare a static port-forwarder: the top-level tunnels: block (legacy, supports a compact string form) or an entry under listeners: with type: tunnel.
Listener form
Entry under listeners: with type: tunnel. Embeds BaseOption (listen, port).
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
network | []string | (required) | tcp | udp | Transports to accept. Pass both as `[tcp, udp]` to expose the same forwarder on both. |
target | string | (required) | <host:port> | Destination of forwarded connections. |
Source: listener/inbound/tunnel.go:13-17 · pinned at v1.19.27 (5184081)
Top-level tunnels: block
The top-level form is concise and pre-dates the unified listeners model. Each entry is either an object or a compact string:
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
network | []string | (required) | tcp | udp | Transports to accept. Object form takes a list. |
address | string | (required) | <host:port> | Listening address. |
target | string | (required) | <host:port> | Destination. |
proxy | string | (routing default) | <proxy or group name> | Force this tunnel's traffic through a specific named proxy or group. Bypasses the rules list. |
Source: listener/config/tunnel.go:11-16 · pinned at v1.19.27 (5184081)
The compact-string form is network,address,target[,proxy] — where network is tcp, udp, or tcp/udp:
tunnels:
- tcp,127.0.0.1:5353,1.1.1.1:53 # TCP only
- udp,127.0.0.1:5353,1.1.1.1:53 # UDP only
- tcp/udp,127.0.0.1:5353,1.1.1.1:53 # both
- tcp,0.0.0.0:8080,10.0.0.10:80,VPN # forced through proxy "VPN"The object form is the same thing with keys split out:
tunnels:
- network: [tcp, udp]
address: 127.0.0.1:5353
target: 1.1.1.1:53
proxy: VPNExamples
Listener-form DNS forwarder:
listeners:
- name: dns-fwd
type: tunnel
listen: 0.0.0.0
port: 5353
network: [tcp, udp]
target: 1.1.1.1:53Top-level form: forward HTTP to an internal host via a named proxy:
proxies:
- name: VPN
type: trojan
server: vpn.example.com
port: 443
password: <password>
tunnels:
- network: [tcp]
address: 0.0.0.0:8080
target: 10.0.0.10:80
proxy: VPNNotes
- The compact-string form's
addressandtargetare both validated ashost:portliterals at parse time (listener/config/tunnel.go:53-58). A missing port produces a clear error. - Unknown values in
networkare silently skipped with a warning at startup (listener/inbound/tunnel.go:96-99). Onlytcpandudpare accepted. - The
proxyfield bypasses the rules list — the tunnel's traffic goes through the named proxy regardless ofmodeor any matchingrules:entries. Use this when you want a fixed route that is independent of normal routing. - The listener form and the
tunnels:form can coexist in the same config — they are independent.
Cross-core notes
- Xray-core uses the
dokodemo-doorprotocol with aportMapfield for multi-port forwarding in one inbound. See Dokodemo — Xray-core. - sing-box has no dedicated tunnel type — use the Direct inbound with
override_addressandoverride_port.
Source: listener/inbound/tunnel.go:13-17 · v1.19.27 (5184081)
