Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SplitHTTP server: add ok padding #3614

Conversation

mmmray
Copy link
Collaborator

@mmmray mmmray commented Jul 29, 2024

Something about anti-censorship. This is the new default, and the new server is no longer compatible with xray clients older than 1.8.17:

"splithttpSettings": {
    "responseOkPadding": "100-1000"
}

if you need to stay compatible with 1.8.16, use this:

"splithttpSettings": {
    "responseOkPadding": -1
}

Only the server needs this setting.

The clientside part has been implemented in 8320732

Something about anti-censorship. Note to users, if you ever feel the
GFW, try something like this:

    "splithttpSettings": {
        "responseOkPadding": "1-100"
    }

The clientside part has been implemented in XTLS@8320732

The setting defaults to "no padding". Using the setting with any value
that is not `0` will break compatibility with Xray client 1.8.16.

At the moment I think it's not worth it to break compatibility, and
until this feature is targeted, I think most clients will have updated
beyond 1.8.16.
@mmmray
Copy link
Collaborator Author

mmmray commented Jul 29, 2024

#3603 (comment)

I think the ED part is a joke, but there is some truth to this. Response body and HTTP headers are in one packet, and so adding random HTTP response headers is actually a more backwards-compatible way of adding padding. Anyway, this works as well, there is technically no guarantee that response headers and response body are in the same packet, and later it can be "secure out of the box" without relying on correct forwarding of headers by CDN (just personal requirements)

@RPRX
Copy link
Member

RPRX commented Jul 30, 2024

By default this setting is off (no padding, compatible with 1.8.16).

At the moment I think it's not worth it to break compatibility, and until this feature is targeted, I think most clients will have updated beyond 1.8.16.

这一特性应当默认启用,默认值 100-1000,可以 break v1.8.16

@mmmray
Copy link
Collaborator Author

mmmray commented Jul 30, 2024

ok, it seems streisand is actually on 1.8.17 so it's acceptable.

@mmmray mmmray merged commit 4b7947c into XTLS:main Aug 2, 2024
36 checks passed
@mmmray mmmray deleted the oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooook branch August 2, 2024 01:16
@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

Add 的 a 没大写,不过问题不大,下次注意即可

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

我觉得还是得给 header 加 padding,虽然有不同的 host 和 path,但在同一个配置中 GET 和 POST 请求头的大小是固定的,感觉可能是没有粘着数据,此外无关配置的 POST 的回复头大小也是固定的,况且我们也不能保证 GET 回复头一定粘着数据

我想的是加一个名为 padding 的 header,这个选项两端共用,服务端还要加一个选项检查客户端的 padding 是否在指定范围内

对了,发 ok 真的有必要吗,好像客户端多写点代码就能避免了?

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

对了,发 ok 真的有必要吗,好像客户端多写点代码就能避免了?

如果是为了等 response 流才能组合出 conn,那么是没有必要的,用 channel 等 response 流就行,我就写过很多特殊的 wrapper

@mmmray
Copy link
Collaborator Author

mmmray commented Aug 2, 2024

I think this is ok, but I feel that if initial GET and POST are sent over the same physical connection, concurrently, the request size of GET and the response size of POST should not be very visible. It becomes a problem with http/1.1, but http/1.1 has many problems.

Perhaps it can be done in such a way that websocket/httpupgrade can have the same options and share the code. Early data is good but there is also no guarantee that it is sufficiently large, random, and that the response contains enough data already.

ok used to be necessary, but after 0-RTT was added (do not wait for GET 200 OK), it is no longer necessary. However, without ok I think it will be more difficult to debug why a certain CDN does not work, because it's no longer possible to curl the endpoint and distinguish between unwanted response buffering and normal operation. Instead, multiple curl calls have to be done for debugging

@mmmray
Copy link
Collaborator Author

mmmray commented Aug 2, 2024

Actually, ok can be eliminated as a feature entirely, without any padding, if the server only sends it when the first VLESS response byte can be sent. This is compatible with all existing clients already, while removing ok would now be a breaking change. I still have some concerns about debugging and I don't know which new timeouts this will trigger instead.

I will think about it some more, I don't think there is an urgent need...

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

我们把 ok 删掉吧,虽然根据一项(应该还)未发表的研究这样做更好,但若有必要,移到 VLESS 层更通用

这里要解决的是 VLESS 层触及不到的 GET & POST header 大小问题,即使是 concurrently,同配置它们的大小也是固定的,而且 POST 的 response 根本没有附加数据,还与配置无关,属于固定长度特征,这不得不加 padding 了

改成加一个 padding 选项指定 header 名和长度,两端共用,默认值为 padding100-1000,你测试下 cf 会不会转发名为 padding 的 header,如果不会的话我们就换一个会被转发的

近期服务端检测到客户端没发 padding 就发 ok,客户端检测到服务端发了 padding 就不读取 ok,可以避免 breaking

然后未来的版本服务端再加一个选项,检查客户端是否用指定的 header 发了指定长度范围内的 padding

WS 和 HU 特征本来就明显,先不管;应用数据长度是否足够随机也是 VLESS 层要用 Vision Seed 解决的问题,这里不管

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

这样干甚至兼容 v1.8.16,虽然早在 v1.8.16 就该把 ok 删掉改成 header padding

本来想把最近两个 commits 给 force 掉,想想还是算了,可以作为记录

@LearZhou
Copy link

LearZhou commented Aug 2, 2024

沒有 ok padding 的 SplitHTTP 似乎已經受到牆擊,有時會被阻斷;使用帶 ok padding 的每日構建版好很多。

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

