root.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. fmt.Println(err)
  101. os.Exit(1)
  102. }
  103. if isLegacyFormat {
  104. fmt.Printf("WARNING: ini format is deprecated and the support will be removed in the future, " +
  105. "please use yaml/json/toml format instead!\n")
  106. }
  107. } else {
  108. if svrCfg, err = parseServerConfigFromCmd(); err != nil {
  109. fmt.Println(err)
  110. os.Exit(1)
  111. }
  112. }
  113. warning, err := validation.ValidateServerConfig(svrCfg)
  114. if warning != nil {
  115. fmt.Printf("WARNING: %v\n", warning)
  116. }
  117. if err != nil {
  118. fmt.Println(err)
  119. os.Exit(1)
  120. }
  121. if err := runServer(svrCfg); err != nil {
  122. fmt.Println(err)
  123. os.Exit(1)
  124. }
  125. return nil
  126. },
  127. }
  128. func Execute() {
  129. if err := rootCmd.Execute(); err != nil {
  130. os.Exit(1)
  131. }
  132. }
  133. func parseServerConfigFromCmd() (*v1.ServerConfig, error) {
  134. cfg := &v1.ServerConfig{}
  135. cfg.BindAddr = bindAddr
  136. cfg.BindPort = bindPort
  137. cfg.KCPBindPort = kcpBindPort
  138. cfg.ProxyBindAddr = proxyBindAddr
  139. cfg.VhostHTTPPort = vhostHTTPPort
  140. cfg.VhostHTTPSPort = vhostHTTPSPort
  141. cfg.VhostHTTPTimeout = vhostHTTPTimeout
  142. cfg.WebServer.Addr = dashboardAddr
  143. cfg.WebServer.Port = dashboardPort
  144. cfg.WebServer.User = dashboardUser
  145. cfg.WebServer.Password = dashboardPwd
  146. cfg.EnablePrometheus = enablePrometheus
  147. if dashboardTLSMode {
  148. cfg.WebServer.TLS = &v1.TLSConfig{
  149. CertFile: dashboardTLSCertFile,
  150. KeyFile: dashboardTLSKeyFile,
  151. }
  152. }
  153. cfg.Log.To = logFile
  154. cfg.Log.Level = logLevel
  155. cfg.Log.MaxDays = logMaxDays
  156. cfg.Log.DisablePrintColor = disableLogColor
  157. cfg.SubDomainHost = subDomainHost
  158. cfg.Transport.TLS.Force = tlsOnly
  159. cfg.MaxPortsPerClient = maxPortsPerClient
  160. // Only token authentication is supported in cmd mode
  161. cfg.Auth.Token = token
  162. if len(allowPorts) > 0 {
  163. portsRanges, err := types.NewPortsRangeSliceFromString(allowPorts)
  164. if err != nil {
  165. return cfg, fmt.Errorf("allow_ports format error: %v", err)
  166. }
  167. cfg.AllowPorts = portsRanges
  168. }
  169. cfg.Complete()
  170. return cfg, nil
  171. }
  172. func runServer(cfg *v1.ServerConfig) (err error) {
  173. log.InitLog(cfg.Log.To, cfg.Log.Level, cfg.Log.MaxDays, cfg.Log.DisablePrintColor)
  174. if cfgFile != "" {
  175. log.Info("frps uses config file: %s", cfgFile)
  176. } else {
  177. log.Info("frps uses command line arguments for config")
  178. }
  179. svr, err := server.NewService(cfg)
  180. if err != nil {
  181. return err
  182. }
  183. log.Info("frps started successfully")
  184. svr.Run(context.Background())
  185. return
  186. }