"Fossies" - the Fresh Open Source Software Archive

Member "frp-0.36.2/pkg/config/server.go" (22 Mar 2021, 12308 Bytes) of package /linux/misc/frp-0.36.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "server.go": 0.36.1_vs_0.36.2.

    1 // Copyright 2020 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 
   15 package config
   16 
   17 import (
   18     "fmt"
   19     "strings"
   20 
   21     "github.com/fatedier/frp/pkg/auth"
   22     plugin "github.com/fatedier/frp/pkg/plugin/server"
   23     "github.com/fatedier/frp/pkg/util/util"
   24 
   25     "gopkg.in/ini.v1"
   26 )
   27 
   28 // ServerCommonConf contains information for a server service. It is
   29 // recommended to use GetDefaultServerConf instead of creating this object
   30 // directly, so that all unspecified fields have reasonable default values.
   31 type ServerCommonConf struct {
   32     auth.ServerConfig `ini:",extends"`
   33 
   34     // BindAddr specifies the address that the server binds to. By default,
   35     // this value is "0.0.0.0".
   36     BindAddr string `ini:"bind_addr" json:"bind_addr"`
   37     // BindPort specifies the port that the server listens on. By default, this
   38     // value is 7000.
   39     BindPort int `ini:"bind_port" json:"bind_port"`
   40     // BindUDPPort specifies the UDP port that the server listens on. If this
   41     // value is 0, the server will not listen for UDP connections. By default,
   42     // this value is 0
   43     BindUDPPort int `ini:"bind_udp_port" json:"bind_udp_port"`
   44     // KCPBindPort specifies the KCP port that the server listens on. If this
   45     // value is 0, the server will not listen for KCP connections. By default,
   46     // this value is 0.
   47     KCPBindPort int `ini:"kcp_bind_port" json:"kcp_bind_port"`
   48     // ProxyBindAddr specifies the address that the proxy binds to. This value
   49     // may be the same as BindAddr.
   50     ProxyBindAddr string `ini:"proxy_bind_addr" json:"proxy_bind_addr"`
   51     // VhostHTTPPort specifies the port that the server listens for HTTP Vhost
   52     // requests. If this value is 0, the server will not listen for HTTP
   53     // requests. By default, this value is 0.
   54     VhostHTTPPort int `ini:"vhost_http_port" json:"vhost_http_port"`
   55     // VhostHTTPSPort specifies the port that the server listens for HTTPS
   56     // Vhost requests. If this value is 0, the server will not listen for HTTPS
   57     // requests. By default, this value is 0.
   58     VhostHTTPSPort int `ini:"vhost_https_port" json:"vhost_https_port"`
   59     // TCPMuxHTTPConnectPort specifies the port that the server listens for TCP
   60     // HTTP CONNECT requests. If the value is 0, the server will not multiplex TCP
   61     // requests on one single port. If it's not - it will listen on this value for
   62     // HTTP CONNECT requests. By default, this value is 0.
   63     TCPMuxHTTPConnectPort int `ini:"tcpmux_httpconnect_port" json:"tcpmux_httpconnect_port"`
   64     // VhostHTTPTimeout specifies the response header timeout for the Vhost
   65     // HTTP server, in seconds. By default, this value is 60.
   66     VhostHTTPTimeout int64 `ini:"vhost_http_timeout" json:"vhost_http_timeout"`
   67     // DashboardAddr specifies the address that the dashboard binds to. By
   68     // default, this value is "0.0.0.0".
   69     DashboardAddr string `ini:"dashboard_addr" json:"dashboard_addr"`
   70     // DashboardPort specifies the port that the dashboard listens on. If this
   71     // value is 0, the dashboard will not be started. By default, this value is
   72     // 0.
   73     DashboardPort int `ini:"dashboard_port" json:"dashboard_port"`
   74     // DashboardUser specifies the username that the dashboard will use for
   75     // login. By default, this value is "admin".
   76     DashboardUser string `ini:"dashboard_user" json:"dashboard_user"`
   77     // DashboardUser specifies the password that the dashboard will use for
   78     // login. By default, this value is "admin".
   79     DashboardPwd string `ini:"dashboard_pwd" json:"dashboard_pwd"`
   80     // EnablePrometheus will export prometheus metrics on {dashboard_addr}:{dashboard_port}
   81     // in /metrics api.
   82     EnablePrometheus bool `ini:"enable_prometheus" json:"enable_prometheus"`
   83     // AssetsDir specifies the local directory that the dashboard will load
   84     // resources from. If this value is "", assets will be loaded from the
   85     // bundled executable using statik. By default, this value is "".
   86     AssetsDir string `ini:"assets_dir" json:"assets_dir"`
   87     // LogFile specifies a file where logs will be written to. This value will
   88     // only be used if LogWay is set appropriately. By default, this value is
   89     // "console".
   90     LogFile string `ini:"log_file" json:"log_file"`
   91     // LogWay specifies the way logging is managed. Valid values are "console"
   92     // or "file". If "console" is used, logs will be printed to stdout. If
   93     // "file" is used, logs will be printed to LogFile. By default, this value
   94     // is "console".
   95     LogWay string `ini:"log_way" json:"log_way"`
   96     // LogLevel specifies the minimum log level. Valid values are "trace",
   97     // "debug", "info", "warn", and "error". By default, this value is "info".
   98     LogLevel string `ini:"log_level" json:"log_level"`
   99     // LogMaxDays specifies the maximum number of days to store log information
  100     // before deletion. This is only used if LogWay == "file". By default, this
  101     // value is 0.
  102     LogMaxDays int64 `ini:"log_max_days" json:"log_max_days"`
  103     // DisableLogColor disables log colors when LogWay == "console" when set to
  104     // true. By default, this value is false.
  105     DisableLogColor bool `ini:"disable_log_color" json:"disable_log_color"`
  106     // DetailedErrorsToClient defines whether to send the specific error (with
  107     // debug info) to frpc. By default, this value is true.
  108     DetailedErrorsToClient bool `ini:"detailed_errors_to_client" json:"detailed_errors_to_client"`
  109 
  110     // SubDomainHost specifies the domain that will be attached to sub-domains
  111     // requested by the client when using Vhost proxying. For example, if this
  112     // value is set to "frps.com" and the client requested the subdomain
  113     // "test", the resulting URL would be "test.frps.com". By default, this
  114     // value is "".
  115     SubDomainHost string `ini:"subdomain_host" json:"subdomain_host"`
  116     // TCPMux toggles TCP stream multiplexing. This allows multiple requests
  117     // from a client to share a single TCP connection. By default, this value
  118     // is true.
  119     TCPMux bool `ini:"tcp_mux" json:"tcp_mux"`
  120     // Custom404Page specifies a path to a custom 404 page to display. If this
  121     // value is "", a default page will be displayed. By default, this value is
  122     // "".
  123     Custom404Page string `ini:"custom_404_page" json:"custom_404_page"`
  124 
  125     // AllowPorts specifies a set of ports that clients are able to proxy to.
  126     // If the length of this value is 0, all ports are allowed. By default,
  127     // this value is an empty set.
  128     AllowPorts map[int]struct{} `ini:"-" json:"-"`
  129     // MaxPoolCount specifies the maximum pool size for each proxy. By default,
  130     // this value is 5.
  131     MaxPoolCount int64 `ini:"max_pool_count" json:"max_pool_count"`
  132     // MaxPortsPerClient specifies the maximum number of ports a single client
  133     // may proxy to. If this value is 0, no limit will be applied. By default,
  134     // this value is 0.
  135     MaxPortsPerClient int64 `ini:"max_ports_per_client" json:"max_ports_per_client"`
  136     // TLSOnly specifies whether to only accept TLS-encrypted connections.
  137     // By default, the value is false.
  138     TLSOnly bool `ini:"tls_only" json:"tls_only"`
  139     // TLSCertFile specifies the path of the cert file that the server will
  140     // load. If "tls_cert_file", "tls_key_file" are valid, the server will use this
  141     // supplied tls configuration. Otherwise, the server will use the tls
  142     // configuration generated by itself.
  143     TLSCertFile string `ini:"tls_cert_file" json:"tls_cert_file"`
  144     // TLSKeyFile specifies the path of the secret key that the server will
  145     // load. If "tls_cert_file", "tls_key_file" are valid, the server will use this
  146     // supplied tls configuration. Otherwise, the server will use the tls
  147     // configuration generated by itself.
  148     TLSKeyFile string `ini:"tls_key_file" json:"tls_key_file"`
  149     // TLSTrustedCaFile specifies the paths of the client cert files that the
  150     // server will load. It only works when "tls_only" is true. If
  151     // "tls_trusted_ca_file" is valid, the server will verify each client's
  152     // certificate.
  153     TLSTrustedCaFile string `ini:"tls_trusted_ca_file" json:"tls_trusted_ca_file"`
  154     // HeartBeatTimeout specifies the maximum time to wait for a heartbeat
  155     // before terminating the connection. It is not recommended to change this
  156     // value. By default, this value is 90.
  157     HeartbeatTimeout int64 `ini:"heartbeat_timeout" json:"heartbeat_timeout"`
  158     // UserConnTimeout specifies the maximum time to wait for a work
  159     // connection. By default, this value is 10.
  160     UserConnTimeout int64 `ini:"user_conn_timeout" json:"user_conn_timeout"`
  161     // HTTPPlugins specify the server plugins support HTTP protocol.
  162     HTTPPlugins map[string]plugin.HTTPPluginOptions `ini:"-" json:"http_plugins"`
  163     // UDPPacketSize specifies the UDP packet size
  164     // By default, this value is 1500
  165     UDPPacketSize int64 `ini:"udp_packet_size" json:"udp_packet_size"`
  166 }
  167 
  168 // GetDefaultServerConf returns a server configuration with reasonable
  169 // defaults.
  170 func GetDefaultServerConf() ServerCommonConf {
  171     return ServerCommonConf{
  172         ServerConfig:           auth.GetDefaultServerConf(),
  173         BindAddr:               "0.0.0.0",
  174         BindPort:               7000,
  175         BindUDPPort:            0,
  176         KCPBindPort:            0,
  177         ProxyBindAddr:          "",
  178         VhostHTTPPort:          0,
  179         VhostHTTPSPort:         0,
  180         TCPMuxHTTPConnectPort:  0,
  181         VhostHTTPTimeout:       60,
  182         DashboardAddr:          "0.0.0.0",
  183         DashboardPort:          0,
  184         DashboardUser:          "admin",
  185         DashboardPwd:           "admin",
  186         EnablePrometheus:       false,
  187         AssetsDir:              "",
  188         LogFile:                "console",
  189         LogWay:                 "console",
  190         LogLevel:               "info",
  191         LogMaxDays:             3,
  192         DisableLogColor:        false,
  193         DetailedErrorsToClient: true,
  194         SubDomainHost:          "",
  195         TCPMux:                 true,
  196         AllowPorts:             make(map[int]struct{}),
  197         MaxPoolCount:           5,
  198         MaxPortsPerClient:      0,
  199         TLSOnly:                false,
  200         TLSCertFile:            "",
  201         TLSKeyFile:             "",
  202         TLSTrustedCaFile:       "",
  203         HeartbeatTimeout:       90,
  204         UserConnTimeout:        10,
  205         Custom404Page:          "",
  206         HTTPPlugins:            make(map[string]plugin.HTTPPluginOptions),
  207         UDPPacketSize:          1500,
  208     }
  209 }
  210 
  211 func UnmarshalServerConfFromIni(source interface{}) (ServerCommonConf, error) {
  212 
  213     f, err := ini.LoadSources(ini.LoadOptions{
  214         Insensitive:         false,
  215         InsensitiveSections: false,
  216         InsensitiveKeys:     false,
  217         IgnoreInlineComment: true,
  218         AllowBooleanKeys:    true,
  219     }, source)
  220     if err != nil {
  221         return ServerCommonConf{}, err
  222     }
  223 
  224     s, err := f.GetSection("common")
  225     if err != nil {
  226         // TODO: add error info
  227         return ServerCommonConf{}, err
  228     }
  229 
  230     common := GetDefaultServerConf()
  231     err = s.MapTo(&common)
  232     if err != nil {
  233         return ServerCommonConf{}, err
  234     }
  235 
  236     // allow_ports
  237     allowPortStr := s.Key("allow_ports").String()
  238     if allowPortStr != "" {
  239         allowPorts, err := util.ParseRangeNumbers(allowPortStr)
  240         if err != nil {
  241             return ServerCommonConf{}, fmt.Errorf("invalid allow_ports: %v", err)
  242         }
  243         for _, port := range allowPorts {
  244             common.AllowPorts[int(port)] = struct{}{}
  245         }
  246     }
  247 
  248     // plugin.xxx
  249     pluginOpts := make(map[string]plugin.HTTPPluginOptions)
  250     for _, section := range f.Sections() {
  251         name := section.Name()
  252         if !strings.HasPrefix(name, "plugin.") {
  253             continue
  254         }
  255 
  256         opt, err := loadHTTPPluginOpt(section)
  257         if err != nil {
  258             return ServerCommonConf{}, err
  259         }
  260 
  261         pluginOpts[opt.Name] = *opt
  262     }
  263     common.HTTPPlugins = pluginOpts
  264 
  265     return common, nil
  266 }
  267 
  268 func (cfg *ServerCommonConf) Complete() {
  269     if cfg.LogFile == "console" {
  270         cfg.LogWay = "console"
  271     } else {
  272         cfg.LogWay = "file"
  273     }
  274 
  275     if cfg.ProxyBindAddr == "" {
  276         cfg.ProxyBindAddr = cfg.BindAddr
  277     }
  278 
  279     if cfg.TLSTrustedCaFile != "" {
  280         cfg.TLSOnly = true
  281     }
  282 }
  283 
  284 func (cfg *ServerCommonConf) Validate() error {
  285     return nil
  286 }
  287 
  288 func loadHTTPPluginOpt(section *ini.Section) (*plugin.HTTPPluginOptions, error) {
  289     name := strings.TrimSpace(strings.TrimPrefix(section.Name(), "plugin."))
  290 
  291     opt := new(plugin.HTTPPluginOptions)
  292     err := section.MapTo(opt)
  293     if err != nil {
  294         return nil, err
  295     }
  296 
  297     opt.Name = name
  298 
  299     return opt, nil
  300 }