沒有 ok padding 的 SplitHTTP 似乎已經受到牆擊,有時會被阻斷;使用帶 ok padding 的每日構建版好很多。

这倒挺难的,因为 SpiltHTTP 还没多少人用,不会被墙写针对,你这是因为 CDN 线路本来就是有时会抽风,你要优选 IP

@LearZhou
Copy link

LearZhou commented Aug 2, 2024

一開始就測試過 ok padding, 使用當時的默認值 0-100,會遇到類似的干擾,當將 padding 增加到大約 100-200 時就穩下來了。

可能確實不是牆專門針對 SplitHTTP 的,因為還不普及。但是否也有可能是觸發了牆已有的某種機制?

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

但是否也有可能是觸發了牆已有的某種機制?

至少应该没有撞上 TLS in TLS 长度特征,那个 response 太长了,而且其实 GET 的 response 占比极低,几乎全是 POST 的 response

@RPRX
Copy link
Member

RPRX commented Aug 2, 2024

至少应该没有撞上 TLS in TLS 长度特征,那个 response 太长了

不过如果只看 Server Hello 的话倒不长,内层是 TLSv1.2 的话时序特征就更明显了

@LearZhou

This comment was marked as off-topic.

@mmmray
Copy link
Collaborator Author

mmmray commented Aug 3, 2024

what do you think about client peeking ok, and if it cannot be found, backtrack and forward to the inner layer? none of the common inner protocols start with this string: vless starts with a version number, vmess starts with random bytes, I think trojan starts with hex-string (and ok is not hex)

vmess can break if the random stream starts with ascii. the probability is really low. until somebody notices, ok has been fully removed.

  1. add peeking to client
  2. in next version, remove ok from the server (or change the default of responseOkPadding)
  3. in the next version, remove ok from client

now this is independent of the padding headers, and the connection does not break if the cdn did not forward the padding headers. i'm not worried about cloudflare (we will find a header name), but otherwise, N CDN have to be tested.

@LearZhou

This comment was marked as off-topic.

@Fangliding

This comment was marked as off-topic.

@RPRX
Copy link
Member

RPRX commented Aug 5, 2024

what do you think about client peeking ok, and if it cannot be found, backtrack and forward to the inner layer? none of the common inner protocols start with this string: vless starts with a version number, vmess starts with random bytes, I think trojan starts with hex-string (and ok is not hex)

vmess can break if the random stream starts with ascii. the probability is really low. until somebody notices, ok has been fully removed.

1. add peeking to client

2. in next version, remove ok from the server (or change the default of responseOkPadding)

3. in the next version, remove ok from client

now this is independent of the padding headers, and the connection does not break if the cdn did not forward the padding headers. i'm not worried about cloudflare (we will find a header name), but otherwise, N CDN have to be tested.

这样的话 reader 要多加一层,不优雅,如果担心 cdn 不转发 header,放 cookie 和 set-cookie 里吧,一定会被转发,也叫 padding

算了,为了防止被 CDN 针对,换成 PHP 那个吧,先不开放自定义 cookie 名

@LearZhou

This comment was marked as off-topic.

@Fangliding

This comment was marked as off-topic.

@ll11l1lIllIl1lll

This comment was marked as off-topic.

@Fangliding

This comment was marked as off-topic.

@LearZhou

This comment was marked as off-topic.

@RPRX

This comment was marked as off-topic.

@LearZhou

This comment was marked as off-topic.

@RPRX

This comment was marked as off-topic.

@RPRX

This comment was marked as off-topic.

@mmmray
Copy link
Collaborator Author

mmmray commented Aug 5, 2024

@RPRX Of course it's true that almost all CDN don't have a problem with this. The header name doesn't really matter in my tests. However, I had a specific, useful setup where absolutely no headers are forwarded (Set-Cookie neither). It is obsolete now, but maybe it comes back. But maybe this entire compatibility checking code will be gone as well by then. Anyway, I'm still thinking about it (and testing some things)

The connection wrapping is of course silly, but I hope the overhead can be as small as this one. And eventually that wrapper can be removed as well.

mmmray added a commit to mmmray/Xray-core that referenced this pull request Aug 5, 2024
mmmray added a commit to mmmray/Xray-core that referenced this pull request Aug 5, 2024
1. "ooook" handling on client is removed entirely, since there is no
   released version of xray-server that actually writes variable-length
   "ok"

   This partially reverts commit
   4b7947c
   (XTLS#3614)

2. X-Padding header is added to every request and response (in fact, all
   of them have length characteristics if the transported protocol has
   length characteristics already. it can be reduced once VLESS adds its
   own padding, but I thought it's best to stay independent of VLESS and
   also handle other inner layers)

3. The client reads two bytes, and if those are != "ok", forwards them
   to VLESS/Trojan.

I think this is the simplest way to deal with this. If headers are used
for communication, then browser dialer has to be adjusted as well (may
be done in later PR)
mmmray added a commit to mmmray/Xray-core that referenced this pull request Aug 5, 2024
1. "ooook" handling on client is removed entirely, since there is no
   released version of xray-server that actually writes variable-length
   "ok"

   This partially reverts commit
   4b7947c
   (XTLS#3614)

2. X-Padding header is added to every request and response (in fact, all
   of them have length characteristics if the transported protocol has
   length characteristics already. it can be reduced once VLESS adds its
   own padding, but I thought it's best to stay independent of VLESS and
   also handle other inner layers)

3. The client reads two bytes, and if those are != "ok", forwards them
   to VLESS/Trojan.

I think this is the simplest way to deal with this. If headers are used
for communication, then browser dialer has to be adjusted as well (may
be done in later PR)
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.

5 participants