root.go 6.6 KB
Newer Older
F
fatedier 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright 2018 fatedier, fatedier@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

F
fatedier 已提交
15 16 17 18 19 20
package main

import (
	"fmt"
	"os"

F
fatedier 已提交
21 22 23 24 25
	"github.com/fatedier/frp/pkg/auth"
	"github.com/fatedier/frp/pkg/config"
	"github.com/fatedier/frp/pkg/util/log"
	"github.com/fatedier/frp/pkg/util/util"
	"github.com/fatedier/frp/pkg/util/version"
F
fatedier 已提交
26
	"github.com/fatedier/frp/server"
F
fatedier 已提交
27 28

	"github.com/spf13/cobra"
F
fatedier 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41
)

const (
	CfgFileTypeIni = iota
	CfgFileTypeCmd
)

var (
	cfgFile     string
	showVersion bool

	bindAddr          string
	bindPort          int
F
fatedier 已提交
42
	bindUDPPort       int
F
fatedier 已提交
43 44
	kcpBindPort       int
	proxyBindAddr     string
F
fatedier 已提交
45 46 47
	vhostHTTPPort     int
	vhostHTTPSPort    int
	vhostHTTPTimeout  int64
F
fatedier 已提交
48 49 50 51 52 53 54 55
	dashboardAddr     string
	dashboardPort     int
	dashboardUser     string
	dashboardPwd      string
	assetsDir         string
	logFile           string
	logLevel          string
	logMaxDays        int64
56
	disableLogColor   bool
F
fatedier 已提交
57 58 59 60 61 62
	token             string
	subDomainHost     string
	tcpMux            bool
	allowPorts        string
	maxPoolCount      int64
	maxPortsPerClient int64
63
	tlsOnly           bool
F
fatedier 已提交
64 65 66
)

func init() {
F
fix  
fatedier 已提交
67
	rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file of frps")
T
Tank 已提交
68
	rootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false, "version of frps")
F
fatedier 已提交
69

F
fix  
fatedier 已提交
70
	rootCmd.PersistentFlags().StringVarP(&bindAddr, "bind_addr", "", "0.0.0.0", "bind address")
F
fatedier 已提交
71
	rootCmd.PersistentFlags().IntVarP(&bindPort, "bind_port", "p", 7000, "bind port")
F
fatedier 已提交
72
	rootCmd.PersistentFlags().IntVarP(&bindUDPPort, "bind_udp_port", "", 0, "bind udp port")
F
fatedier 已提交
73 74
	rootCmd.PersistentFlags().IntVarP(&kcpBindPort, "kcp_bind_port", "", 0, "kcp bind udp port")
	rootCmd.PersistentFlags().StringVarP(&proxyBindAddr, "proxy_bind_addr", "", "0.0.0.0", "proxy bind address")
F
fatedier 已提交
75 76 77
	rootCmd.PersistentFlags().IntVarP(&vhostHTTPPort, "vhost_http_port", "", 0, "vhost http port")
	rootCmd.PersistentFlags().IntVarP(&vhostHTTPSPort, "vhost_https_port", "", 0, "vhost https port")
	rootCmd.PersistentFlags().Int64VarP(&vhostHTTPTimeout, "vhost_http_timeout", "", 60, "vhost http response header timeout")
F
fatedier 已提交
78 79 80 81 82 83
	rootCmd.PersistentFlags().StringVarP(&dashboardAddr, "dashboard_addr", "", "0.0.0.0", "dasboard address")
	rootCmd.PersistentFlags().IntVarP(&dashboardPort, "dashboard_port", "", 0, "dashboard port")
	rootCmd.PersistentFlags().StringVarP(&dashboardUser, "dashboard_user", "", "admin", "dashboard user")
	rootCmd.PersistentFlags().StringVarP(&dashboardPwd, "dashboard_pwd", "", "admin", "dashboard password")
	rootCmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "log file")
	rootCmd.PersistentFlags().StringVarP(&logLevel, "log_level", "", "info", "log level")
Z
zhangwei 已提交
84
	rootCmd.PersistentFlags().Int64VarP(&logMaxDays, "log_max_days", "", 3, "log max days")
85 86
	rootCmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")

F
fatedier 已提交
87
	rootCmd.PersistentFlags().StringVarP(&token, "token", "t", "", "auth token")
F
fatedier 已提交
88
	rootCmd.PersistentFlags().StringVarP(&subDomainHost, "subdomain_host", "", "", "subdomain host")
K
kac- 已提交
89
	rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
F
fatedier 已提交
90
	rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
91
	rootCmd.PersistentFlags().BoolVarP(&tlsOnly, "tls_only", "", false, "frps tls only")
F
fatedier 已提交
92 93 94 95 96 97 98 99 100 101 102
}

var rootCmd = &cobra.Command{
	Use:   "frps",
	Short: "frps is the server of frp (https://github.com/fatedier/frp)",
	RunE: func(cmd *cobra.Command, args []string) error {
		if showVersion {
			fmt.Println(version.Full())
			return nil
		}

103
		var cfg config.ServerCommonConf
H
hanshuai 已提交
104
		var err error
F
fatedier 已提交
105
		if cfgFile != "" {
106 107 108 109 110
			var content string
			content, err = config.GetRenderedConfFromFile(cfgFile)
			if err != nil {
				return err
			}
111
			cfg, err = parseServerCommonCfg(CfgFileTypeIni, content)
F
fatedier 已提交
112
		} else {
113
			cfg, err = parseServerCommonCfg(CfgFileTypeCmd, "")
H
hanshuai 已提交
114 115 116
		}
		if err != nil {
			return err
F
fatedier 已提交
117 118
		}

119
		err = runServer(cfg)
F
fatedier 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		return nil
	},
}

func Execute() {
	if err := rootCmd.Execute(); err != nil {
		os.Exit(1)
	}
}

134
func parseServerCommonCfg(fileType int, content string) (cfg config.ServerCommonConf, err error) {
F
fatedier 已提交
135
	if fileType == CfgFileTypeIni {
136
		cfg, err = parseServerCommonCfgFromIni(content)
F
fatedier 已提交
137
	} else if fileType == CfgFileTypeCmd {
138
		cfg, err = parseServerCommonCfgFromCmd()
F
fatedier 已提交
139 140 141 142 143
	}
	if err != nil {
		return
	}

144
	err = cfg.Check()
F
fatedier 已提交
145 146 147 148 149 150
	if err != nil {
		return
	}
	return
}

151 152
func parseServerCommonCfgFromIni(content string) (config.ServerCommonConf, error) {
	cfg, err := config.UnmarshalServerConfFromIni(content)
F
fatedier 已提交
153
	if err != nil {
154
		return config.ServerCommonConf{}, err
F
fatedier 已提交
155
	}
156
	return cfg, nil
F
fatedier 已提交
157 158
}

159 160 161 162 163
func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
	cfg = config.GetDefaultServerConf()

	cfg.BindAddr = bindAddr
	cfg.BindPort = bindPort
F
fatedier 已提交
164 165
	cfg.BindUDPPort = bindUDPPort
	cfg.KCPBindPort = kcpBindPort
166
	cfg.ProxyBindAddr = proxyBindAddr
F
fatedier 已提交
167 168 169
	cfg.VhostHTTPPort = vhostHTTPPort
	cfg.VhostHTTPSPort = vhostHTTPSPort
	cfg.VhostHTTPTimeout = vhostHTTPTimeout
170 171 172 173 174 175 176 177
	cfg.DashboardAddr = dashboardAddr
	cfg.DashboardPort = dashboardPort
	cfg.DashboardUser = dashboardUser
	cfg.DashboardPwd = dashboardPwd
	cfg.LogFile = logFile
	cfg.LogLevel = logLevel
	cfg.LogMaxDays = logMaxDays
	cfg.SubDomainHost = subDomainHost
F
fatedier 已提交
178
	cfg.TLSOnly = tlsOnly
179 180

	// Only token authentication is supported in cmd mode
F
fatedier 已提交
181
	cfg.ServerConfig = auth.GetDefaultServerConf()
182
	cfg.Token = token
K
kac- 已提交
183 184 185 186 187 188 189 190 191
	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 {
192
			cfg.AllowPorts[int(port)] = struct{}{}
K
kac- 已提交
193 194
		}
	}
195
	cfg.MaxPortsPerClient = maxPortsPerClient
F
fatedier 已提交
196 197

	if logFile == "console" {
198
		cfg.LogWay = "console"
F
fatedier 已提交
199
	} else {
200
		cfg.LogWay = "file"
F
fatedier 已提交
201
	}
202
	cfg.DisableLogColor = disableLogColor
F
fatedier 已提交
203 204 205
	return
}

206 207 208
func runServer(cfg config.ServerCommonConf) (err error) {
	log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, cfg.LogMaxDays, cfg.DisableLogColor)
	svr, err := server.NewService(cfg)
F
fatedier 已提交
209 210 211
	if err != nil {
		return err
	}
F
fatedier 已提交
212
	log.Info("start frps success")
F
fatedier 已提交
213 214 215
	svr.Run()
	return
}