// 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" "github.com/fatedier/frp/utils/util" ini "github.com/vaughan0/go-ini" ) var ServerCommonCfg *ServerCommonConf // common config type ServerCommonConf struct { ConfigFile string BindAddr string BindPort int64 BindUdpPort int64 KcpBindPort int64 ProxyBindAddr string // 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 DashboardAddr string // 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 TcpMux bool // if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected PrivilegeAllowPorts [][2]int64 MaxPoolCount int64 HeartBeatTimeout int64 UserConnTimeout int64 } func GetDefaultServerCommonConf() *ServerCommonConf { return &ServerCommonConf{ ConfigFile: "./frps.ini", BindAddr: "0.0.0.0", BindPort: 7000, BindUdpPort: 0, KcpBindPort: 0, ProxyBindAddr: "0.0.0.0", VhostHttpPort: 0, VhostHttpsPort: 0, DashboardAddr: "0.0.0.0", DashboardPort: 0, DashboardUser: "admin", DashboardPwd: "admin", AssetsDir: "", LogFile: "console", LogWay: "console", LogLevel: "info", LogMaxDays: 3, PrivilegeMode: true, PrivilegeToken: "", AuthTimeout: 900, SubDomainHost: "", TcpMux: true, MaxPoolCount: 5, HeartBeatTimeout: 90, 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", "bind_udp_port") if ok { v, err = strconv.ParseInt(tmpStr, 10, 64) if err == nil { cfg.BindUdpPort = v } } tmpStr, ok = conf.Get("common", "kcp_bind_port") if ok { v, err = strconv.ParseInt(tmpStr, 10, 64) if err == nil && v > 0 { cfg.KcpBindPort = v } } tmpStr, ok = conf.Get("common", "proxy_bind_addr") if ok { cfg.ProxyBindAddr = tmpStr } else { cfg.ProxyBindAddr = cfg.BindAddr } 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_addr") if ok { cfg.DashboardAddr = tmpStr } else { cfg.DashboardAddr = cfg.BindAddr } 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 { cfg.PrivilegeToken, _ = conf.Get("common", "privilege_token") allowPortsStr, ok := conf.Get("common", "privilege_allow_ports") // TODO: check if conflicts exist in port ranges if ok { cfg.PrivilegeAllowPorts, err = util.GetPortRanges(allowPortsStr) if err != nil { err = fmt.Errorf("Parse conf error: privilege_allow_ports is incorrect, %v", err) 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", "tcp_mux") if ok && tmpStr == "false" { cfg.TcpMux = false } else { cfg.TcpMux = true } 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 }