all: add new feature privilege mode

This commit is contained in:
fatedier
2016-06-26 22:36:07 +08:00
parent b14441d5cd
commit f968f3eace
13 changed files with 252 additions and 53 deletions

View File

@@ -31,6 +31,9 @@ type ProxyClient struct {
config.BaseConf
LocalIp string
LocalPort int64
RemotePort int64
CustomDomains []string
}
func (p *ProxyClient) GetLocalConn() (c *conn.Conn, err error) {
@@ -57,10 +60,11 @@ func (p *ProxyClient) GetRemoteConn(addr string, port int64) (c *conn.Conn, err
nowTime := time.Now().Unix()
authKey := pcrypto.GetAuthKey(p.Name + p.AuthToken + fmt.Sprintf("%d", nowTime))
req := &msg.ControlReq{
Type: consts.NewWorkConn,
ProxyName: p.Name,
AuthKey: authKey,
Timestamp: nowTime,
Type: consts.NewWorkConn,
ProxyName: p.Name,
AuthKey: authKey,
PrivilegeMode: p.PrivilegeMode,
Timestamp: nowTime,
}
buf, _ := json.Marshal(req)

View File

@@ -17,6 +17,7 @@ package client
import (
"fmt"
"strconv"
"strings"
ini "github.com/vaughan0/go-ini"
)
@@ -29,6 +30,7 @@ var (
LogWay string = "console"
LogLevel string = "info"
LogMaxDays int64 = 3
PrivilegeKey string = ""
HeartBeatInterval int64 = 20
HeartBeatTimeout int64 = 90
)
@@ -75,12 +77,15 @@ func LoadConf(confFile string) (err error) {
LogMaxDays, _ = strconv.ParseInt(tmpStr, 10, 64)
}
tmpStr, ok = conf.Get("common", "privilege_key")
if ok {
PrivilegeKey = tmpStr
}
var authToken string
tmpStr, ok = conf.Get("common", "auth_token")
if ok {
authToken = tmpStr
} else {
return fmt.Errorf("auth_token not found")
}
// proxies
@@ -90,9 +95,6 @@ func LoadConf(confFile string) (err error) {
// name
proxyClient.Name = name
// auth_token
proxyClient.AuthToken = authToken
// local_ip
proxyClient.LocalIp, ok = section["local_ip"]
if !ok {
@@ -101,46 +103,101 @@ func LoadConf(confFile string) (err error) {
}
// local_port
portStr, ok := section["local_port"]
tmpStr, ok = section["local_port"]
if ok {
proxyClient.LocalPort, err = strconv.ParseInt(portStr, 10, 64)
proxyClient.LocalPort, err = strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
return fmt.Errorf("Parse ini file error: proxy [%s] local_port error", proxyClient.Name)
return fmt.Errorf("Parse conf error: proxy [%s] local_port error", proxyClient.Name)
}
} else {
return fmt.Errorf("Parse ini file error: proxy [%s] local_port not found", proxyClient.Name)
return fmt.Errorf("Parse conf error: proxy [%s] local_port not found", proxyClient.Name)
}
// type
proxyClient.Type = "tcp"
typeStr, ok := section["type"]
tmpStr, ok = section["type"]
if ok {
if typeStr != "tcp" && typeStr != "http" && typeStr != "https" {
return fmt.Errorf("Parse ini file error: proxy [%s] type error", proxyClient.Name)
if tmpStr != "tcp" && tmpStr != "http" && tmpStr != "https" {
return fmt.Errorf("Parse conf error: proxy [%s] type error", proxyClient.Name)
}
proxyClient.Type = typeStr
proxyClient.Type = tmpStr
}
// use_encryption
proxyClient.UseEncryption = false
useEncryptionStr, ok := section["use_encryption"]
if ok && useEncryptionStr == "true" {
tmpStr, ok = section["use_encryption"]
if ok && tmpStr == "true" {
proxyClient.UseEncryption = true
}
// use_gzip
proxyClient.UseGzip = false
useGzipStr, ok := section["use_gzip"]
if ok && useGzipStr == "true" {
tmpStr, ok = section["use_gzip"]
if ok && tmpStr == "true" {
proxyClient.UseGzip = true
}
// privilege_mode
proxyClient.PrivilegeMode = false
tmpStr, ok = section["privilege_mode"]
if ok && tmpStr == "true" {
proxyClient.PrivilegeMode = true
}
// configures used in privilege mode
if proxyClient.PrivilegeMode == true {
// auth_token
proxyClient.AuthToken = PrivilegeKey
if proxyClient.Type == "tcp" {
// remote_port
tmpStr, ok = section["remote_port"]
if ok {
proxyClient.RemotePort, err = strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
return fmt.Errorf("Parse conf error: proxy [%s] remote_port error", proxyClient.Name)
}
} else {
return fmt.Errorf("Parse conf error: proxy [%s] remote_port not found", proxyClient.Name)
}
} else if proxyClient.Type == "http" {
domainStr, ok := section["custom_domains"]
if ok {
proxyClient.CustomDomains = strings.Split(domainStr, ",")
if len(proxyClient.CustomDomains) == 0 {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name)
}
for i, domain := range proxyClient.CustomDomains {
proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
}
} else {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name)
}
} else if proxyClient.Type == "https" {
domainStr, ok := section["custom_domains"]
if ok {
proxyClient.CustomDomains = strings.Split(domainStr, ",")
if len(proxyClient.CustomDomains) == 0 {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals https", proxyClient.Name)
}
for i, domain := range proxyClient.CustomDomains {
proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
}
} else {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name)
}
}
} else /* proxyClient.PrivilegeMode == false */ {
// authToken
proxyClient.AuthToken = authToken
}
ProxyClients[proxyClient.Name] = proxyClient
}
}
if len(ProxyClients) == 0 {
return fmt.Errorf("Parse ini file error: no proxy config found")
return fmt.Errorf("Parse conf error: no proxy config found")
}
return nil

