123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- package main
- import (
- "flag"
- "fmt"
- "github.com/astaxie/beego/logs"
- "github.com/ccding/go-stun/stun"
- "github.com/cnlh/nps/client"
- "github.com/cnlh/nps/lib/common"
- "github.com/cnlh/nps/lib/config"
- "github.com/cnlh/nps/lib/file"
- "github.com/cnlh/nps/lib/install"
- "github.com/cnlh/nps/lib/version"
- "github.com/kardianos/service"
- "os"
- "runtime"
- "strings"
- "time"
- )
- var (
- serverAddr = flag.String("server", "", "Server addr (ip:port)")
- configPath = flag.String("config", "", "Configuration file path")
- verifyKey = flag.String("vkey", "", "Authentication key")
- logType = flag.String("log", "stdout", "Log output mode(stdout|file)")
- connType = flag.String("type", "tcp", "Connection type with the server(kcp|tcp)")
- proxyUrl = flag.String("proxy", "", "proxy socks5 url(eg:socks5://111:222@127.0.0.1:9007)")
- logLevel = flag.String("log_level", "7", "log level 0~7")
- registerTime = flag.Int("time", 2, "register time long /h")
- localPort = flag.Int("local_port", 2000, "p2p local port")
- password = flag.String("password", "", "p2p password flag")
- target = flag.String("target", "", "p2p target")
- localType = flag.String("local_type", "p2p", "p2p target")
- logPath = flag.String("log_path", "", "npc log path")
- debug = flag.Bool("debug", true, "npc debug")
- )
- func main() {
- flag.Parse()
- logs.Reset()
- logs.EnableFuncCallDepth(true)
- logs.SetLogFuncCallDepth(3)
- if *logPath == "" {
- *logPath = common.GetNpcLogPath()
- }
- if common.IsWindows() {
- *logPath = strings.Replace(*logPath, "\\", "\\\\", -1)
- }
- if *debug {
- logs.SetLogger(logs.AdapterConsole, `{"level":`+*logLevel+`,"color":true}`)
- } else {
- logs.SetLogger(logs.AdapterFile, `{"level":`+*logLevel+`,"filename":"`+*logPath+`","daily":false,"maxlines":100000,"color":true}`)
- }
- // init service
- options := make(service.KeyValue)
- options["Restart"] = "on-success"
- options["SuccessExitStatus"] = "1 2 8 SIGKILL"
- svcConfig := &service.Config{
- Name: "Npc",
- DisplayName: "nps内网穿透客户端",
- Description: "一款轻量级、功能强大的内网穿透代理服务器。支持tcp、udp流量转发,支持内网http代理、内网socks5代理,同时支持snappy压缩、站点保护、加密传输、多路复用、header修改等。支持web图形化管理,集成多用户模式。",
- Option: options,
- }
- if !common.IsWindows() {
- svcConfig.Dependencies = []string{
- "Requires=network.target",
- "After=network-online.target syslog.target"}
- }
- for _, v := range os.Args[1:] {
- switch v {
- case "install", "start", "stop", "uninstall", "restart":
- continue
- }
- if !strings.Contains(v, "-service=") && !strings.Contains(v, "-debug=") {
- svcConfig.Arguments = append(svcConfig.Arguments, v)
- }
- }
- svcConfig.Arguments = append(svcConfig.Arguments, "-debug=false")
- prg := &npc{
- exit: make(chan struct{}),
- }
- s, err := service.New(prg, svcConfig)
- if err != nil {
- logs.Error(err)
- return
- }
- if len(os.Args) >= 2 {
- switch os.Args[1] {
- case "status":
- if len(os.Args) > 2 {
- path := strings.Replace(os.Args[2], "-config=", "", -1)
- client.GetTaskStatus(path)
- }
- case "register":
- flag.CommandLine.Parse(os.Args[2:])
- client.RegisterLocalIp(*serverAddr, *verifyKey, *connType, *proxyUrl, *registerTime)
- case "update":
- install.UpdateNpc()
- return
- case "nat":
- nat, host, err := stun.NewClient().Discover()
- if err != nil || host == nil {
- logs.Error("get nat type error", err)
- return
- }
- fmt.Printf("nat type: %s \npublic address: %s\n", nat.String(), host.String())
- os.Exit(0)
- case "install", "start", "stop", "uninstall", "restart":
- if os.Args[1] == "install" {
- install.InstallNpc()
- }
- err := service.Control(s, os.Args[1])
- if err != nil {
- logs.Error("Valid actions: %q\n", service.ControlAction, err.Error())
- }
- return
- }
- }
- s.Run()
- }
- type npc struct {
- exit chan struct{}
- }
- func (p *npc) Start(s service.Service) error {
- go p.run()
- return nil
- }
- func (p *npc) Stop(s service.Service) error {
- close(p.exit)
- if service.Interactive() {
- os.Exit(0)
- }
- return nil
- }
- func (p *npc) run() error {
- defer func() {
- if err := recover(); err != nil {
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
- logs.Warning("npc: panic serving %v: %v\n%s", err, string(buf))
- }
- }()
- //p2p or secret command
- if *password != "" {
- commonConfig := new(config.CommonConfig)
- commonConfig.Server = *serverAddr
- commonConfig.VKey = *verifyKey
- commonConfig.Tp = *connType
- localServer := new(config.LocalServer)
- localServer.Type = *localType
- localServer.Password = *password
- localServer.Target = *target
- localServer.Port = *localPort
- commonConfig.Client = new(file.Client)
- commonConfig.Client.Cnf = new(file.Config)
- go client.StartLocalServer(localServer, commonConfig)
- return nil
- }
- env := common.GetEnvMap()
- if *serverAddr == "" {
- *serverAddr, _ = env["NPC_SERVER_ADDR"]
- }
- if *verifyKey == "" {
- *verifyKey, _ = env["NPC_SERVER_VKEY"]
- }
- logs.Info("the version of client is %s, the core version of client is %s", version.VERSION, version.GetVersion())
- if *verifyKey != "" && *serverAddr != "" && *configPath == "" {
- go func() {
- for {
- client.NewRPClient(*serverAddr, *verifyKey, *connType, *proxyUrl, nil).Start()
- logs.Info("It will be reconnected in five seconds")
- time.Sleep(time.Second * 5)
- }
- }()
- } else {
- if *configPath == "" {
- *configPath = "conf/npc.conf"
- }
- go client.StartFromFile(*configPath)
- }
- select {
- case <-p.exit:
- logs.Warning("stop...")
- }
- return nil
- }
|