root.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2018 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "context"
  17. "fmt"
  18. "os"
  19. "github.com/spf13/cobra"
  20. "github.com/fatedier/frp/pkg/config"
  21. "github.com/fatedier/frp/pkg/config/types"
  22. v1 "github.com/fatedier/frp/pkg/config/v1"
  23. "github.com/fatedier/frp/pkg/config/v1/validation"
  24. "github.com/fatedier/frp/pkg/util/log"
  25. "github.com/fatedier/frp/pkg/util/version"
  26. "github.com/fatedier/frp/server"
  27. )
  28. var (
  29. cfgFile string
  30. showVersion bool
  31. bindAddr string
  32. bindPort int
  33. kcpBindPort int
  34. proxyBindAddr string
  35. vhostHTTPPort int
  36. vhostHTTPSPort int
  37. vhostHTTPTimeout int64
  38. dashboardAddr string
  39. dashboardPort int
  40. dashboardUser string
  41. dashboardPwd string
  42. enablePrometheus bool
  43. logFile string
  44. logLevel string
  45. logMaxDays int64
  46. disableLogColor bool
  47. token string
  48. subDomainHost string
  49. allowPorts string
  50. maxPortsPerClient int64
  51. tlsOnly bool
  52. dashboardTLSMode bool
  53. dashboardTLSCertFile string
  54. dashboardTLSKeyFile string
  55. )
  56. func init() {
  57. rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps")
  58. rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps")
  59. rootCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "0.0.0.0", "bind address")
  60. rootCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "p", 7000, "bind port")
  61. rootCmd.PersistentFlags().IntVarP(&kcpBindPort, "kcp_bind_port", "", 0, "kcp bind udp port")
  62. rootCmd.PersistentFlags().StringVarP(&proxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address")
  63. rootCmd.PersistentFlags().IntVarP(&vhostHTTPPort, "vhost_http_port", "", 0, "vhost http port")
  64. rootCmd.PersistentFlags().IntVarP(&vhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port")
  65. rootCmd.PersistentFlags().Int64VarP(&vhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout")
  66. rootCmd.PersistentFlags().StringVarP(&dashboardAddr, "dashboard_addr", "", "0.0.0.0", "dashboard address")
  67. rootCmd.PersistentFlags().IntVarP(&dashboardPort, "dashboard_port", "", 0, "dashboard port")
  68. rootCmd.PersistentFlags().StringVarP(&dashboardUser, "dashboard_user", "", "admin", "dashboard user")
  69. rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password")
  70. rootCmd.PersistentFlags().BoolVarP(&enablePrometheus, "enable_prometheus", "", false, "enable prometheus dashboard")
  71. rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file")
  72. rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
  73. rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days")
  74. rootCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
  75. rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
  76. rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
  77. rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
  78. rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
  79. rootCmd.PersistentFlags().BoolVarP(&tlsOnly, "tls_only", "", false, "frps tls only")
  80. rootCmd.PersistentFlags().BoolVarP(&dashboardTLSMode, "dashboard_tls_mode", "", false, "dashboard tls mode")
  81. rootCmd.PersistentFlags().StringVarP(&dashboardTLSCertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file")
  82. rootCmd.PersistentFlags().StringVarP(&dashboardTLSKeyFile, "dashboard_tls_key_file", "", "", "dashboard tls key file")
  83. }
  84. var rootCmd = &cobra.Command{
  85. Use: "frps",
  86. Short: "frps is the server of frp (https://github.com/fatedier/frp)",
  87. RunE: func(cmd *cobra.Command, args []string) error {
  88. if showVersion {
  89. fmt.Println(version.Full())
  90. return nil
  91. }
  92. var (
  93. svrCfg *v1.ServerConfig
  94. isLegacyFormat bool
  95. err error
  96. )
  97. if cfgFile != "" {
  98. svrCfg, isLegacyFormat, err = config.LoadServerConfig(cfgFile)
  99. if err != nil {
  100. return err
  101. }
  102. if isLegacyFormat {
  103. fmt.Printf("WARNING: ini format is deprecated and the support will be removed in the future, " +
  104. "please use yaml/json/toml format instead!\n")
  105. }
  106. } else {
  107. if svrCfg, err = parseServerConfigFromCmd(); err != nil {
  108. return err
  109. }
  110. }
  111. warning, err := validation.ValidateServerConfig(svrCfg)
  112. if warning != nil {
  113. fmt.Printf("WARNING: %v\n", warning)
  114. }
  115. if err != nil {
  116. return err
  117. }
  118. if err := runServer(svrCfg); err != nil {
  119. fmt.Println(err)
  120. os.Exit(1)
  121. }
  122. return nil
  123. },
  124. }
  125. func Execute() {
  126. if err := rootCmd.Execute(); err != nil {
  127. os.Exit(1)
  128. }
  129. }
  130. func parseServerConfigFromCmd() (*v1.ServerConfig, error) {
  131. cfg := &v1.ServerConfig{}
  132. cfg.BindAddr = bindAddr
  133. cfg.BindPort = bindPort
  134. cfg.KCPBindPort = kcpBindPort
  135. cfg.ProxyBindAddr = proxyBindAddr
  136. cfg.VhostHTTPPort = vhostHTTPPort
  137. cfg.VhostHTTPSPort = vhostHTTPSPort
  138. cfg.VhostHTTPTimeout = vhostHTTPTimeout
  139. cfg.WebServer.Addr = dashboardAddr
  140. cfg.WebServer.Port = dashboardPort
  141. cfg.WebServer.User = dashboardUser
  142. cfg.WebServer.Password = dashboardPwd
  143. cfg.EnablePrometheus = enablePrometheus
  144. if dashboardTLSMode {
  145. cfg.WebServer.TLS = &v1.TLSConfig{
  146. CertFile: dashboardTLSCertFile,
  147. KeyFile: dashboardTLSKeyFile,
  148. }
  149. }
  150. cfg.Log.To = logFile
  151. cfg.Log.Level = logLevel
  152. cfg.Log.MaxDays = logMaxDays
  153. cfg.Log.DisablePrintColor = disableLogColor
  154. cfg.SubDomainHost = subDomainHost
  155. cfg.TLS.Force = tlsOnly
  156. cfg.MaxPortsPerClient = maxPortsPerClient
  157. // Only token authentication is supported in cmd mode
  158. cfg.Auth.Token = token
  159. if len(allowPorts) > 0 {
  160. portsRanges, err := types.NewPortsRangeSliceFromString(allowPorts)
  161. if err != nil {
  162. return cfg, fmt.Errorf("allow_ports format error: %v", err)
  163. }
  164. cfg.AllowPorts = portsRanges
  165. }
  166. cfg.Complete()
  167. return cfg, nil
  168. }
  169. func runServer(cfg *v1.ServerConfig) (err error) {
  170. log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
  171. if cfgFile != "" {
  172. log.Info("frps uses config file: %s", cfgFile)
  173. } else {
  174. log.Info("frps uses command line arguments for config")
  175. }
  176. svr, err := server.NewService(cfg)
  177. if err != nil {
  178. return err
  179. }
  180. log.Info("frps started successfully")
  181. svr.Run(context.Background())
  182. return
  183. }