Skip to content

Reality 探测逻辑硬编码 "tcp" 导致 UDS dest 下抗检测失效 #5675

@iliyian

Description

@iliyian

完整性要求

  • 我读完了 issue 模板中的所有注释,确保填写符合要求。
  • 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
  • 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。
  • 我搜索了 issues, 没有发现已提出的类似问题。
  • 问题在 Release 最新的版本上可以成功复现

描述

偶然翻到去年检测 reality 的那个库 aparecium,然后试了试发现现在竟然还能检测,调了好久后在 gemini 的帮助下发现可能是代码问题
record_detect.go 文件的三十行附近

https://github.com/XTLS/REALITY/blob/cd53f7d5023741301aabb5a7274ed0dd024fbd2c/record_detect.go#L30-L33

对 dest 硬编码了 tcp,根据文档,reality 的 dest 的格式同 vless fallbacks 的 dest,而 fallbacks 的 dest 可以使用uds,因此只探测 tcp 应该不是预期行为,这里应该会有 err,导致后续探测被取消。

感觉这种回落到 uds 然后偷自己的配置还蛮常见的吧((

重现方式

开启客户端和服务端,在 aparecium 文件夹内运行

go run ./main.go -addr ":10444" -remote "address:442" -victim reality

然后运行

curl https://www.google.com -x socks5://127.0.0.1:10880

然后观察结果,服务端 dest 到端口,aparecium 显示

Starting scan...

服务端 dest 到 uds,aparecium 显示,被检测了

Starting scan...
TLS camouflage connection detected

客户端配置

Details
{
  "log": {
    "loglevel": "debug",
    "dnsLog": true
  },
  "inbounds": [
    {
      "port": 10880,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "127.0.0.1",
            "port": 10444,
            "users": [
              {
                "id": "hide",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "xhttp",
        "security": "reality",
        "realitySettings": {
          "serverName": "example.com",
          "fingerprint": "chrome",
          "show": true,
          "publicKey": "hide"
        }
      },
      "tag": "proxy"
    }
  ]
}

服务端配置

Details

nginx配置

events {
    worker_connections 1024;
}

http {
    server {
        listen 127.0.0.1:81 ssl proxy_protocol;
        listen unix:/run/nginx/nginx-xray.socks ssl proxy_protocol;

        server_name example.com;

        ssl_certificate /etc/xray/example.com.crt;
        ssl_certificate_key /etc/xray/example.com.key;

        ssl_protocols TLSv1.3;

        location / {
            return 200 "REALITY Target matched!";
        }
    }
}

xray配置,两次运行仅修改 dest

{
  "log": {
    "loglevel": "debug",
    "dnsLog": true
  },
  "inbounds": [
    {
      "port": 442,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "hide"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "xhttp",
        "security": "reality",
        "realitySettings": {
          "dest": "81",
//          "dest": "/run/nginx/nginx-xray.socks",
          "show": true,
          "xver": 1,
          "privateKey": "hide",
          "shortIds": [
            ""
          ],
          "serverNames": [
            "example.com"
          ]
        }
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom"
    }
  ]
}

客户端日志

Details

下面是 dest 到端口的情况

Xray 26.2.6 (Xray, Penetrates Everything.) 12ee51e (go1.25.7 windows/amd64)
A unified platform for anti-censorship.
2026/02/09 23:47:37.138758 [Info] infra/conf/serial: Reading config: &{Name:C:\path\client.json Format:json}
2026/02/09 23:47:37.142055 [Warning] common/errors: The feature VLESS (with no Flow, etc.) is deprecated, not recommended for using and might be removed. Please migrate to VLESS with Flow & Seed as soon as possible.
2026/02/09 23:47:37.142596 [Debug] app/log: Logger started
2026/02/09 23:47:37.142596 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:10880
2026/02/09 23:47:37.144219 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:10880
2026/02/09 23:47:37.145321 [Info] transport/internet/udp: listening UDP on 127.0.0.1:10880
2026/02/09 23:47:37.145321 [Warning] core: Xray 26.2.6 started
2026/02/09 23:50:47.495714 [Info] [1804476112] proxy/socks: TCP Connect request to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:47.496816 [Info] [1804476112] app/dispatcher: default route for tcp:xx.xx.xx.xx:443
2026/02/09 23:50:47.497373 from tcp:127.0.0.1:9216 accepted tcp:xx.xx.xx.xx:443 [proxy]
2026/02/09 23:50:47.502397 [Debug] [1804476112] transport/internet/splithttp: XMUX: creating xmuxClient because xmuxClients is empty
2026/02/09 23:50:47.502931 [Info] [1804476112] transport/internet/splithttp: XHTTP is dialing to tcp:127.0.0.1:10444, mode stream-one, HTTP version 2, host example.com
2026/02/09 23:50:47.506275 [Debug] [1804476112] transport/internet: dialing to tcp:127.0.0.1:10444
REALITY localAddr: 127.0.0.1:9219       hello.SessionId[:16]: [26 2 6 0 105 138 2 87 0 0 0 0 0 0 0 0]
REALITY localAddr: 127.0.0.1:9219       uConn.AuthKey[:16]: [208 84 144 18 171 27 234 199 138 67 25 30 204 91 175 32]  AEAD: *gcm.GCM
REALITY localAddr: 127.0.0.1:9219       is using X25519MLKEM768 for TLS' communication: true
REALITY localAddr: 127.0.0.1:9219       is using ML-DSA-65 for cert's extra verification: false
REALITY localAddr: 127.0.0.1:9219       uConn.Verified: true
2026/02/09 23:50:47.905665 [Info] [1804476112] proxy/vless/outbound: tunneling request to tcp:xx.xx.xx.xx:443 via 127.0.0.1:10444

下面是 dest 到 uds 的情况

Xray 26.2.6 (Xray, Penetrates Everything.) 12ee51e (go1.25.7 windows/amd64)
A unified platform for anti-censorship.
2026/02/10 00:00:41.049940 [Info] infra/conf/serial: Reading config: &{Name:C:\path\client.json Format:json}
2026/02/10 00:00:41.053638 [Warning] common/errors: The feature VLESS (with no Flow, etc.) is deprecated, not recommended for using and might be removed. Please migrate to VLESS with Flow & Seed as soon as possible.
2026/02/10 00:00:41.053638 [Debug] app/log: Logger started
2026/02/10 00:00:41.053638 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:10880
2026/02/10 00:00:41.055796 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:10880
2026/02/10 00:00:41.055796 [Info] transport/internet/udp: listening UDP on 127.0.0.1:10880
2026/02/10 00:00:41.055796 [Warning] core: Xray 26.2.6 started
2026/02/10 00:00:53.681539 [Info] [425376449] proxy/socks: TCP Connect request to tcp:xx.xx.xx.xx:443
2026/02/10 00:00:53.681539 [Info] [425376449] app/dispatcher: default route for tcp:xx.xx.xx.xx:443
2026/02/10 00:00:53.681539 from tcp:127.0.0.1:61018 accepted tcp:xx.xx.xx.xx:443 [proxy]
2026/02/10 00:00:53.681539 [Debug] [425376449] transport/internet/splithttp: XMUX: creating xmuxClient because xmuxClients is empty
2026/02/10 00:00:53.682280 [Info] [425376449] transport/internet/splithttp: XHTTP is dialing to tcp:127.0.0.1:10444, mode stream-one, HTTP version 2, host example.com
2026/02/10 00:00:53.683353 [Debug] [425376449] transport/internet: dialing to tcp:127.0.0.1:10444
REALITY localAddr: 127.0.0.1:61021      hello.SessionId[:16]: [26 2 6 0 105 138 4 181 0 0 0 0 0 0 0 0]
REALITY localAddr: 127.0.0.1:61021      uConn.AuthKey[:16]: [88 121 251 122 88 233 191 183 131 101 42 118 251 43 158 200]       AEAD: *gcm.GCM
REALITY localAddr: 127.0.0.1:61021      is using X25519MLKEM768 for TLS' communication: true
REALITY localAddr: 127.0.0.1:61021      is using ML-DSA-65 for cert's extra verification: false
REALITY localAddr: 127.0.0.1:61021      uConn.Verified: true
2026/02/10 00:00:54.207581 [Info] [425376449] proxy/vless/outbound: tunneling request to tcp:xx.xx.xx.xx:443 via 127.0.0.1:10444

服务端日志

Details

下面是 dest 到端口的情况,可以看到有 len(postHandshakeRecord): 287

Xray 26.2.6 (Xray, Penetrates Everything.) 12ee51e (go1.25.7 linux/amd64)
A unified platform for anti-censorship.
2026/02/09 23:50:13.134350 [Info] infra/conf/serial: Reading config: &{Name:config.json Format:json}
2026/02/09 23:50:13.137183 [Warning] common/errors: The feature VLESS (with no Flow, etc.) is deprecated, not recommended for using and might be removed. Please migrate to VLESS with Flow & Seed as soon as possible.
2026/02/09 23:50:13.137786 [Debug] app/log: Logger started
2026/02/09 23:50:13.137844 [Debug] app/proxyman/inbound: creating stream worker on 0.0.0.0:442
2026/02/09 23:50:13.138063 [Info] transport/internet/splithttp: listening TCP for XHTTP on 0.0.0.0:442
2026/02/09 23:50:13.138338 [Warning] core: Xray 26.2.6 started
REALITY remoteAddr: xx.xx.xx.xx:5477
REALITY remoteAddr: xx.xx.xx.xx:5477  hs.c.AuthKey[:16]: [69 139 204 74 41 25 33 169 15 226 105 208 181 176 80 183]   AEAD: *gcm.GCM
REALITY remoteAddr: xx.xx.xx.xx:5477  hs.c.conn == conn: false
REALITY remoteAddr: xx.xx.xx.xx:5477  forwarded SNI: example.com
REALITY remoteAddr: xx.xx.xx.xx:5478
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.AuthKey[:16]: [208 84 144 18 171 27 234 199 138 67 25 30 204 91 175 32]    AEAD: *gcm.GCM
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.ClientVer: [26 2 6]
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.ClientTime: 2026-02-09 23:50:47 +0800 CST
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.ClientShortId: [0 0 0 0 0 0 0 0]
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.conn == conn: true
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 4096     Server Hello: 1215
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 2881     Change Cipher Spec: 6
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 2875     Encrypted Extensions: 47
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 2828     Certificate: 3920
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 4080     Certificate: 3920
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 160      Certificate Verify: 102
REALITY remoteAddr: xx.xx.xx.xx:5478  len(s2cSaved): 58       Finished: 58
REALITY remoteAddr: xx.xx.xx.xx:5478  is using X25519MLKEM768 for TLS' communication: true
REALITY remoteAddr: xx.xx.xx.xx:5478  is using ML-DSA-65 for cert's extra signature: false
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.handshake() err: <nil>
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.readClientFinished() err: <nil>
REALITY remoteAddr: xx.xx.xx.xx:5478  len(postHandshakeRecord): 287
REALITY remoteAddr: xx.xx.xx.xx:5478  len(postHandshakeRecord): 287
REALITY remoteAddr: xx.xx.xx.xx:5478  hs.c.isHandshakeComplete.Load(): true
2026/02/09 23:50:25.217973 [Info] [2774795519] proxy/vless/inbound: firstLen = 487
2026/02/09 23:50:25.217998 [Info] [2774795519] proxy/vless/inbound: received request for tcp:xx.xx.xx.xx:443
2026/02/09 23:50:25.218003 [Info] [2774795519] app/dispatcher: default route for tcp:xx.xx.xx.xx:443
2026/02/09 23:50:25.218065 from xx.xx.xx.xx:5478 accepted tcp:xx.xx.xx.xx:443 [direct]
2026/02/09 23:50:25.218156 [Info] [2774795519] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:25.219552 [Debug] [2774795519] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:41.226603 [Info] [2774795519] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:41.226649 [Debug] [2774795519] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:57.340335 [Info] [2774795519] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/09 23:50:57.340374 [Debug] [2774795519] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/09 23:51:13.541992 [Info] [2774795519] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/09 23:51:13.542013 [Debug] [2774795519] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/09 23:51:29.843887 [Info] [2774795519] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/09 23:51:29.843916 [Debug] [2774795519] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/09 23:51:46.248246 [Info] [2774795519] app/proxyman/outbound: app/proxyman/outbound: failed to process outbound traffic > proxy/freedom: failed to open connection to tcp:xx.xx.xx.xx:443 > common/retry: [dial tcp xx.xx.xx.xx:443: i/o timeout] > common/retry: all retry attempts failed

下面是 dest 到 uds 的情况,可以看到没有 len(postHandshakeRecord)

Xray 26.2.6 (Xray, Penetrates Everything.) 12ee51e (go1.25.7 linux/amd64)
A unified platform for anti-censorship.
2026/02/10 00:00:14.452118 [Info] infra/conf/serial: Reading config: &{Name:config.json Format:json}
2026/02/10 00:00:14.453452 [Warning] common/errors: The feature VLESS (with no Flow, etc.) is deprecated, not recommended for using and might be removed. Please migrate to VLESS with Flow & Seed as soon as possible.
2026/02/10 00:00:14.454667 [Debug] app/log: Logger started
2026/02/10 00:00:14.454810 [Debug] app/proxyman/inbound: creating stream worker on 0.0.0.0:442
2026/02/10 00:00:14.455328 [Info] transport/internet/splithttp: listening TCP for XHTTP on 0.0.0.0:442
2026/02/10 00:00:14.455346 [Warning] core: Xray 26.2.6 started
REALITY remoteAddr: xx.xx.xx.xx:5431
REALITY remoteAddr: xx.xx.xx.xx:5431  hs.c.AuthKey[:16]: [74 77 17 242 84 54 109 176 3 85 161 104 184 120 197 169]    AEAD: *gcm.GCM
REALITY remoteAddr: xx.xx.xx.xx:5431  hs.c.conn == conn: false
REALITY remoteAddr: xx.xx.xx.xx:5431  forwarded SNI: example.com
REALITY remoteAddr: xx.xx.xx.xx:5433
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.AuthKey[:16]: [88 121 251 122 88 233 191 183 131 101 42 118 251 43 158 200]        AEAD: *gcm.GCM
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.ClientVer: [26 2 6]
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.ClientTime: 2026-02-10 00:00:53 +0800 CST
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.ClientShortId: [0 0 0 0 0 0 0 0]
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.conn == conn: true
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 4096     Server Hello: 1215
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 2881     Change Cipher Spec: 6
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 2875     Encrypted Extensions: 47
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 2828     Certificate: 3920
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 4079     Certificate: 3920
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 159      Certificate Verify: 101
REALITY remoteAddr: xx.xx.xx.xx:5433  len(s2cSaved): 58       Finished: 58
REALITY remoteAddr: xx.xx.xx.xx:5433  is using X25519MLKEM768 for TLS' communication: true
REALITY remoteAddr: xx.xx.xx.xx:5433  is using ML-DSA-65 for cert's extra signature: false
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.handshake() err: <nil>
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.readClientFinished() err: <nil>
REALITY remoteAddr: xx.xx.xx.xx:5433  hs.c.isHandshakeComplete.Load(): true
2026/02/10 00:00:31.440604 [Info] [1454709825] proxy/vless/inbound: firstLen = 487
2026/02/10 00:00:31.440641 [Info] [1454709825] proxy/vless/inbound: received request for tcp:xx.xx.xx.xx:443
2026/02/10 00:00:31.440647 [Info] [1454709825] app/dispatcher: default route for tcp:xx.xx.xx.xx:443
2026/02/10 00:00:31.440651 [Info] [1454709825] transport/internet/tcp: dialing TCP to tcp:xx.xx.xx.xx:443
2026/02/10 00:00:31.440805 from xx.xx.xx.xx:5433 accepted tcp:xx.xx.xx.xx:443 [direct]
2026/02/10 00:00:31.441159 [Debug] [1454709825] transport/internet: dialing to tcp:xx.xx.xx.xx:443
2026/02/10 00:00:31.729174 [Info] [1454709825] proxy/freedom: connection opened to tcp:xx.xx.xx.xx:443, local endpoint xx.xx.xx.xx:10192, remote endpoint xx.xx.xx.xx:443
2026/02/10 00:00:31.730646 [Debug] [1454709825] proxy: CopyRawConn (maybe) readv
2026/02/10 00:00:33.097231 [Info] [1454709825] app/proxyman/outbound: app/proxyman/outbound: failed to process outbound traffic > proxy/freedom: connection ends > proxy/freedom: failed to process request > stream error: stream ID 1; CANCEL

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions