2018年7月5日
FRP 更改多 Token 支持 – Lzxz1234 的小站
简介之前一直用 Ngrok,但 Ngrok 有比较严重的内存泄露问题,经常无故退出。所以最近更改到了 frp。 frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。
由于 frp 默认只支持一个 token,这样当 token 泄露更改时会导致全部客户端不可用,所以就有了本次修改。 过程- if util.GetAuthKey(g.GlbServerCfg.Token, loginMsg) != loginMsg.PrivilegeKey {
复制代码
所以我们可以新建 server/auth.go 主要处理授权逻辑: - package server
- import (
- "database/sql"
- "github.com/fatedier/frp/models/msg"
- "github.com/fatedier/frp/utils/util"
- _ "github.com/mattn/go-sqlite3"
- )
- var db *sql.DB
- type User struct {
- UserName string
- Token string
- }
- func GetAuthKey(loginMsg *msg.Login) (key string) {
- user := GetUser(loginMsg.User)
- key = util.GetAuthKey(user.Token, loginMsg.Timestamp)
- return
- }
- func GetToken(loginMsg *msg.Login) (key string) {
- user := GetUser(loginMsg.User)
- key = user.Token
- return
- }
- func GetUser(userName string) (user User) {
- if db == nil {
- db, _ = sql.Open("sqlite3", "/sqlite3.db")
- db.Exec("create table if not exists user(user_name varchar(128), token varchar(128))")
- }
- stmt, _ := db.Prepare("SELECT user_name, token FROM user where user_name = ?")
- defer stmt.Close()
- rows, _ := stmt.Query(userName)
- defer rows.Close()
- if rows.Next() {
- rows.Scan(&user.UserName, &user.Token)
- }
- return
- }
复制代码
此处将用户信息存储在了 sqlite3 中,同时将用户做成实体,后续可以根据用户限制代理类型个数等。同时由于引用了 github.com/mattn/go-sqlite3 包,所以也需要在 vendor 目录里添加对应包。 其它修改除了登录时的 token 校验,还有其它地方也需要同步修改,主要是 server/control.go 和 server/proxy.go,这两个文件的修改主要用于替换 token 的获取逻辑,由全局获取改为数据库获取: control.go212 行改为: - encWriter, err := crypto.NewWriter(ctl.conn, []byte(GetToken(ctl.loginMsg)))
复制代码
242 行改为: - encReader := crypto.NewReader(ctl.conn, []byte(GetToken(ctl.loginMsg)))
复制代码
311 行改为: - rwc, err = frpIo.WithEncryption(rwc, []byte(GetToken(pxy.ctl.loginMsg)))
复制代码
669 行改为: - local, err = frpIo.WithEncryption(local, []byte(GetToken(pxy.GetControl().loginMsg)))
复制代码
到此重新编辑部署就可以了,更多还可以删除 cmd\frps 目录里启动命令里的 Token 字段设置,不改也无所谓,因为设置也不会生效了
|