v2fly / v2ray-core

A platform for building proxies to bypass network restrictions.
https://v2fly.org
MIT License
29.48k stars 4.66k forks source link

探究 TLS 内 WebSocket 0-RTT 的可能性 #378

Closed RPRX closed 3 years ago

RPRX commented 4 years ago

背景

WebSocket 应用还是挺广泛的,之前用 v2rayNG 测试了很多次:

其它条件完全相同的情况下,WebSocket 方式比 TCP 的 HTTP 伪装慢 200-400ms(线路不是很好)。

实现

这个 0-RTT 主要取决于 CDN、Nginx 等是否支持,我觉得,至少分成两个包发送应该没有问题。

具体到客户端的实现上,可以缓存 WebSocket 协商返回的附加信息,后续相同请求直接当作响应(忽略 Sec-WebSocket-Accept)。

~WebSocketX 预定~

RPRX commented 4 years ago

~至于为何限定 TLS 内,是因为不套 TLS 会有可区别的特征,当然,如果你对着 CF 等不怕被封 IP 的用 0-RTT,也不是不可以。~

RPRX commented 4 years ago

这里顺便科普一下,v2ray 是一条请求一条 WebSocket,除非开了 Mux(不少人说 v2ray 的 Mux 有问题)

而 v2ray 的 h2 用了多路复用,即会把多条请求融合为一条 h2(但 v2ray 的 h2 似乎也性能不佳)

darhwa commented 4 years ago

有个非标准的做法,是把首个payload放在ws连接请求的header里。到底可不可行还需要测试验证。

RPRX commented 4 years ago

@darhwa

(不一定要连一起,连一起有可能不行,但不连一起应该可行)

ilpl commented 4 years ago

有个非标准的做法,是把首个payload放在ws连接请求的header里。到底可不可行还需要测试验证。

感觉不太行, 不是先响应101吗 ?

RPRX commented 4 years ago

对了,这个只需要改客户端行为,不用动服务端。

RPRX commented 4 years ago

https://github.com/gorilla/websocket/blob/c3dd95aea9779669bb3daafbd84ee0530c8ce1c1/server.go#L183-L186

或许 WebSocket 服务端主流实现都是这样,那么肯定不可以连一起了,分成两个包发送应该可行。

Jaivv commented 4 years ago

希望非TLS也能使用😀

ghost commented 4 years ago

我觉得是可行的,nginx监听443端口,设置ocsp和tcpfastopen。 反代处设置反代协议为domain socket V2Ray监听domain socket 具体配置如下: nginx:

server {
    listen 443 ssl http2 fastopen=100 reuseport;
    listen [::]:443 ssl http2 fastopen=100 reuseport;
    server_name domain.com;
    ssl_certificate         cer;
    ssl_certificate_key    key;
    ssl_protocols           TLSv1.3;
    ssl_stapling            on;
    ssl_stapling_verify     on;
    ssl_trusted_certificate cer;
    root /etc/nginx/html;
    location = /xxxxx {
        proxy_redirect off;
        proxy_pass http://unix:/dev/shm/v2_ws.sock;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
    }
}

V2Ray

{
    "log": {
        "loglevel": "none"
    },
    "inbounds": [
        {
            "listen": "/dev/shm/v2_ws.sock",
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "",
                        "level": 1
                    }
                ],
                "decryption": "none"
            },
            "streamSettings": {
                "network": "ws",
                "wsSettings": {
                    "path": "/xxxx"
                }
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom"
        }
    ]
}

这样子客户端和Nginx以及Nginx和v2ray之间都不需要tcp三次握手(domain socket应该是没有tcp三次握手的。 或者可能我对 0-RTT 有什么误解

RPRX commented 4 years ago

@kirin10000

有很大误解

ghost commented 4 years ago

@kirin10000

有很大误解

抱歉,那我删掉了

daiaji commented 3 years ago

我觉得这个可能更有用…… 毕竟现在裸连基本死路一条

wwbfred commented 3 years ago

有个疑问:为什么不考虑继续优化mux模块?这个模块好像很久都没有更新过了.现在这个模块有阻塞问题,连接数量容量及时间不可控等问题,新连接产生时的行为也让人比较迷惑,感觉有很大的改进空间. 另外现有标准协议把一切软件的可探测特征都隐藏到了一个不可知的URL之后,重新设计协议会不会引入安全问题?

kslr commented 3 years ago

Mux比较复杂,修不如换。

wwbfred commented 3 years ago

即使如此个人理解比起更改协议,关闭删除mux并重新引入一个可插拔层要更自然一些,除非有其他方面的优势. 如果愿意可以考虑引入并优化下smux,那个维护起来比mux要方便些还不需要重新造轮子.

kslr commented 3 years ago

可以,你愿意来做这块工作吗,替换为smux

wwbfred commented 3 years ago

这段时间在写文,等我忙完了手头的活如果没人开工的话我可以来搞.

ghost commented 3 years ago

我觉得这个可能更有用…… 毕竟现在裸连基本死路一条

现在的大环境,裸连不是基本,是肯定死路一条。1分钟前还能用,一分钟后就G了

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days