flags.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // Copyright 2023 The frp Authors
  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 config
  15. import (
  16. "fmt"
  17. "strconv"
  18. "strings"
  19. "github.com/spf13/cobra"
  20. "github.com/spf13/pflag"
  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. )
  25. // WordSepNormalizeFunc changes all flags that contain "_" separators
  26. func WordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
  27. if strings.Contains(name, "_") {
  28. return pflag.NormalizedName(strings.ReplaceAll(name, "_", "-"))
  29. }
  30. return pflag.NormalizedName(name)
  31. }
  32. type RegisterFlagOption func(*registerFlagOptions)
  33. type registerFlagOptions struct {
  34. sshMode bool
  35. }
  36. func WithSSHMode() RegisterFlagOption {
  37. return func(o *registerFlagOptions) {
  38. o.sshMode = true
  39. }
  40. }
  41. type BandwidthQuantityFlag struct {
  42. V *types.BandwidthQuantity
  43. }
  44. func (f *BandwidthQuantityFlag) Set(s string) error {
  45. return f.V.UnmarshalString(s)
  46. }
  47. func (f *BandwidthQuantityFlag) String() string {
  48. return f.V.String()
  49. }
  50. func (f *BandwidthQuantityFlag) Type() string {
  51. return "string"
  52. }
  53. func RegisterProxyFlags(cmd *cobra.Command, c v1.ProxyConfigurer, opts ...RegisterFlagOption) {
  54. registerProxyBaseConfigFlags(cmd, c.GetBaseConfig(), opts...)
  55. switch cc := c.(type) {
  56. case *v1.TCPProxyConfig:
  57. cmd.Flags().IntVarP(&cc.RemotePort, "remote_port", "r", 0, "remote port")
  58. case *v1.UDPProxyConfig:
  59. cmd.Flags().IntVarP(&cc.RemotePort, "remote_port", "r", 0, "remote port")
  60. case *v1.HTTPProxyConfig:
  61. registerProxyDomainConfigFlags(cmd, &cc.DomainConfig)
  62. cmd.Flags().StringSliceVarP(&cc.Locations, "locations", "", []string{}, "locations")
  63. cmd.Flags().StringVarP(&cc.HTTPUser, "http_user", "", "", "http auth user")
  64. cmd.Flags().StringVarP(&cc.HTTPPassword, "http_pwd", "", "", "http auth password")
  65. cmd.Flags().StringVarP(&cc.HostHeaderRewrite, "host_header_rewrite", "", "", "host header rewrite")
  66. case *v1.HTTPSProxyConfig:
  67. registerProxyDomainConfigFlags(cmd, &cc.DomainConfig)
  68. case *v1.TCPMuxProxyConfig:
  69. registerProxyDomainConfigFlags(cmd, &cc.DomainConfig)
  70. cmd.Flags().StringVarP(&cc.Multiplexer, "mux", "", "", "multiplexer")
  71. cmd.Flags().StringVarP(&cc.HTTPUser, "http_user", "", "", "http auth user")
  72. cmd.Flags().StringVarP(&cc.HTTPPassword, "http_pwd", "", "", "http auth password")
  73. case *v1.STCPProxyConfig:
  74. cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key")
  75. cmd.Flags().StringSliceVarP(&cc.AllowUsers, "allow_users", "", []string{}, "allow visitor users")
  76. case *v1.SUDPProxyConfig:
  77. cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key")
  78. cmd.Flags().StringSliceVarP(&cc.AllowUsers, "allow_users", "", []string{}, "allow visitor users")
  79. case *v1.XTCPProxyConfig:
  80. cmd.Flags().StringVarP(&cc.Secretkey, "sk", "", "", "secret key")
  81. cmd.Flags().StringSliceVarP(&cc.AllowUsers, "allow_users", "", []string{}, "allow visitor users")
  82. }
  83. }
  84. func registerProxyBaseConfigFlags(cmd *cobra.Command, c *v1.ProxyBaseConfig, opts ...RegisterFlagOption) {
  85. if c == nil {
  86. return
  87. }
  88. options := &registerFlagOptions{}
  89. for _, opt := range opts {
  90. opt(options)
  91. }
  92. cmd.Flags().StringVarP(&c.Name, "proxy_name", "n", "", "proxy name")
  93. if !options.sshMode {
  94. cmd.Flags().StringVarP(&c.LocalIP, "local_ip", "i", "127.0.0.1", "local ip")
  95. cmd.Flags().IntVarP(&c.LocalPort, "local_port", "l", 0, "local port")
  96. cmd.Flags().BoolVarP(&c.Transport.UseEncryption, "ue", "", false, "use encryption")
  97. cmd.Flags().BoolVarP(&c.Transport.UseCompression, "uc", "", false, "use compression")
  98. cmd.Flags().StringVarP(&c.Transport.BandwidthLimitMode, "bandwidth_limit_mode", "", types.BandwidthLimitModeClient, "bandwidth limit mode")
  99. cmd.Flags().VarP(&BandwidthQuantityFlag{V: &c.Transport.BandwidthLimit}, "bandwidth_limit", "", "bandwidth limit (e.g. 100KB or 1MB)")
  100. }
  101. }
  102. func registerProxyDomainConfigFlags(cmd *cobra.Command, c *v1.DomainConfig) {
  103. if c == nil {
  104. return
  105. }
  106. cmd.Flags().StringSliceVarP(&c.CustomDomains, "custom_domain", "d", []string{}, "custom domains")
  107. cmd.Flags().StringVarP(&c.SubDomain, "sd", "", "", "sub domain")
  108. }
  109. func RegisterVisitorFlags(cmd *cobra.Command, c v1.VisitorConfigurer, opts ...RegisterFlagOption) {
  110. registerVisitorBaseConfigFlags(cmd, c.GetBaseConfig(), opts...)
  111. // add visitor flags if exist
  112. }
  113. func registerVisitorBaseConfigFlags(cmd *cobra.Command, c *v1.VisitorBaseConfig, _ ...RegisterFlagOption) {
  114. if c == nil {
  115. return
  116. }
  117. cmd.Flags().StringVarP(&c.Name, "visitor_name", "n", "", "visitor name")
  118. cmd.Flags().BoolVarP(&c.Transport.UseEncryption, "ue", "", false, "use encryption")
  119. cmd.Flags().BoolVarP(&c.Transport.UseCompression, "uc", "", false, "use compression")
  120. cmd.Flags().StringVarP(&c.SecretKey, "sk", "", "", "secret key")
  121. cmd.Flags().StringVarP(&c.ServerName, "server_name", "", "", "server name")
  122. cmd.Flags().StringVarP(&c.ServerUser, "server-user", "", "", "server user")
  123. cmd.Flags().StringVarP(&c.BindAddr, "bind_addr", "", "", "bind addr")
  124. cmd.Flags().IntVarP(&c.BindPort, "bind_port", "", 0, "bind port")
  125. }
  126. func RegisterClientCommonConfigFlags(cmd *cobra.Command, c *v1.ClientCommonConfig, opts ...RegisterFlagOption) {
  127. options := &registerFlagOptions{}
  128. for _, opt := range opts {
  129. opt(options)
  130. }
  131. if !options.sshMode {
  132. cmd.PersistentFlags().StringVarP(&c.ServerAddr, "server_addr", "s", "127.0.0.1", "frp server's address")
  133. cmd.PersistentFlags().IntVarP(&c.ServerPort, "server_port", "P", 7000, "frp server's port")
  134. cmd.PersistentFlags().StringVarP(&c.Transport.Protocol, "protocol", "p", "tcp",
  135. fmt.Sprintf("optional values are %v", validation.SupportedTransportProtocols))
  136. cmd.PersistentFlags().StringVarP(&c.Log.Level, "log_level", "", "info", "log level")
  137. cmd.PersistentFlags().StringVarP(&c.Log.To, "log_file", "", "console", "console or file path")
  138. cmd.PersistentFlags().Int64VarP(&c.Log.MaxDays, "log_max_days", "", 3, "log file reversed days")
  139. cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console")
  140. cmd.PersistentFlags().StringVarP(&c.Transport.TLS.ServerName, "tls_server_name", "", "", "specify the custom server name of tls certificate")
  141. cmd.PersistentFlags().StringVarP(&c.DNSServer, "dns_server", "", "", "specify dns server instead of using system default one")
  142. c.Transport.TLS.Enable = cmd.PersistentFlags().BoolP("tls_enable", "", true, "enable frpc tls")
  143. }
  144. cmd.PersistentFlags().StringVarP(&c.User, "user", "u", "", "user")
  145. cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token")
  146. }
  147. type PortsRangeSliceFlag struct {
  148. V *[]types.PortsRange
  149. }
  150. func (f *PortsRangeSliceFlag) String() string {
  151. if f.V == nil {
  152. return ""
  153. }
  154. return types.PortsRangeSlice(*f.V).String()
  155. }
  156. func (f *PortsRangeSliceFlag) Set(s string) error {
  157. slice, err := types.NewPortsRangeSliceFromString(s)
  158. if err != nil {
  159. return err
  160. }
  161. *f.V = slice
  162. return nil
  163. }
  164. func (f *PortsRangeSliceFlag) Type() string {
  165. return "string"
  166. }
  167. type BoolFuncFlag struct {
  168. TrueFunc func()
  169. FalseFunc func()
  170. v bool
  171. }
  172. func (f *BoolFuncFlag) String() string {
  173. return strconv.FormatBool(f.v)
  174. }
  175. func (f *BoolFuncFlag) Set(s string) error {
  176. f.v = strconv.FormatBool(f.v) == "true"
  177. if !f.v {
  178. if f.FalseFunc != nil {
  179. f.FalseFunc()
  180. }
  181. return nil
  182. }
  183. if f.TrueFunc != nil {
  184. f.TrueFunc()
  185. }
  186. return nil
  187. }
  188. func (f *BoolFuncFlag) Type() string {
  189. return "bool"
  190. }
  191. func RegisterServerConfigFlags(cmd *cobra.Command, c *v1.ServerConfig, opts ...RegisterFlagOption) {
  192. cmd.PersistentFlags().StringVarP(&c.BindAddr, "bind_addr", "", "0.0.0.0", "bind address")
  193. cmd.PersistentFlags().IntVarP(&c.BindPort, "bind_port", "p", 7000, "bind port")
  194. cmd.PersistentFlags().IntVarP(&c.KCPBindPort, "kcp_bind_port", "", 0, "kcp bind udp port")
  195. cmd.PersistentFlags().StringVarP(&c.ProxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address")
  196. cmd.PersistentFlags().IntVarP(&c.VhostHTTPPort, "vhost_http_port", "", 0, "vhost http port")
  197. cmd.PersistentFlags().IntVarP(&c.VhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port")
  198. cmd.PersistentFlags().Int64VarP(&c.VhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout")
  199. cmd.PersistentFlags().StringVarP(&c.WebServer.Addr, "dashboard_addr", "", "0.0.0.0", "dashboard address")
  200. cmd.PersistentFlags().IntVarP(&c.WebServer.Port, "dashboard_port", "", 0, "dashboard port")
  201. cmd.PersistentFlags().StringVarP(&c.WebServer.User, "dashboard_user", "", "admin", "dashboard user")
  202. cmd.PersistentFlags().StringVarP(&c.WebServer.Password, "dashboard_pwd", "", "admin", "dashboard password")
  203. cmd.PersistentFlags().BoolVarP(&c.EnablePrometheus, "enable_prometheus", "", false, "enable prometheus dashboard")
  204. cmd.PersistentFlags().StringVarP(&c.Log.To, "log_file", "", "console", "log file")
  205. cmd.PersistentFlags().StringVarP(&c.Log.Level, "log_level", "", "info", "log level")
  206. cmd.PersistentFlags().Int64VarP(&c.Log.MaxDays, "log_max_days", "", 3, "log max days")
  207. cmd.PersistentFlags().BoolVarP(&c.Log.DisablePrintColor, "disable_log_color", "", false, "disable log color in console")
  208. cmd.PersistentFlags().StringVarP(&c.Auth.Token, "token", "t", "", "auth token")
  209. cmd.PersistentFlags().StringVarP(&c.SubDomainHost, "subdomain_host", "", "", "subdomain host")
  210. cmd.PersistentFlags().VarP(&PortsRangeSliceFlag{V: &c.AllowPorts}, "allow_ports", "", "allow ports")
  211. cmd.PersistentFlags().Int64VarP(&c.MaxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
  212. cmd.PersistentFlags().BoolVarP(&c.Transport.TLS.Force, "tls_only", "", false, "frps tls only")
  213. webServerTLS := v1.TLSConfig{}
  214. cmd.PersistentFlags().StringVarP(&webServerTLS.CertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file")
  215. cmd.PersistentFlags().StringVarP(&webServerTLS.KeyFile, "dashboard_tls_key_file", "", "", "dashboard tls key file")
  216. cmd.PersistentFlags().VarP(&BoolFuncFlag{
  217. TrueFunc: func() { c.WebServer.TLS = &webServerTLS },
  218. }, "dashboard_tls_mode", "", "if enable dashboard tls mode")
  219. }