View File

@@ -20,4 +20,5 @@ type BaseConf struct {
Type string
UseEncryption bool
UseGzip bool
PrivilegeMode bool
}

View File

@@ -22,11 +22,17 @@ type GeneralRes struct {
// messages between control connections of frpc and frps
type ControlReq struct {
Type int64 `json:"type"`
ProxyName string `json:"proxy_name,omitempty"`
AuthKey string `json:"auth_key, omitempty"`
UseEncryption bool `json:"use_encryption, omitempty"`
UseGzip bool `json:"use_gzip, omitempty"`
Timestamp int64 `json:"timestamp, omitempty"`
ProxyName string `json:"proxy_name"`
AuthKey string `json:"auth_key"`
UseEncryption bool `json:"use_encryption"`
UseGzip bool `json:"use_gzip"`
// configures used if privilege_mode is enabled
PrivilegeMode bool `json:"privilege_mode"`
ProxyType string `json:"proxy_type"`
RemotePort int64 `json:"remote_port"`
CustomDomains []string `json:"custom_domains, omitempty"`
Timestamp int64 `json:"timestamp"`
}
type ControlRes struct {

View File

@@ -141,7 +141,6 @@ func pipeDecrypt(r net.Conn, w net.Conn, conf config.BaseConf) (err error) {
}
// gzip
if conf.UseGzip {
log.Warn("%x", res)
res, err = laes.Decompression(res)
if err != nil {
log.Warn("ProxyName [%s], decompression error, %v", conf.Name, err)

View File

@@ -22,6 +22,7 @@ import (
ini "github.com/vaughan0/go-ini"
"frp/models/consts"
"frp/utils/log"
"frp/utils/vhost"
)
@@ -38,6 +39,8 @@ var (
LogWay string = "console" // console or file
LogLevel string = "info"
LogMaxDays int64 = 3
PrivilegeMode bool = false
PrivilegeKey string = ""
HeartBeatTimeout int64 = 90
UserConnTimeout int64 = 10
@@ -132,6 +135,22 @@ func loadCommonConf(confFile string) error {
LogMaxDays = v
}
}
tmpStr, ok = conf.Get("common", "privilege_mode")
if ok {
if tmpStr == "true" {
PrivilegeMode = true
}
}
if PrivilegeMode == true {
tmpStr, ok = conf.Get("common", "privilege_key")
if ok {
PrivilegeKey = tmpStr
} else {
return fmt.Errorf("Parse conf error: privilege_key must be set if privilege_mode is enabled")
}
}
return nil
}
@@ -189,6 +208,8 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e
for i, domain := range proxyServer.CustomDomains {
proxyServer.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
}
} else {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyServer.Name)
}
} else if proxyServer.Type == "https" {
// for https
@@ -201,6 +222,8 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e
for i, domain := range proxyServer.CustomDomains {
proxyServer.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
}
} else {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals https", proxyServer.Name)
}
}
proxyServers[proxyServer.Name] = proxyServer
@@ -234,14 +257,37 @@ func ReloadConf(confFile string) (err error) {
}
}
// proxies created by PrivilegeMode won't be deleted
for name, oldProxyServer := range ProxyServers {
_, ok := loadProxyServers[name]
if !ok {
oldProxyServer.Close()
delete(ProxyServers, name)
log.Info("ProxyName [%s] deleted, close it", name)
if !oldProxyServer.PrivilegeMode {
oldProxyServer.Close()
delete(ProxyServers, name)
log.Info("ProxyName [%s] deleted, close it", name)
} else {
log.Info("ProxyName [%s] created by PrivilegeMode, won't be closed", name)
}
}
}
ProxyServersMutex.Unlock()
return nil
}
func CreateProxy(s *ProxyServer) error {
ProxyServersMutex.Lock()
defer ProxyServersMutex.Unlock()
oldServer, ok := ProxyServers[s.Name]
if ok {
if oldServer.Status == consts.Working {
return fmt.Errorf("this proxy is already working now")
}
oldServer.Close()
if oldServer.PrivilegeMode {
delete(ProxyServers, s.Name)
}
}
s.Init()
ProxyServers[s.Name] = s
return nil
}

View File

@@ -52,6 +52,20 @@ func NewProxyServer() (p *ProxyServer) {
return p
}
func NewProxyServerFromCtlMsg(req *msg.ControlReq) (p *ProxyServer) {
p = &ProxyServer{}
p.Name = req.ProxyName
p.Type = req.ProxyType
p.UseEncryption = req.UseEncryption
p.UseGzip = req.UseGzip
p.PrivilegeMode = req.PrivilegeMode
p.BindAddr = BindAddr
p.ListenPort = req.RemotePort
p.CustomDomains = req.CustomDomains
p.AuthToken = PrivilegeKey
return
}
func (p *ProxyServer) Init() {
p.Lock()
p.Status = consts.Idle
@@ -161,11 +175,9 @@ func (p *ProxyServer) Close() {
p.Lock()
if p.Status != consts.Closed {
p.Status = consts.Closed
if len(p.listeners) != 0 {
for _, l := range p.listeners {
if l != nil {
l.Close()
}
for _, l := range p.listeners {
if l != nil {
l.Close()
}
}
close(p.ctlMsgChan)