找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 318|回复: 0

FRP 更改多 Token 支持

[复制链接]

28

主题

1

回帖

148

积分

管理员

积分
148
发表于 2024-8-20 09:24:41 | 显示全部楼层 |阅读模式
2018年7月5日

FRP 更改多 Token 支持 – Lzxz1234 的小站
简介
之前一直用 Ngrok,但 Ngrok 有比较严重的内存泄露问题,经常无故退出。所以最近更改到了 frp。
frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。
由于 frp 默认只支持一个 token,这样当 token 泄露更改时会导致全部客户端不可用,所以就有了本次修改。
过程
先 fork 代码库 https://github.com/fatedier/frp,简单阅读后可知,登录时 token 校验逻辑位于 server/service.go 文件中第 320 行:
  1. if util.GetAuthKey(g.GlbServerCfg.Token, loginMsg) != loginMsg.PrivilegeKey {
复制代码

所以我们可以新建 server/auth.go 主要处理授权逻辑:
  1. package server

  2. import (
  3.     "database/sql"
  4.     "github.com/fatedier/frp/models/msg"
  5.     "github.com/fatedier/frp/utils/util"
  6.     _ "github.com/mattn/go-sqlite3"
  7. )

  8. var db *sql.DB

  9. type User struct {
  10.     UserName string
  11.     Token string
  12. }

  13. func GetAuthKey(loginMsg *msg.Login) (key string) {

  14.     user := GetUser(loginMsg.User)
  15.     key = util.GetAuthKey(user.Token, loginMsg.Timestamp)
  16.     return
  17. }

  18. func GetToken(loginMsg *msg.Login) (key string) {

  19.     user := GetUser(loginMsg.User)
  20.     key = user.Token
  21.     return
  22. }

  23. func GetUser(userName string) (user User) {

  24.     if db == nil {
  25.         db, _ = sql.Open("sqlite3", "/sqlite3.db")
  26.         db.Exec("create table if not exists user(user_name varchar(128), token varchar(128))")
  27.     }

  28.     stmt, _ := db.Prepare("SELECT user_name, token FROM user where user_name = ?")
  29.     defer stmt.Close()
  30.     rows, _ := stmt.Query(userName)
  31.     defer rows.Close()

  32.     if rows.Next() {
  33.         rows.Scan(&user.UserName, &user.Token)
  34.     }
  35.     return
  36. }
复制代码

此处将用户信息存储在了 sqlite3 中,同时将用户做成实体,后续可以根据用户限制代理类型个数等。同时由于引用了 github.com/mattn/go-sqlite3 包,所以也需要在 vendor 目录里添加对应包。
其它修改
除了登录时的 token 校验,还有其它地方也需要同步修改,主要是 server/control.go 和 server/proxy.go,这两个文件的修改主要用于替换 token 的获取逻辑,由全局获取改为数据库获取:
control.go
212 行改为:
  1. encWriter, err := crypto.NewWriter(ctl.conn, []byte(GetToken(ctl.loginMsg)))
复制代码

242 行改为:
  1. encReader := crypto.NewReader(ctl.conn, []byte(GetToken(ctl.loginMsg)))
复制代码

311 行改为:
  1. rwc, err = frpIo.WithEncryption(rwc, []byte(GetToken(pxy.ctl.loginMsg)))
复制代码

669 行改为:
  1. local, err = frpIo.WithEncryption(local, []byte(GetToken(pxy.GetControl().loginMsg)))
复制代码

到此重新编辑部署就可以了,更多还可以删除 cmd\frps 目录里启动命令里的 Token 字段设置,不改也无所谓,因为设置也不会生效了



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|整天BBB

GMT+8, 2025-1-10 19:16 , Processed in 0.078629 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表