You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
frp/models/config/server_common.go

280 lines
6.8 KiB

// Copyright 2016 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"fmt"
"strconv"
"strings"
ini "github.com/vaughan0/go-ini"
)
var ServerCommonCfg *ServerCommonConf
// common config
type ServerCommonConf struct {
ConfigFile string
BindAddr string
BindPort int64
// If VhostHttpPort equals 0, don't listen a public port for http protocol.
VhostHttpPort int64
// if VhostHttpsPort equals 0, don't listen a public port for https protocol
VhostHttpsPort int64
// if DashboardPort equals 0, dashboard is not available
DashboardPort int64
DashboardUser string
DashboardPwd string
AssetsDir string
LogFile string
LogWay string // console or file
LogLevel string
LogMaxDays int64
PrivilegeMode bool
PrivilegeToken string
AuthTimeout int64
SubDomainHost string
// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
PrivilegeAllowPorts map[int64]struct{}
MaxPoolCount int64
HeartBeatTimeout int64
UserConnTimeout int64
}
func GetDefaultServerCommonConf() *ServerCommonConf {
return &ServerCommonConf{
ConfigFile: "./frps.ini",
BindAddr: "0.0.0.0",
BindPort: 7000,
VhostHttpPort: 0,
VhostHttpsPort: 0,
DashboardPort: 0,
DashboardUser: "admin",
DashboardPwd: "admin",
AssetsDir: "",
LogFile: "console",
LogWay: "console",
LogLevel: "info",
LogMaxDays: 3,
PrivilegeMode: true,
PrivilegeToken: "",
AuthTimeout: 900,
SubDomainHost: "",
MaxPoolCount: 10,
HeartBeatTimeout: 30,
UserConnTimeout: 10,
}
}
// Load server common configure.
func LoadServerCommonConf(conf ini.File) (cfg *ServerCommonConf, err error) {
var (
tmpStr string
ok bool
v int64
)
cfg = GetDefaultServerCommonConf()
tmpStr, ok = conf.Get("common", "bind_addr")
if ok {
cfg.BindAddr = tmpStr
}
tmpStr, ok = conf.Get("common", "bind_port")
if ok {
v, err = strconv.ParseInt(tmpStr, 10, 64)
if err == nil {
cfg.BindPort = v
}
}
tmpStr, ok = conf.Get("common", "vhost_http_port")
if ok {
cfg.VhostHttpPort, err = strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
err = fmt.Errorf("Parse conf error: vhost_http_port is incorrect")
return
}
} else {
cfg.VhostHttpPort = 0
}
tmpStr, ok = conf.Get("common", "vhost_https_port")
if ok {
cfg.VhostHttpsPort, err = strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
err = fmt.Errorf("Parse conf error: vhost_https_port is incorrect")
return
}
} else {
cfg.VhostHttpsPort = 0
}
tmpStr, ok = conf.Get("common", "dashboard_port")
if ok {
cfg.DashboardPort, err = strconv.ParseInt(tmpStr, 10, 64)
if err != nil {
err = fmt.Errorf("Parse conf error: dashboard_port is incorrect")
return
}
} else {
cfg.DashboardPort = 0
}
tmpStr, ok = conf.Get("common", "dashboard_user")
if ok {
cfg.DashboardUser = tmpStr
}
tmpStr, ok = conf.Get("common", "dashboard_pwd")
if ok {
cfg.DashboardPwd = tmpStr
}
tmpStr, ok = conf.Get("common", "assets_dir")
if ok {
cfg.AssetsDir = tmpStr
}
tmpStr, ok = conf.Get("common", "log_file")
if ok {
cfg.LogFile = tmpStr
if cfg.LogFile == "console" {
cfg.LogWay = "console"
} else {
cfg.LogWay = "file"
}
}
tmpStr, ok = conf.Get("common", "log_level")
if ok {
cfg.LogLevel = tmpStr
}
tmpStr, ok = conf.Get("common", "log_max_days")
if ok {
v, err = strconv.ParseInt(tmpStr, 10, 64)
if err == nil {
cfg.LogMaxDays = v
}
}
tmpStr, ok = conf.Get("common", "privilege_mode")
if ok {
if tmpStr == "true" {
cfg.PrivilegeMode = true
}
}
// PrivilegeMode configure
if cfg.PrivilegeMode == true {
tmpStr, ok = conf.Get("common", "privilege_token")
if ok {
if tmpStr == "" {
err = fmt.Errorf("Parse conf error: privilege_token can not be empty")
return
}
cfg.PrivilegeToken = tmpStr
} else {
err = fmt.Errorf("Parse conf error: privilege_token must be set if privilege_mode is enabled")
return
}
cfg.PrivilegeAllowPorts = make(map[int64]struct{})
tmpStr, ok = conf.Get("common", "privilege_allow_ports")
if ok {
// e.g. 1000-2000,2001,2002,3000-4000
portRanges := strings.Split(tmpStr, ",")
for _, portRangeStr := range portRanges {
// 1000-2000 or 2001
portArray := strings.Split(portRangeStr, "-")
// length: only 1 or 2 is correct
rangeType := len(portArray)
if rangeType == 1 {
// single port
singlePort, errRet := strconv.ParseInt(portArray[0], 10, 64)
if errRet != nil {
err = fmt.Errorf("Parse conf error: privilege_allow_ports is incorrect, %v", errRet)
return
}
ServerCommonCfg.PrivilegeAllowPorts[singlePort] = struct{}{}
} else if rangeType == 2 {
// range ports
min, errRet := strconv.ParseInt(portArray[0], 10, 64)
if errRet != nil {
err = fmt.Errorf("Parse conf error: privilege_allow_ports is incorrect, %v", errRet)
return
}
max, errRet := strconv.ParseInt(portArray[1], 10, 64)
if errRet != nil {
err = fmt.Errorf("Parse conf error: privilege_allow_ports is incorrect, %v", errRet)
return
}
if max < min {
err = fmt.Errorf("Parse conf error: privilege_allow_ports range incorrect")
return
}
for i := min; i <= max; i++ {
cfg.PrivilegeAllowPorts[i] = struct{}{}
}
} else {
err = fmt.Errorf("Parse conf error: privilege_allow_ports is incorrect")
return
}
}
}
}
tmpStr, ok = conf.Get("common", "max_pool_count")
if ok {
v, err = strconv.ParseInt(tmpStr, 10, 64)
if err == nil && v >= 0 {
cfg.MaxPoolCount = v
}
}
tmpStr, ok = conf.Get("common", "authentication_timeout")
if ok {
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
if errRet != nil {
err = fmt.Errorf("Parse conf error: authentication_timeout is incorrect")
return
} else {
cfg.AuthTimeout = v
}
}
tmpStr, ok = conf.Get("common", "subdomain_host")
if ok {
cfg.SubDomainHost = strings.ToLower(strings.TrimSpace(tmpStr))
}
tmpStr, ok = conf.Get("common", "heartbeat_timeout")
if ok {
v, errRet := strconv.ParseInt(tmpStr, 10, 64)
if errRet != nil {
err = fmt.Errorf("Parse conf error: heartbeat_timeout is incorrect")
return
} else {
cfg.HeartBeatTimeout = v
}
}
return
}