Skip to content

Comments

Finalmask: Add XICMP (relies on mKCP/QUIC or WireGuard)#5633

Merged
RPRX merged 9 commits intoXTLS:mainfrom
LjhAUMEM:icmp
Feb 2, 2026
Merged

Finalmask: Add XICMP (relies on mKCP/QUIC or WireGuard)#5633
RPRX merged 9 commits intoXTLS:mainfrom
LjhAUMEM:icmp

Conversation

@LjhAUMEM
Copy link
Contributor

@LjhAUMEM LjhAUMEM commented Feb 1, 2026

无 mtu 限制,quic 也可使用

需要 root 或者 CAP_NET_RAW 权限

逻辑与 xdns 相似,一发一收,但有两个区别

  1. 抛弃了服务端的合包逻辑,也不需要
  2. 面对空 echo 服务端只在有数据时才回复

目前两个配置项

ip: 监听的 ip,默认 0.0.0.0
id: 只接收指定 echo.ID 的数据,不设置可能看到大量噪声

另外如果服务端机器内核没关闭对 icmp echo 的 reply 客户端就会看到两个 reply,一个来自内核一个来自 xray,用户态程序决定不了内核行为,你可能希望关闭内核的回复,当然不关闭对 xray 也是没影响的

sysctl -w net.ipv4.icmp_echo_ignore_all=1
sysctl -w net.ipv6.icmp.echo_ignore_all=1

配置示例

{
  "log": { "loglevel": "debug" },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 1080,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "address": "a.com",
        "port": 1081,
        "id": "5783a3e7-e373-51cd-8642-c83782b807c5",
        "encryption": "none"
      },
      "streamSettings": {
        "network": "kcp",
        "finalmask": {
          "udp": [
            {
              "type": "xicmp",
              "settings": {
                "id": 1234
              }
            }
          ]
        }
      }
    }
  ]
}
{
  "log": { "loglevel": "debug" },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 1081,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "5783a3e7-e373-51cd-8642-c83782b807c5"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "kcp",
        "finalmask": {
          "udp": [
            {
              "type": "xicmp",
              "settings": {
                "id": 1234
              }
            }
          ]
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom"
    }
  ]
}

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

不过也还是玩具,光是看长度就可以杀死游戏,更不用说回复的 echo.Data 与来源的不一致

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

无 mtu 限制,quic 也可使用

这是因为 XICMP 自带分包还是就是不限制?

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

这是因为 XICMP 自带分包还是就是不限制?

分包和 pktConn 一样交由 IP 层处理了,程序收到的是组好的,测试发 8000 那边也能收到 8000,就是丢包严重

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

XICMP 没有自带分包就行,finalmask udp 部分的理念就是“仅伪装、不可靠传输”

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

你那里测试 XHTTP+REALITY 新版本正常吗,群里有几个说有问题的,如果要 fix 的话今天正好再发一版

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

你那里测试 XHTTP+REALITY 新版本正常吗,群里有几个说有问题的,如果要 fix 的话今天正好再发一版

还没更新客户端,晚点我测试下

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

抛弃了服务端的合包逻辑,也不需要

XDNS 服务端有合包逻辑?

面对空 echo 服务端只在有数据时才回复

XDNS 也能这样吗

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

XDNS 服务端有合包逻辑?

会尽量把包在限制内塞在一个 txt 记录里

XDNS 也能这样吗

不建议,xicmp 不需要经过公共服务器转发,行为可以自己管理,xdns 如果不发空响应可能让转发服务器做出未知行为

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

重新看了下 rfc echo id 和 echo seq 是两字节,api 给的 int 还以为是四字节,那还需要小改下

@Fangliding
Copy link
Member

反正代码里取的 uint16() 最后都会截断到uint16去 不会报错

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

能用是能用,但是会多占两个字节 现在用的是在 echo.Data 前面塞上 id 来区分数据 reply 和内核 reply,不知道还有没有什么好办法

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

你那里测试 XHTTP+REALITY 新版本正常吗,群里有几个说有问题的,如果要 fix 的话今天正好再发一版

还没更新客户端,晚点我测试下

似乎是 break 了,xhttp reality 只配置 path mode 连不上旧版,只是卡住没有报错,还没看是什么原因,得再晚点

mode pactet-up stream-one stream-up 单独配置都可以连上,就 auto 不行

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

不知道还有没有什么好办法

因为 linux 内核对 icmp echo 默认会回相同的 echo.Data,所以客户端会收到两份 reply,一份的 echo.Data 为发送过去的,一份为 xray 返回的,所以要确保返回的前 n 个字节与发送的前 n 个字节不同才能区分

想了一下可以随机一个字节塞前面,记录下 seq 与这个字节,返回再随机一个与这个不同的,就能区分了,或者直接用固定的 msg.Type 塞前面也可以

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

这样特征更明显了不好吧,又不是服务端 Linux 没发

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

这样特征更明显了不好吧,又不是服务端 Linux 没发

那就只能用随机了,关闭了 linux内核的自动回复就不会有这个问题,但总得适配不关闭的

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

特征光长度就解决不了,所以也差不多

@Fangliding
Copy link
Member

