Top Menu

FRP从数据库获取Token和User

FRP从数据库获取Token和User

环境

目标

  • 客户端连接时查询Mysql数据库中是否存在对应用户ID
  • 若存在用户ID则从数据库中查询对应的token进行客户端验证
  • 若不存在则返回连接失败

调试

获取FRP源码

编译源码

测试运行

分析

FRP的主要入口是github.com/fatedier/frp/server/service.go

主要验证代码在第349-353行

其中调用了util.GetAuthKey函数,这个函数在github.com/fatedier/frp/utils/util/util.go中的第43-49行

综合这两段代码可以发现frp中对客户端的验证方法主要是通过获取服务器frps.ini配置文件中的token字段和timestamp组合求MD5 hash之后再进行16进制转换后再和客户端传递的PrivilegeKey值进行对比来验证。当然,客户端提交的PrivilegeKey也是这样计算的。

那么如果要接入数据库,就需要改造这个验证

通过新建验证函数,将token的获取方式从配置文件改为数据库,后续的hash和hex都继续保留即可。

但这仅仅是客户端的第一次验证环节,frp在客户端成功注册后,会马上进行控制层的数据交换,这时就会遇到第二个使用token的环节,既控制层的数据是用token加密的。

这个环节在github.com/fatedier/frp/server/control.go的第226-311行,关键行如下

可以看到,其中的加密都用到了token,也需要用新的获取token的方法更换

在这步完成之后,客户端的注册和控制数据的交互已经没有问题了,但是紧接着会出现第三个使用token的环节,既http代理有一个数据加密的选项,如果开启加密,那么将使用token对http数据流进行加密。

这个环节在github.com/fatedier/frp/server/proxy/http.go的第116行

其中的token也需要使用数据库方法替换,但是这里有一个坑,就是http.go太底层了,导致执行的时候并没有客户端的认证信息被传递到这里,所以没有办法获取用户ID。

解决方法就是在github.com/fatedier/frp/server/control.go的第427行在创建Proxy的时候手动传递一个用户ID给底层

然后在github.com/fatedier/frp/server/proxy/proxy.go的第145行接住这个用户ID

然后在后面的basePxy中增加这个用户ID字段,使得在http.go里可以调用

当然除了http外,tcp也有一个use_encryption的选项,也是用的token进行的加密,在github.com/fatedier/frp/server/proxy/proxy.go的第212行,也需要替换

可以在proxy.go增加一个函数用于调用basePxy里传递过来的用户ID

 

Know More

https://lzxz1234.cn/archives/201

There are no comments yet

  • Hello, guest

Powered by WordPress. Designed by WooThemes