Skip to content

Dokodemo-door — Xray-core ​

Dokodemo (Japanese for "any-door") is Xray's transparent-proxy inbound. It listens on one or more ports and forwards every accepted connection to a fixed destination — or, on Linux, to the connection's original pre-NAT destination via SO_ORIGINAL_DST / IP_TRANSPARENT.

Inbound ​

settings for an inbound of "protocol": "dokodemo-door":

FieldTypeDefaultAllowed valuesDescription
allowedNetwork*NetworkList(any)tcp | udp | tcp,udpTransport protocols the inbound accepts. Canonical name for the legacy network field.
rewriteAddress*Address(unset)<host>Destination address forwarded traffic is rewritten to. Used when portMap does not match and followRedirect is false. Canonical name for the legacy address field.
rewritePortuint160<port>Destination port for forwarded traffic. Canonical name for the legacy port field.
network*NetworkList(alias)(alias of allowedNetwork)Legacy alias for allowedNetwork; if set it overrides it at build time.
address*Address(alias)(alias of rewriteAddress)Legacy alias for rewriteAddress; copied over at build time.
portuint16(alias)(alias of rewritePort)Legacy alias for rewritePort.
portMapmap[string]string{}{<src-port>: <host:port>}Per-port destination overrides. Keys are listening ports (as strings); values are host:port literals. Each value is validated at config build.
followRedirectboolfalsetrue | falseRead the original destination from the OS (Linux iptables SO_ORIGINAL_DST / tproxy). When true, address/port become the fallback target if recovery fails.
userLeveluint320<uint32>Default policy level applied to forwarded connections.

Source: infra/conf/dokodemo.go:10-20 · pinned at v26.9.9 (52a412d)

Examples ​

Static port-forwarder — accept on :5353 and forward to 1.1.1.1:53:

json
{
  "inbounds": [
    {
      "tag": "dns-forward",
      "listen": "0.0.0.0",
      "port": 5353,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "1.1.1.1",
        "port": 53,
        "network": "tcp,udp"
      }
    }
  ]
}

Per-port mapping — accept on multiple ports and forward each to a different destination:

json
{
  "inbounds": [
    {
      "tag": "multi-forward",
      "listen": "0.0.0.0",
      "port": "80,443,5353",
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "portMap": {
          "80":   "10.0.0.10:80",
          "443":  "10.0.0.10:443",
          "5353": "1.1.1.1:53"
        }
      }
    }
  ]
}

Linux transparent-proxy receiver:

json
{
  "inbounds": [
    {
      "tag": "tproxy",
      "listen": "0.0.0.0",
      "port": 12345,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "streamSettings": {
        "sockopt": { "tproxy": "tproxy" }
      }
    }
  ]
}

Notes ​

  • allowedNetwork / rewriteAddress / rewritePort are the canonical names; network / address / port are accepted as aliases and copied onto the canonical fields at build time. The examples on this page use the alias names; configs can use either set.
  • portMap values that are not valid host:port literals fail at startup (infra/conf/dokodemo.go:39-43).
  • For followRedirect: true to recover the original destination, the listening socket needs IP_TRANSPARENT (TPROXY) or the inbound must be the iptables REDIRECT target. Set this via streamSettings.sockopt.tproxy.
  • followRedirect together with sockopt.tproxy is also supported on OpenBSD.
  • When neither address/port nor portMap match and followRedirect cannot recover a destination, the connection is closed.
  • The inbound's listening port field on the parent inbound object accepts both a single port and a comma-separated list ("80,443") or range ("5000-5010") — the standard inbound port-list syntax.

Cross-core notes ​

  • sing-box does not have a dedicated dokodemo struct. Use the Direct inbound — its override_address / override_port fields cover the static-target case, and TPROXY mode is enabled via tcp_fast_open / sniff options at the inbound level.
  • mihomo offers two flavors: an entry under listeners: with type: tunnel, or the top-level tunnels: block with a compact comma-separated string form. See Tunnel — mihomo.

Source: infra/conf/dokodemo.go:10-20 · v26.9.9 (52a412d)

Core Tutorial by Argsment