echo request的响应和请求不一样本身就是特征了(

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

echo request的响应和请求不一样本身就是特征了(

那还加啥随机,内容一样的响应直接丢弃不就行了

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

上层 mKCP 应该不会往返包内容一样吧,不知道它有没有心跳包会一样,反正 QUIC 肯定不一样

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

那不得还是记录下发了啥然后 bytes.Equal,只记第一个字节就好了

上层 mKCP 应该不会往返包内容一样吧,不知道它有没有心跳包会一样,反正 QUIC 肯定不一样

这个不影响,就是有一份回复是和发出去的一样(来自 linux内核)

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

那假如上层 mKCP 或什么的心跳包往返都是 0x00... 这样呢

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

上层一样没事,区别出是来自 linux 还是 xray 就可以,所以塞 n 个字节到前面,来自 xray 这 n 个会变

@RPRX
Copy link
Member

RPRX commented Feb 1, 2026

那就加一个随机字节然后响应包随机到一个不一样的吧(for),明天再发版吧

@Fangliding
Copy link
Member

话说你有想过过了nat之后id出去会不一样吗 然后双端设成一样的最后还是给扔了

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 1, 2026

不确定 nat 转发 icmp 是什么行为,应该没理由去碰 id,不过作为服务端回相同的 id seq 上没问题

如果 id 在转发会变那只能靠 echo.Data 上加一层自己的头来确认,这样就没 id 方便

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 2, 2026

重构了下加了个 seqStatus,在轮转(poll)空 echo.Data 的情况下则不需要加字节区分

以及修改在客户端有数据时直接记录数据里的第一个字节,服务端生成一个不同的在前面,此前是客户端也生成一个在前面

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 2, 2026

icmp 对端只有 ip 信息,原始 kcp 可以根据 ip port 来区分不同 session,改了下把 id 作为 port 模拟了这一行为,但还是有点区别,id 可以自定义,port 的话只会被一个监听

不过理论上不模拟也没事,因为即使单IP多客户端 单个客户端也只会接收自己的那一个 id 数据,但尽量完美吧

@RPRX RPRX changed the title xicmp Finalmask: Add XICMP (relies mKCP or QUIC) Feb 2, 2026
@RPRX RPRX merged commit e7cbe17 into XTLS:main Feb 2, 2026
39 checks passed
@RPRX RPRX changed the title Finalmask: Add XICMP (relies mKCP or QUIC) Finalmask: Add XICMP (relies mKCP or QUIC or WireGuard) Feb 2, 2026
@RPRX RPRX changed the title Finalmask: Add XICMP (relies mKCP or QUIC or WireGuard) Finalmask: Add XICMP (relies mKCP/QUIC or WireGuard) Feb 2, 2026
@RPRX
Copy link
Member

RPRX commented Feb 2, 2026

#5639 有人问 Finalmask 是否支持 WG 你测一下(有原生 UDP 特性),应该比 Amnezia 那个灵活很多吧

还有 SS AEAD/2022 的 UDP 你也测一下,VLESS Encryption 以后也要出原生 UDP

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 2, 2026

#5639 有人问 Finalmask 是否支持 WG 你测一下(有原生 UDP 特性),应该比 Amnezia 那个灵活很多吧

找了一下终于看到客户端使用 dialer 的地方 netBindClient,我测试下

还有 SS AEAD/2022 的 UDP 你也测一下,VLESS Encryption 以后也要出原生 UDP

ss 之前看过应该问题不大,话说 2022 真的不重新实现下吗

@RPRX
Copy link
Member

RPRX commented Feb 2, 2026

ss 之前看过应该问题不大,话说 2022 真的不重新实现下吗

我没有兴趣,你有兴趣的话你来

@LjhAUMEM
Copy link
Contributor Author

LjhAUMEM commented Feb 2, 2026

奇怪,为什么搭的 wg 入站都不通,哪里有问题吗

{
  "log": { "loglevel": "debug" },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 1080,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "wg-in",
      // "listen": "127.0.0.1",
      "port": 1081,
      "protocol": "wireguard",
      "settings": {
        "secretKey": "uJv5tZMDltsiYEn+kUwb0Ll/CXWhMkaSCWWhfPEZM3A=",
        "peers": [
          {
            "publicKey": "6e65ce0be17517110c17d77288ad87e7fd5252dcc7d09b95a39d61db03df832a"
          }
        ]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "wireguard",
      "settings": {
        "secretKey": "uJv5tZMDltsiYEn+kUwb0Ll/CXWhMkaSCWWhfPEZM3A=",
        "address": ["10.1.1.1", "fd59:7153:2388:b5fd:0000:0000:1234:0001"],
        "peers": [
          {
            "publicKey": "6e65ce0be17517110c17d77288ad87e7fd5252dcc7d09b95a39d61db03df832a",
            "endpoint": "127.0.0.1:1081"
          }
        ],
        "noKernelTun": true
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    }
  ],
  "routing": {
    "rules": [
      {
        "inboundTag": ["wg-in"],
        "outboundTag": "direct"
      }
    ]
  }
}

@RPRX RPRX changed the title Finalmask: Add XICMP (relies mKCP/QUIC or WireGuard) Finalmask: Add XICMP (relies on mKCP/QUIC or WireGuard) Feb 2, 2026
@RPRX
Copy link
Member

RPRX commented Feb 2, 2026

@LjhAUMEM Project X NFT https://etherscan.io/tx/0x65731430636ec0673e1763af01646db238f789c324dbfa321de2b3911f6fc97c

既然有人测 WireGuard 了不如把它的出入站问题和 FullCone 问题一起修了吧,已经有很多研究了,Hy2 入站不急

Finalmask 的下一步计划你看一下 https://t.me/projectXtls/1473

目前有人提到 MQTT、RDP、FakeSIP、Kafka,还有 STOMP https://t.me/projectXray/4633462 https://t.me/projectXray/4633467

Email 放草稿箱不发的话是 XDRIVE 的范畴,传输层,这种用别人家可靠服务的最好自带少点浪费的可靠传输和间隔控制吧,也没人指望它能有原生 UDP 特性吧,发 Email 的话还不确定该放到 transport 还是 finalmask,还是取决于频率吧 finalmask 是高频

其实我觉得一个 header-custom 就能解决大部分问题,要不你先加一下它,TCP/UDP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants