support yaml/json/toml configuration format, make ini deprecated (#3599)

This commit is contained in:
fatedier
2023-09-06 10:18:02 +08:00
committed by GitHub
parent 885b029fcf
commit c95311d1a0
103 changed files with 4178 additions and 3829 deletions

View File

@@ -21,7 +21,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -40,7 +42,7 @@ func init() {
httpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
httpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
httpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
httpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
httpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(httpCmd)
}
@@ -55,40 +57,36 @@ var httpCmd = &cobra.Command{
os.Exit(1)
}
cfg := &config.HTTPProxyConf{}
cfg := &v1.HTTPProxyConfig{}
var prefix string
if user != "" {
prefix = user + "."
}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.HTTPProxy
cfg.Name = prefix + proxyName
cfg.Type = consts.HTTPProxy
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.CustomDomains = strings.Split(customDomains, ",")
cfg.SubDomain = subDomain
cfg.Locations = strings.Split(locations, ",")
cfg.HTTPUser = httpUser
cfg.HTTPPwd = httpPwd
cfg.HTTPPassword = httpPwd
cfg.HostHeaderRewrite = hostHeaderRewrite
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg,
}
err = startService(clientCfg, proxyConfs, nil, "")
err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -21,7 +21,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -36,7 +38,7 @@ func init() {
httpsCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
httpsCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
httpsCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
httpsCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
httpsCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(httpsCmd)
}
@@ -51,36 +53,32 @@ var httpsCmd = &cobra.Command{
os.Exit(1)
}
cfg := &config.HTTPSProxyConf{}
cfg := &v1.HTTPSProxyConfig{}
var prefix string
if user != "" {
prefix = user + "."
}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.HTTPSProxy
cfg.Name = prefix + proxyName
cfg.Type = consts.HTTPSProxy
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.CustomDomains = strings.Split(customDomains, ",")
cfg.SubDomain = subDomain
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg,
}
err = startService(clientCfg, proxyConfs, nil, "")
err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -21,6 +21,7 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/nathole"
)
@@ -49,9 +50,9 @@ var natholeDiscoveryCmd = &cobra.Command{
Short: "Discover nathole information from stun server",
RunE: func(cmd *cobra.Command, args []string) error {
// ignore error here, because we can use command line pameters
cfg, _, _, err := config.ParseClientConfig(cfgFile)
cfg, _, _, _, err := config.LoadClientConfig(cfgFile)
if err != nil {
cfg = config.GetDefaultClientConf()
cfg = &v1.ClientCommonConfig{}
}
if natHoleSTUNServer != "" {
cfg.NatHoleSTUNServer = natHoleSTUNServer
@@ -89,7 +90,7 @@ var natholeDiscoveryCmd = &cobra.Command{
},
}
func validateForNatHoleDiscovery(cfg config.ClientCommonConf) error {
func validateForNatHoleDiscovery(cfg *v1.ClientCommonConfig) error {
if cfg.NatHoleSTUNServer == "" {
return fmt.Errorf("nat_hole_stun_server can not be empty")
}

View File

@@ -25,6 +25,7 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
)
func init() {
@@ -35,7 +36,7 @@ var reloadCmd = &cobra.Command{
Use: "reload",
Short: "Hot-Reload frpc configuration",
RunE: func(cmd *cobra.Command, args []string) error {
cfg, _, _, err := config.ParseClientConfig(cfgFile)
cfg, _, _, _, err := config.LoadClientConfig(cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -51,19 +52,20 @@ var reloadCmd = &cobra.Command{
},
}
func reload(clientCfg config.ClientCommonConf) error {
if clientCfg.AdminPort == 0 {
return fmt.Errorf("admin_port shoud be set if you want to use reload feature")
func reload(clientCfg *v1.ClientCommonConfig) error {
if clientCfg.WebServer.Port == 0 {
return fmt.Errorf("the port of web server shoud be set if you want to use reload feature")
}
req, err := http.NewRequest("GET", "http://"+
clientCfg.AdminAddr+":"+fmt.Sprintf("%d", clientCfg.AdminPort)+"/api/reload", nil)
clientCfg.WebServer.Addr+":"+
fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/reload", nil)
if err != nil {
return err
}
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+
clientCfg.AdminPwd))
authStr := "Basic " + base64.StdEncoding.EncodeToString(
[]byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password))
req.Header.Add("Authorization", authStr)
resp, err := http.DefaultClient.Do(req)

View File

@@ -27,20 +27,17 @@ import (
"syscall"
"time"
"github.com/samber/lo"
"github.com/spf13/cobra"
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/pkg/auth"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/util/log"
"github.com/fatedier/frp/pkg/util/version"
)
const (
CfgFileTypeIni = iota
CfgFileTypeCmd
)
var (
cfgFile string
cfgDir string
@@ -160,78 +157,89 @@ func handleTermSignal(svr *client.Service) {
svr.GracefulClose(500 * time.Millisecond)
}
func parseClientCommonCfgFromCmd() (cfg config.ClientCommonConf, err error) {
cfg = config.GetDefaultClientConf()
func parseClientCommonCfgFromCmd() (*v1.ClientCommonConfig, error) {
cfg := &v1.ClientCommonConfig{}
ipStr, portStr, err := net.SplitHostPort(serverAddr)
if err != nil {
err = fmt.Errorf("invalid server_addr: %v", err)
return
return nil, fmt.Errorf("invalid server_addr: %v", err)
}
cfg.ServerAddr = ipStr
cfg.ServerPort, err = strconv.Atoi(portStr)
if err != nil {
err = fmt.Errorf("invalid server_addr: %v", err)
return
return nil, fmt.Errorf("invalid server_addr: %v", err)
}
cfg.User = user
cfg.Protocol = protocol
cfg.LogLevel = logLevel
cfg.LogFile = logFile
cfg.LogMaxDays = int64(logMaxDays)
cfg.DisableLogColor = disableLogColor
cfg.Transport.Protocol = protocol
cfg.Log.Level = logLevel
cfg.Log.To = logFile
cfg.Log.MaxDays = int64(logMaxDays)
cfg.Log.DisablePrintColor = disableLogColor
cfg.DNSServer = dnsServer
// Only token authentication is supported in cmd mode
cfg.ClientConfig = auth.GetDefaultClientConf()
cfg.Token = token
cfg.TLSEnable = tlsEnable
cfg.TLSServerName = tlsServerName
cfg.Auth.Token = token
cfg.Transport.TLS.Enable = lo.ToPtr(tlsEnable)
cfg.Transport.TLS.ServerName = tlsServerName
cfg.Complete()
if err = cfg.Validate(); err != nil {
err = fmt.Errorf("parse config error: %v", err)
return
err, warning := validation.ValidateClientCommonConfig(cfg)
if warning != nil {
fmt.Printf("WARNING: %v\n", warning)
}
return
if err != nil {
return nil, fmt.Errorf("parse config error: %v", err)
}
return cfg, nil
}
func runClient(cfgFilePath string) error {
cfg, pxyCfgs, visitorCfgs, err := config.ParseClientConfig(cfgFilePath)
cfg, pxyCfgs, visitorCfgs, isLegacyFormat, err := config.LoadClientConfig(cfgFilePath)
if err != nil {
fmt.Println(err)
return err
}
if isLegacyFormat {
fmt.Printf("WARNING: ini format is deprecated and the support will be removed in the future, " +
"please use yaml/json/toml format instead!\n")
}
warning, err := validation.ValidateAllClientConfig(cfg, pxyCfgs, visitorCfgs)
if warning != nil {
fmt.Printf("WARNING: %v\n", warning)
}
if err != nil {
return err
}
return startService(cfg, pxyCfgs, visitorCfgs, cfgFilePath)
}
func startService(
cfg config.ClientCommonConf,
pxyCfgs map[string]config.ProxyConf,
visitorCfgs map[string]config.VisitorConf,
cfg *v1.ClientCommonConfig,
pxyCfgs []v1.ProxyConfigurer,
visitorCfgs []v1.VisitorConfigurer,
cfgFile string,
) (err error) {
log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel,
cfg.LogMaxDays, cfg.DisableLogColor)
) error {
log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
if cfgFile != "" {
log.Info("start frpc service for config file [%s]", cfgFile)
defer log.Info("frpc service for config file [%s] stopped", cfgFile)
}
svr, errRet := client.NewService(cfg, pxyCfgs, visitorCfgs, cfgFile)
if errRet != nil {
err = errRet
return
svr, err := client.NewService(cfg, pxyCfgs, visitorCfgs, cfgFile)
if err != nil {
return err
}
shouldGracefulClose := cfg.Protocol == "kcp" || cfg.Protocol == "quic"
shouldGracefulClose := cfg.Transport.Protocol == "kcp" || cfg.Transport.Protocol == "quic"
// Capture the exit signal if we use kcp or quic.
if shouldGracefulClose {
go handleTermSignal(svr)
}
_ = svr.Run(context.Background())
return
return nil
}

View File

@@ -28,6 +28,7 @@ import (
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
)
func init() {
@@ -38,7 +39,7 @@ var statusCmd = &cobra.Command{
Use: "status",
Short: "Overview of all proxies status",
RunE: func(cmd *cobra.Command, args []string) error {
cfg, _, _, err := config.ParseClientConfig(cfgFile)
cfg, _, _, _, err := config.LoadClientConfig(cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -52,19 +53,19 @@ var statusCmd = &cobra.Command{
},
}
func status(clientCfg config.ClientCommonConf) error {
if clientCfg.AdminPort == 0 {
return fmt.Errorf("admin_port shoud be set if you want to get proxy status")
func status(clientCfg *v1.ClientCommonConfig) error {
if clientCfg.WebServer.Port == 0 {
return fmt.Errorf("the port of web server shoud be set if you want to get proxy status")
}
req, err := http.NewRequest("GET", "http://"+
clientCfg.AdminAddr+":"+fmt.Sprintf("%d", clientCfg.AdminPort)+"/api/status", nil)
clientCfg.WebServer.Addr+":"+fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/status", nil)
if err != nil {
return err
}
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+
clientCfg.AdminPwd))
authStr := "Basic " + base64.StdEncoding.EncodeToString(
[]byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password))
req.Header.Add("Authorization", authStr)
resp, err := http.DefaultClient.Do(req)

View File

@@ -20,7 +20,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -38,7 +40,7 @@ func init() {
stcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
stcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
stcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
stcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
stcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(stcpCmd)
}
@@ -53,8 +55,8 @@ var stcpCmd = &cobra.Command{
os.Exit(1)
}
proxyConfs := make(map[string]config.ProxyConf)
visitorConfs := make(map[string]config.VisitorConf)
pxyCfgs := make([]v1.ProxyConfigurer, 0)
visitorCfgs := make([]v1.VisitorConfigurer, 0)
var prefix string
if user != "" {
@@ -63,50 +65,46 @@ var stcpCmd = &cobra.Command{
switch role {
case "server":
cfg := &config.STCPProxyConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.STCPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.STCPProxyConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.STCPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Secretkey = sk
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs[cfg.ProxyName] = cfg
pxyCfgs = append(pxyCfgs, cfg)
case "visitor":
cfg := &config.STCPVisitorConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.STCPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.STCPVisitorConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.STCPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.SecretKey = sk
cfg.ServerName = serverName
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
err = cfg.Validate()
if err != nil {
if err := validation.ValidateVisitorConfigurer(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
visitorConfs[cfg.ProxyName] = cfg
visitorCfgs = append(visitorCfgs, cfg)
default:
fmt.Println("invalid role")
os.Exit(1)
}
err = startService(clientCfg, proxyConfs, visitorConfs, "")
err = startService(clientCfg, pxyCfgs, visitorCfgs, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -25,6 +25,7 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
v1 "github.com/fatedier/frp/pkg/config/v1"
)
func init() {
@@ -35,7 +36,7 @@ var stopCmd = &cobra.Command{
Use: "stop",
Short: "Stop the running frpc",
RunE: func(cmd *cobra.Command, args []string) error {
cfg, _, _, err := config.ParseClientConfig(cfgFile)
cfg, _, _, _, err := config.LoadClientConfig(cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
@@ -51,19 +52,20 @@ var stopCmd = &cobra.Command{
},
}
func stopClient(clientCfg config.ClientCommonConf) error {
if clientCfg.AdminPort == 0 {
return fmt.Errorf("admin_port shoud be set if you want to use stop feature")
func stopClient(clientCfg *v1.ClientCommonConfig) error {
if clientCfg.WebServer.Port == 0 {
return fmt.Errorf("the port of web server shoud be set if you want to use stop feature")
}
req, err := http.NewRequest("POST", "http://"+
clientCfg.AdminAddr+":"+fmt.Sprintf("%d", clientCfg.AdminPort)+"/api/stop", nil)
clientCfg.WebServer.Addr+":"+
fmt.Sprintf("%d", clientCfg.WebServer.Port)+"/api/stop", nil)
if err != nil {
return err
}
authStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(clientCfg.AdminUser+":"+
clientCfg.AdminPwd))
authStr := "Basic " + base64.StdEncoding.EncodeToString(
[]byte(clientCfg.WebServer.User+":"+clientCfg.WebServer.Password))
req.Header.Add("Authorization", authStr)
resp, err := http.DefaultClient.Do(req)

View File

@@ -20,7 +20,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -38,7 +40,7 @@ func init() {
sudpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
sudpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
sudpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
sudpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
sudpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(sudpCmd)
}
@@ -53,8 +55,8 @@ var sudpCmd = &cobra.Command{
os.Exit(1)
}
proxyConfs := make(map[string]config.ProxyConf)
visitorConfs := make(map[string]config.VisitorConf)
pxyCfgs := make([]v1.ProxyConfigurer, 0)
visitorCfgs := make([]v1.VisitorConfigurer, 0)
var prefix string
if user != "" {
@@ -63,50 +65,46 @@ var sudpCmd = &cobra.Command{
switch role {
case "server":
cfg := &config.SUDPProxyConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.SUDPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.SUDPProxyConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.SUDPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Secretkey = sk
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs[cfg.ProxyName] = cfg
pxyCfgs = append(pxyCfgs, cfg)
case "visitor":
cfg := &config.SUDPVisitorConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.SUDPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.SUDPVisitorConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.SUDPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.SecretKey = sk
cfg.ServerName = serverName
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
err = cfg.Validate()
if err != nil {
if err := validation.ValidateVisitorConfigurer(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
visitorConfs[cfg.ProxyName] = cfg
visitorCfgs = append(visitorCfgs, cfg)
default:
fmt.Println("invalid role")
os.Exit(1)
}
err = startService(clientCfg, proxyConfs, visitorConfs, "")
err = startService(clientCfg, pxyCfgs, visitorCfgs, "")
if err != nil {
os.Exit(1)
}

View File

@@ -20,7 +20,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -34,7 +36,7 @@ func init() {
tcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
tcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
tcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
tcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
tcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(tcpCmd)
}
@@ -49,35 +51,30 @@ var tcpCmd = &cobra.Command{
os.Exit(1)
}
cfg := &config.TCPProxyConf{}
cfg := &v1.TCPProxyConfig{}
var prefix string
if user != "" {
prefix = user + "."
}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.TCPProxy
cfg.Name = prefix + proxyName
cfg.Type = consts.TCPProxy
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.RemotePort = remotePort
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg,
}
err = startService(clientCfg, proxyConfs, nil, "")
err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -21,7 +21,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -37,7 +39,7 @@ func init() {
tcpMuxCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
tcpMuxCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
tcpMuxCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
tcpMuxCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
tcpMuxCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(tcpMuxCmd)
}
@@ -52,37 +54,33 @@ var tcpMuxCmd = &cobra.Command{
os.Exit(1)
}
cfg := &config.TCPMuxProxyConf{}
cfg := &v1.TCPMuxProxyConfig{}
var prefix string
if user != "" {
prefix = user + "."
}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.TCPMuxProxy
cfg.Name = prefix + proxyName
cfg.Type = consts.TCPMuxProxy
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.CustomDomains = strings.Split(customDomains, ",")
cfg.SubDomain = subDomain
cfg.Multiplexer = multiplexer
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg,
}
err = startService(clientCfg, proxyConfs, nil, "")
err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -20,7 +20,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -34,7 +36,7 @@ func init() {
udpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
udpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
udpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
udpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
udpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(udpCmd)
}
@@ -49,35 +51,31 @@ var udpCmd = &cobra.Command{
os.Exit(1)
}
cfg := &config.UDPProxyConf{}
cfg := &v1.UDPProxyConfig{}
var prefix string
if user != "" {
prefix = user + "."
}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.UDPProxy
cfg.Name = prefix + proxyName
cfg.Type = consts.UDPProxy
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.RemotePort = remotePort
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs := map[string]config.ProxyConf{
cfg.ProxyName: cfg,
}
err = startService(clientCfg, proxyConfs, nil, "")
err = startService(clientCfg, []v1.ProxyConfigurer{cfg}, nil, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -21,6 +21,7 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/v1/validation"
)
func init() {
@@ -31,7 +32,20 @@ var verifyCmd = &cobra.Command{
Use: "verify",
Short: "Verify that the configures is valid",
RunE: func(cmd *cobra.Command, args []string) error {
_, _, _, err := config.ParseClientConfig(cfgFile)
if cfgFile == "" {
fmt.Println("frpc: the configuration file is not specified")
return nil
}
cliCfg, pxyCfgs, visitorCfgs, _, err := config.LoadClientConfig(cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
warning, err := validation.ValidateAllClientConfig(cliCfg, pxyCfgs, visitorCfgs)
if warning != nil {
fmt.Printf("WARNING: %v\n", warning)
}
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -20,7 +20,9 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/consts"
)
@@ -38,7 +40,7 @@ func init() {
xtcpCmd.PersistentFlags().BoolVarP(&useEncryption, "ue", "", false, "use encryption")
xtcpCmd.PersistentFlags().BoolVarP(&useCompression, "uc", "", false, "use compression")
xtcpCmd.PersistentFlags().StringVarP(&bandwidthLimit, "bandwidth_limit", "", "", "bandwidth limit")
xtcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", config.BandwidthLimitModeClient, "bandwidth limit mode")
xtcpCmd.PersistentFlags().StringVarP(&bandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
rootCmd.AddCommand(xtcpCmd)
}
@@ -53,8 +55,8 @@ var xtcpCmd = &cobra.Command{
os.Exit(1)
}
proxyConfs := make(map[string]config.ProxyConf)
visitorConfs := make(map[string]config.VisitorConf)
pxyCfgs := make([]v1.ProxyConfigurer, 0)
visitorCfgs := make([]v1.VisitorConfigurer, 0)
var prefix string
if user != "" {
@@ -63,50 +65,48 @@ var xtcpCmd = &cobra.Command{
switch role {
case "server":
cfg := &config.XTCPProxyConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.XTCPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.XTCPProxyConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.XTCPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.Secretkey = sk
cfg.LocalIP = localIP
cfg.LocalPort = localPort
cfg.BandwidthLimit, err = config.NewBandwidthQuantity(bandwidthLimit)
cfg.Transport.BandwidthLimit, err = types.NewBandwidthQuantity(bandwidthLimit)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
cfg.BandwidthLimitMode = bandwidthLimitMode
err = cfg.ValidateForClient()
if err != nil {
cfg.Transport.BandwidthLimitMode = bandwidthLimitMode
if err := validation.ValidateProxyConfigurerForClient(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
proxyConfs[cfg.ProxyName] = cfg
pxyCfgs = append(pxyCfgs, cfg)
case "visitor":
cfg := &config.XTCPVisitorConf{}
cfg.ProxyName = prefix + proxyName
cfg.ProxyType = consts.XTCPProxy
cfg.UseEncryption = useEncryption
cfg.UseCompression = useCompression
cfg.Role = role
cfg.Sk = sk
cfg := &v1.XTCPVisitorConfig{}
cfg.Name = prefix + proxyName
cfg.Type = consts.XTCPProxy
cfg.Transport.UseEncryption = useEncryption
cfg.Transport.UseCompression = useCompression
cfg.SecretKey = sk
cfg.ServerName = serverName
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
err = cfg.Validate()
if err != nil {
if err := validation.ValidateVisitorConfigurer(cfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
visitorConfs[cfg.ProxyName] = cfg
visitorCfgs = append(visitorCfgs, cfg)
default:
fmt.Println("invalid role")
os.Exit(1)
}
err = startService(clientCfg, proxyConfs, visitorConfs, "")
err = startService(clientCfg, pxyCfgs, visitorCfgs, "")
if err != nil {
fmt.Println(err)
os.Exit(1)

View File

@@ -15,9 +15,6 @@
package main
import (
"math/rand"
"time"
"github.com/fatedier/golib/crypto"
_ "github.com/fatedier/frp/assets/frps"
@@ -26,8 +23,5 @@ import (
func main() {
crypto.DefaultSalt = "frp"
// TODO: remove this when we drop support for go1.19
rand.Seed(time.Now().UnixNano())
Execute()
}

View File

@@ -21,19 +21,15 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/auth"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/types"
v1 "github.com/fatedier/frp/pkg/config/v1"
"github.com/fatedier/frp/pkg/config/v1/validation"
"github.com/fatedier/frp/pkg/util/log"
"github.com/fatedier/frp/pkg/util/util"
"github.com/fatedier/frp/pkg/util/version"
"github.com/fatedier/frp/server"
)
const (
CfgFileTypeIni = iota
CfgFileTypeCmd
)
var (
cfgFile string
showVersion bool
@@ -104,24 +100,35 @@ var rootCmd = &cobra.Command{
return nil
}
var cfg config.ServerCommonConf
var err error
var (
svrCfg *v1.ServerConfig
isLegacyFormat bool
err error
)
if cfgFile != "" {
var content []byte
content, err = config.GetRenderedConfFromFile(cfgFile)
svrCfg, isLegacyFormat, err = config.LoadServerConfig(cfgFile)
if err != nil {
return err
}
cfg, err = parseServerCommonCfg(CfgFileTypeIni, content)
if isLegacyFormat {
fmt.Printf("WARNING: ini format is deprecated and the support will be removed in the future, " +
"please use yaml/json/toml format instead!\n")
}
} else {
cfg, err = parseServerCommonCfg(CfgFileTypeCmd, nil)
if svrCfg, err = parseServerConfigFromCmd(); err != nil {
return err
}
}
warning, err := validation.ValidateServerConfig(svrCfg)
if warning != nil {
fmt.Printf("WARNING: %v\n", warning)
}
if err != nil {
return err
}
err = runServer(cfg)
if err != nil {
if err := runServer(svrCfg); err != nil {
fmt.Println(err)
os.Exit(1)
}
@@ -135,26 +142,8 @@ func Execute() {
}
}
func parseServerCommonCfg(fileType int, source []byte) (cfg config.ServerCommonConf, err error) {
if fileType == CfgFileTypeIni {
cfg, err = config.UnmarshalServerConfFromIni(source)
} else if fileType == CfgFileTypeCmd {
cfg, err = parseServerCommonCfgFromCmd()
}
if err != nil {
return
}
cfg.Complete()
err = cfg.Validate()
if err != nil {
err = fmt.Errorf("parse config error: %v", err)
return
}
return
}
func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
cfg = config.GetDefaultServerConf()
func parseServerConfigFromCmd() (*v1.ServerConfig, error) {
cfg := &v1.ServerConfig{}
cfg.BindAddr = bindAddr
cfg.BindPort = bindPort
@@ -163,42 +152,42 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
cfg.VhostHTTPPort = vhostHTTPPort
cfg.VhostHTTPSPort = vhostHTTPSPort
cfg.VhostHTTPTimeout = vhostHTTPTimeout
cfg.DashboardAddr = dashboardAddr
cfg.DashboardPort = dashboardPort
cfg.DashboardUser = dashboardUser
cfg.DashboardPwd = dashboardPwd
cfg.WebServer.Addr = dashboardAddr
cfg.WebServer.Port = dashboardPort
cfg.WebServer.User = dashboardUser
cfg.WebServer.Password = dashboardPwd
cfg.EnablePrometheus = enablePrometheus
cfg.DashboardTLSCertFile = dashboardTLSCertFile
cfg.DashboardTLSKeyFile = dashboardTLSKeyFile
cfg.DashboardTLSMode = dashboardTLSMode
cfg.LogFile = logFile
cfg.LogLevel = logLevel
cfg.LogMaxDays = logMaxDays
cfg.SubDomainHost = subDomainHost
cfg.TLSOnly = tlsOnly
// Only token authentication is supported in cmd mode
cfg.ServerConfig = auth.GetDefaultServerConf()
cfg.Token = token
if len(allowPorts) > 0 {
// e.g. 1000-2000,2001,2002,3000-4000
ports, errRet := util.ParseRangeNumbers(allowPorts)
if errRet != nil {
err = fmt.Errorf("parse conf error: allow_ports: %v", errRet)
return
}
for _, port := range ports {
cfg.AllowPorts[int(port)] = struct{}{}
if dashboardTLSMode {
cfg.WebServer.TLS = &v1.TLSConfig{
CertFile: dashboardTLSCertFile,
KeyFile: dashboardTLSKeyFile,
}
}
cfg.Log.To = logFile
cfg.Log.Level = logLevel
cfg.Log.MaxDays = logMaxDays
cfg.Log.DisablePrintColor = disableLogColor
cfg.SubDomainHost = subDomainHost
cfg.TLS.Force = tlsOnly
cfg.MaxPortsPerClient = maxPortsPerClient
cfg.DisableLogColor = disableLogColor
return
// Only token authentication is supported in cmd mode
cfg.Auth.Token = token
if len(allowPorts) > 0 {
portsRanges, err := types.NewPortsRangeSliceFromString(allowPorts)
if err != nil {
return cfg, fmt.Errorf("allow_ports format error: %v", err)
}
cfg.AllowPorts = portsRanges
}
cfg.Complete()
return cfg, nil
}
func runServer(cfg config.ServerCommonConf) (err error) {
log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, cfg.LogMaxDays, cfg.DisableLogColor)
func runServer(cfg *v1.ServerConfig) (err error) {
log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
if cfgFile != "" {
log.Info("frps uses config file: %s", cfgFile)

View File

@@ -21,6 +21,7 @@ import (
"github.com/spf13/cobra"
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/pkg/config/v1/validation"
)
func init() {
@@ -32,21 +33,23 @@ var verifyCmd = &cobra.Command{
Short: "Verify that the configures is valid",
RunE: func(cmd *cobra.Command, args []string) error {
if cfgFile == "" {
fmt.Println("no config file is specified")
fmt.Println("frps: the configuration file is not specified")
return nil
}
iniContent, err := config.GetRenderedConfFromFile(cfgFile)
svrCfg, _, err := config.LoadServerConfig(cfgFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
_, err = parseServerCommonCfg(CfgFileTypeIni, iniContent)
warning, err := validation.ValidateServerConfig(svrCfg)
if warning != nil {
fmt.Printf("WARNING: %v\n", warning)
}
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("frps: the configuration file %s syntax is ok\n", cfgFile)
return nil
},