[fatedier/frp]多客户端privilege_mode=true好像没有效果

2023-12-10 283 views
6

我在服务端启动了privilege_mode模式,在两台服务器上运行两个客户端,两个客户端的配置文件中privilege_token设置成和服务端的一样,remote_port不一样,但是出现了只能一台设备连接到服务器,另一台日志打印如下: 2016/08/22 19:30:52 [control.go:181][E] ProxyName [privilege_web], start proxy error, ProxyName [privilege_web], this proxy is already working now 2016/08/22 19:30:52 [control.go:39][E] ProxyName [privilege_web], connect to server failed! 提示被占用了,这个是bug么。

回答

4

proxy 的 name 不能一样,[privilege_web],需要换成其他的名字。

1

按照你的解决了,不过为啥这么设计呢,多客户端每个都得改成不同的名字不是很麻烦。

7

另外请教一下,现在客户端和服务端的时间差相差很大的话客户端就会自动退出,有没有什么设置能不检查这个时间差还能继续连接。

5

@railsfans

  1. 这个名字一个是方便定位问题,也有利于之后服务端做一些统计数据的展示,还有之后的负载均衡可能也会用到。修改配置文件只是一次性的事,应该不算麻烦。另外这个名字可能之后会附加上一些其他数据,暂时还不确定。
  2. 目前还不能设置,这个主要是出于安全性方面的考虑,避免一次校验的 key 会被重复使用。不过也在考虑其他的替代方案,有什么好的建议可以提。
4

我现在想在自己的ARM板子上运用,我的ARM板子启动的时候时间是没有校正过的,还是初始化的2000年时间,所以我虽然加入了开机启动项中,但是还是直接退出。可以考虑在程序中设置一个类似C中的宏定义来决定是否启用这个时间校正的功能。

6

现在你的key怕被重复使用,key的内容可以设置成proxy 的 name,这个不是唯一的么。其他的就连接不上了。

0

你可以把 src/cmd/frps/control.go 的下面这段去掉,自己编译一下:

if nowTime-req.Timestamp > 15*60 {
    info = fmt.Sprintf("ProxyName [%s], privilege mode authorization timeout", req.ProxyName)
    log.Warn(info)
    return
}

每一个报文中用于身份验证生成的 key 是动态的,通过 proxyName + timestamp + authToken 的 md5 值得到,其中 authToken 不会在网络中传输,即使别人通过网络截获到了你的 key 值,有效期也是15分钟,之后这个 key 无法通过验证,也不会泄漏你的 authToken

3

好的,我有个问题请教一下,我从你这里下过来源码,里面有Makefile和Makefile.cross-compiles两个文件,Makefile编译出来的是哪个平台的,Makefile.cross-compiles编译出来的是哪个平台的,我用Makefile.cross-compiles编译出来了好多文件,arguments_darwin_386,calculator_darwin_386,config_file_darwin_386,git_darwin_386,arguments_darwin_amd64,calculator_darwin_amd64,config_file_darwin_amd64,git_darwin_amd64等很多后缀是不同平台的文件,哪个才是frps的客户端和服务端。

8

Makefile 里编译出来的程序取决于你当前系统环境,你在 64位 linux 下编译就是 linux amd64 的,Makefile.croos-compiles 是我用来打包要发布的各个平台的程序,你要编译其他平台的程序,推荐你用下面的命令( go 1.5 及以上版本 ):

env GOOS=linux GOARCH=amd64 go build -o ./frpc ./src/cmd/frpc
env GOOS=linux GOARCH=amd64 go build -o ./frps ./src/cmd/frps

根据你要编译的系统和架构修改 GOOSGOARCH 的值。

附:关于时间戳的验证,考虑之后的版本提供一个配置项,毕竟可能每个人对于安全性的需求不同,可以主动设置验证时间的长短或者完全关闭。

7

恩。现在调试的时候发现了一个问题,就是如果服务端没有开启的话,客户端是直接退出的,能否实现客户端不退出程序,自动延迟30s或者其他时间后重新连接服务端。

2

只有第一次启动的时候,如果连接失败会直接退出,这种情况下通常都是 server 端的地址或者端口写错了,启动之后,如果中间出现网络中断,会自动重连。

5

参考楼主的代码我在loginToServer函数中增加了如下代码,实现了第一次启动的时候也能重连不退出,楼主可以考虑加入到新版本中。

func loginToServer(cli *client.ProxyClient) (c *conn.Conn, err error) {
    var delayTime time.Duration = 1 
    // loop until reconnect to frps
    for {
        c, err = conn.ConnectServer(client.ServerAddr, client.ServerPort)
        if err == nil {
            break
        }
        log.Error("ProxyName [%s], connect to server [%s:%d] error, %v", cli.Name, client.ServerAddr, client.ServerPort, err)
        log.Info("ProxyName [%s], try to reconnect to frps [%s:%d]...", cli.Name, client.ServerAddr, client.ServerPort)

        if delayTime < 60 {
            delayTime = delayTime * 2
        }
        time.Sleep(delayTime * time.Second)
    }   
5

我的考虑是第一次连接如果失败,有很大可能性是配置错误,这种情况下由用户手动操作比较合适。

1

我看文档frps服务端重启用到了reload选项,但是实际我试了下不管用。

[root@root opt]# ./frps -c ./frps.ini --reload
Usage: 
    frps [-c config_file] [-L log_file] [--log-level=<log_level>] [--addr=<bind_addr>]
    frps --reload
    frps -h | --help
    frps -v | --version

另外我想问下这个frps最多能承受多少客户端的连接,有没有存在ngrok那样内存泄露的问题。

2

尽量在一个 issue 里解决一个问题,如果遇到 bug 和有比较好的建议可以另开一个 issue,方便管理和查看。

--reload 我在 linux 64 位环境下是 ok 的,需要你提供一下 frps 的版本以及系统架构的信息我测试一下,有可能是不同系统下处理逻辑不一致,不是很确定。

承受多少客户端的连接取决于硬件配置,网络环境,在 linux 下 go 的网络 IO 模型类似于 nginx,可以参考。至于内存泄漏以及其他问题,也不能保证没有 bug,至少我自已用着还是很稳定的。目前也只是前期开发阶段,后续还会加一些功能,进行优化,在这个过程中肯定会有相当多的问题,作为一个开源项目还是需要大家共同来完善,提意见。个人的力量毕竟是有限的,只能保证会尽力去维护。