e1732a364fed / v2ray_simple

a verysimple proxy
MIT License
529 stars 105 forks source link

【BUG】服务器 v2ray_simple grpc 时,部分终端无法通过代理连上 ssh #240

Open 5l2 opened 1 year ago

5l2 commented 1 year ago

环境

描述

使用 v2ray_simple 作为代理服务器且协议为 trojan+grpc+tls 时,部分终端(如 mobaxterm)通过代理连接 ssh 会卡在终端画面(光标原地闪烁),无法登录。

作为实验,部署 v2ray/hysteria/naiveproxy 等不同应用、为 v2ray_simple 增加 vmess+ws+tls+cdn 的协议组合,接着使用 clash 的 tunnel 功能通过前述代理将服务器 ssh 端口映射到本地不同端口,最后使用 nc/telnet 连接这些本地端口。现象如下。

组 1(对照):无代理直连服务器 ssh 端口

使用 nc/telnet 直连服务器 ssh 端口,会打印版本信息。如:

SSH-2.0-OpenSSH_8.4p1 Debian-5+deb11u1

组 2:使用 hysteria/naiveproxy 作为代理服务器

使用 nc/telnet 连接映射后的本地端口,会打印版本信息。

组 3:使用 v2ray 作为代理服务器,协议为 trojan+grpc+tls

使用 nc/telnet 连接映射后的本地端口,会打印版本信息。

组 4:使用 v2ray_simple 作为代理服务器,协议为 vmess+ws+tls+cdn

使用 nc/telnet 连接映射后的本地端口,会打印版本信息。

组 5:使用 v2ray_simple 作为代理服务器,协议为 trojan+grpc+tls

使用 nc/telnet 连接映射后的本地端口,卡在终端画面(光标原地闪烁),不打印任何字符。

测试发现,若在卡住时键入任何按键,则又会打印版本信息。

如何复现

  1. 搭建 web 服务器作为反向代理。
  2. 搭建 v2ray_simple,协议为 trojan+grpc

    cat vs_config.toml
    
    [app]
    loglevel = 2
    logfile = "/var/log/verysimple/error.log"
    default_uuid = ************
    [[listen]]
    protocol = "trojan"
    #uuid = ************
    users = ************
    ip = "[::1]"
    port = 8080
    adv = "grpc"
    path = "string"
    [[dial]]
    protocol = "direct"
    fullcone = false
    
  3. 安装 clash 客户端。

    cat clash.yaml
    
     - name: clash
       server: 233.252.0.1
       port: 443
       type: trojan
       password: ************
       network: grpc
       sni: example.org
       skip-cert-verify: false
       udp: true
       grpc-opts:
         grpc-service-name: "string"
    
  4. 安装 mobaxterm,新建 ssh 连接,配置使用代理。
  5. 登录 ssh。

日志

v2ray_simple debug 级日志

cat error.log

{"L":"WARN ","T":"230129 160942.072","M":"Failed in reading first payload, not because of timeout, will hung up","connid":852675,"target":"233.252.0.1:22","error":"EOF"}
{"L":"WARN ","T":"230129 161008.953","M":"Failed in reading first payload, not because of timeout, will hung up","connid":852675,"target":"233.252.0.1:22","error":"EOF"}
{"L":"INFO ","T":"230129 161038.471","M":"Program started","loglvl":0}
{"L":"INFO ","T":"230129 161038.473","M":"zap log init complete.","logfile":"/var/log/verysimple/error.log"}
{"L":"INFO ","T":"230129 161038.473","M":"verysimple [ commit: ff93818, all_go_files_md5: ************  -, tags: ], go1.19.4 linux amd64, with advLayer packages: [quic grpcSimple ws] \n"}
{"L":"INFO ","T":"230129 161038.474","M":"Working at","dir":"/"}
{"L":"DEBUG","T":"230129 161038.474","M":"All Given Flags","flags":{"c":"my string representation"}}
{"L":"INFO ","T":"230129 161038.476","M":"Options","Log Level":"debug","UseReadv":true}
{"L":"INFO ","T":"230129 161038.478","M":"Starting..."}
{"L":"INFO ","T":"230129 161038.479","M":"Listening","tag":"","protocol":"grpc+trojan","listen_addr":"[::1]:8080","defaultClient":"dual+direct","dial_addr":""}
{"L":"INFO ","T":"230129 161041.230","M":"New Accepted Conn","connid":816535,"from":"[::1]:45754","handler":"grpc+trojan://[::1]:8080/string"}
{"L":"DEBUG","T":"230129 161124.585","M":"Default Route","connid":816535,"source":"233.252.0.1:22","client":"dual+direct","addr":""}
{"L":"INFO ","T":"230129 161124.588","M":"Request","connid":816535,"From":"[::1]:45754","Target":"tcp://233.252.0.1:22","through":"dual+direct://"}
{"L":"DEBUG","T":"230129 161124.588","M":"handshake client with first payload","connid":816535,"len":1}
{"L":"DEBUG","T":"230129 161124.849","M":"TryCopy","id":816535,"from":"*net.TCPConn","->":"*trojan.UserTCPConn"}
{"L":"DEBUG","T":"230129 161124.852","M":"copying with readv","id":816535}
{"L":"DEBUG","T":"230129 161124.851","M":"TryCopy","id":816535,"from":"*trojan.UserTCPConn","->":"*net.TCPConn"}
{"L":"DEBUG","T":"230129 161124.853","M":"copying with classic method","id":816535}
{"L":"DEBUG","T":"230129 161126.640","M":"Relay End","id":816535,"direction":"R->L","target":"233.252.0.1:22","bytes":76,"error":"EOF"}
{"L":"DEBUG","T":"230129 161126.643","M":"Relay End","id":816535,"direction":"L->R","target":"233.252.0.1:22","bytes":2,"error":"readfrom tcp 233.252.0.2:48854->233.252.0.1:22: body closed by handler"}

解决

经研究发现,若将 mobaxterm 等终端的协议版本auto 变更为 SSHv2 可解决 v2ray_simple 使用 trojan+grpc+tls 时无法通过代理连上 ssh 的问题。此时可正常登录。

但是,此方案不能解决使用 nc/telnet 连接 ssh 映射后的本地端口,不打印版本信息的问题。

5l2 commented 1 year ago

应该是 v2ray_simple 读取 first payload 的机制导致了以上 nc/telnet 的现象?

e1732a364fed commented 1 year ago

有可能,需详查

lw4free commented 1 year ago

应该还是grpc服务器端的bug没有完全修复 https://github.com/e1732a364fed/v2ray_simple/issues/159#issue-1402217771

e1732a364fed commented 1 year ago

在vs的 grpc server 收到grpc握手后,确实,如果客户端没发任何信息,就会陷入等待中.

我看了一下代码,忘 Flush了。

e1732a364fed commented 1 year ago

我在最新代码里加了 flush, 请你用最新代码编译并再试一次,然后看看如何

5l2 commented 1 year ago

已按组 5 条件测试,依旧不打印 ssh 服务器版本信息。

执行的编译命令:

sudo snap install go --classic
git clone https://github.com/e1732a364fed/v2ray_simple
cd v2ray_simple/cmd/verysimple/
go build

./verysimple -v:

verysimple [version_undefined], go1.19.5 linux amd64, with advLayer packages: [quic grpcSimple ws]
HeXis-YS commented 1 year ago

虽然没有经过严格的测试,但是在我的配置(从gRPC回落到TCP)下也会有类似的行为。