diff --git a/bridge/bridge.go b/bridge/bridge.go index eab8ebe..6b58ed4 100755 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -200,20 +200,28 @@ func (s *Bridge) cliProcess(c *conn.Conn) { func (s *Bridge) DelClient(id int) { if v, ok := s.Client.Load(id); ok { - if c, err := file.GetCsvDb().GetClient(id); err == nil && c.NoStore { - s.CloseClient <- c.Id - } if v.(*Client).signal != nil { v.(*Client).signal.Close() } s.Client.Delete(id) + if file.GetCsvDb().IsPubClient(id) { + return + } + if c, err := file.GetCsvDb().GetClient(id); err == nil && c.NoStore { + s.CloseClient <- c.Id + } } } //use different func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) { + isPub := file.GetCsvDb().IsPubClient(id) switch typeVal { case common.WORK_MAIN: + if isPub { + c.Close() + return + } //the vKey connect by another ,close the client of before if v, ok := s.Client.LoadOrStore(id, NewClient(nil, nil, c)); ok { if v.(*Client).signal != nil { @@ -229,16 +237,8 @@ func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) { v.(*Client).tunnel = muxConn } case common.WORK_CONFIG: - var isPub bool client, err := file.GetCsvDb().GetClient(id) - if err == nil { - if client.VerifyKey == beego.AppConfig.String("public_vkey") { - isPub = true - } else { - isPub = false - } - } - if !isPub && !client.ConfigConnAllow { + if err != nil || (!isPub && !client.ConfigConnAllow) { c.Close() return } @@ -458,6 +458,7 @@ loop: tl := new(file.Tunnel) tl.Mode = t.Mode tl.Port = ports[i] + tl.ServerIp = t.ServerIp if len(ports) == 1 { tl.Target = t.Target tl.Remark = t.Remark diff --git a/client/client.go b/client/client.go index 266644f..a345d07 100755 --- a/client/client.go +++ b/client/client.go @@ -228,7 +228,13 @@ loop: } func (s *TRPClient) Close() { - s.tunnel.Close() - s.signal.Close() - s.ticker.Stop() + if s.tunnel != nil { + s.tunnel.Close() + } + if s.signal != nil { + s.signal.Close() + } + if s.ticker != nil { + s.ticker.Stop() + } } diff --git a/conf/npc.conf b/conf/npc.conf index 888e53e..1862402 100644 --- a/conf/npc.conf +++ b/conf/npc.conf @@ -1,7 +1,7 @@ [common] -server=127.0.0.1:8024 -tp=tcp -vkey=123 +server_addr=127.0.0.1:8024 +conn_type=tcp +vkey=nps auto_reconnection=true [health_check_test1] @@ -20,39 +20,38 @@ health_check_type=tcp health_check_target=127.0.0.1:8083,127.0.0.1:8082 [web] host=b.o.com -target=127.0.0.1:8080 +target_addr=127.0.0.1:8080 [tcp] mode=tcp -target=127.0.0.1:8083,127.0.0.1:8082 -port=9006 -targetAddr=123.206.77.88 +target=127.0.0.1:8080 +server_port=10000 [socks5] mode=socks5 -port=9005 +server_port=9005 [http] mode=httpProxy -port=9004 +server_port=9004 [file] mode=file -port=9009 +server_port=9009 local_path=./ strip_pre=/web/ [udp] mode=udp -port=53 -target=114.114.114.114:53 +server_port=53 +target_addr=114.114.114.114:53 [secret_ssh] -port=2001 +local_port=2001 password=sec [p2p_ssh] -port=2002 -password=c -target=123.206.77.88:22 \ No newline at end of file +local_port=2002 +password=ppp +target_addr=192.168.74.199:22 \ No newline at end of file diff --git a/conf/nps.conf b/conf/nps.conf index deb32f7..6ff9258 100755 --- a/conf/nps.conf +++ b/conf/nps.conf @@ -6,6 +6,7 @@ runmode = pro http_proxy_port=80 https_proxy_port=443 https_just_proxy=true +http_proxy_ip=0.0.0.0 #certFile absolute path #pem_path=conf/server.pem #KeyFile absolute path diff --git a/conf/tasks.csv b/conf/tasks.csv index 82c2806..b2cc28f 100644 --- a/conf/tasks.csv +++ b/conf/tasks.csv @@ -1 +1 @@ -9988,tcp,127.0.0.1:8080,1,3,11,,0,504, +9999,tcp,,1,3,11,,0,0,,0.0.0.0 diff --git a/lib/config/config.go b/lib/config/config.go index e52df58..15b1227 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -20,6 +20,7 @@ type CommonConfig struct { type LocalServer struct { Type string Port int + Ip string Password string Target string } @@ -112,11 +113,11 @@ func dealCommon(s string) *CommonConfig { item = append(item, "") } switch item[0] { - case "server": + case "server_addr": c.Server = item[1] case "vkey": c.VKey = item[1] - case "tp": + case "conn_type": c.Tp = item[1] case "auto_reconnection": c.AutoReconnection = common.GetBoolByStr(item[1]) @@ -156,7 +157,7 @@ func dealHost(s string) *file.Host { switch strings.TrimSpace(item[0]) { case "host": h.Host = item[1] - case "target": + case "target_addr": h.Target = strings.Replace(item[1], ",", "\n", -1) case "host_change": h.HostChange = item[1] @@ -211,13 +212,15 @@ func dealTunnel(s string) *file.Tunnel { item = append(item, "") } switch strings.TrimSpace(item[0]) { - case "port": + case "server_port": t.Ports = item[1] + case "server_ip": + t.ServerIp = item[1] case "mode": t.Mode = item[1] - case "target": + case "target_port", "target_addr": t.Target = strings.Replace(item[1], ",", "\n", -1) - case "targetAddr": + case "target_ip": t.TargetAddr = item[1] case "password": t.Password = item[1] @@ -241,11 +244,13 @@ func delLocalService(s string) *LocalServer { item = append(item, "") } switch item[0] { - case "port": + case "local_port": l.Port = common.GetIntNoErrByStr(item[1]) + case "local_ip": + l.Ip = item[1] case "password": l.Password = item[1] - case "target": + case "target_addr": l.Target = item[1] } } diff --git a/lib/conn/conn.go b/lib/conn/conn.go index 3b8cdf1..0718df7 100755 --- a/lib/conn/conn.go +++ b/lib/conn/conn.go @@ -316,7 +316,7 @@ func (s *Conn) SendTaskInfo(t *file.Tunnel) (int, error) { */ raw := bytes.NewBuffer([]byte{}) binary.Write(raw, binary.LittleEndian, []byte(common.NEW_TASK)) - common.BinaryWrite(raw, t.Mode, t.Ports, t.Target, t.Remark, t.TargetAddr, t.Password, t.LocalPath, t.StripPre) + common.BinaryWrite(raw, t.Mode, t.Ports, t.Target, t.Remark, t.TargetAddr, t.Password, t.LocalPath, t.StripPre, t.ServerIp) s.Lock() defer s.Unlock() return s.Write(raw.Bytes()) @@ -345,6 +345,9 @@ func (s *Conn) GetTaskInfo() (t *file.Tunnel, err error) { t.Password = arr[5] t.LocalPath = arr[6] t.StripPre = arr[7] + if len(arr) > 8 { + t.ServerIp = arr[8] + } t.NoStore = true } return diff --git a/lib/file/file.go b/lib/file/file.go index ddf8ddf..967fae3 100644 --- a/lib/file/file.go +++ b/lib/file/file.go @@ -7,6 +7,7 @@ import ( "github.com/cnlh/nps/lib/common" "github.com/cnlh/nps/lib/crypt" "github.com/cnlh/nps/lib/rate" + "github.com/cnlh/nps/vender/github.com/astaxie/beego" "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs" "net/http" "os" @@ -59,6 +60,7 @@ func (s *Csv) StoreTasksToCsv() { strconv.Itoa(int(task.Flow.ExportFlow)), strconv.Itoa(int(task.Flow.InletFlow)), task.Password, + task.ServerIp, } err := writer.Write(record) if err != nil { @@ -111,6 +113,11 @@ func (s *Csv) LoadTaskFromCsv() { if post.Client, err = s.GetClient(common.GetIntNoErrByStr(item[5])); err != nil { continue } + if len(item) > 10 { + post.ServerIp = item[10] + } else { + post.ServerIp = "0.0.0.0" + } s.Tasks.Store(post.Id, post) if post.Id > int(s.TaskIncreaseId) { s.TaskIncreaseId = int32(s.TaskIncreaseId) @@ -440,7 +447,7 @@ func (s *Csv) UpdateClient(t *Client) error { return nil } -func (s *Csv) GetClientList(start, length int, search string) ([]*Client, int) { +func (s *Csv) GetClientList(start, length int, search string, clientId int) ([]*Client, int) { list := make([]*Client, 0) var cnt int keys := common.GetMapKeys(s.Clients) @@ -450,6 +457,9 @@ func (s *Csv) GetClientList(start, length int, search string) ([]*Client, int) { if v.NoDisplay { continue } + if clientId != 0 && clientId != v.Id { + continue + } if search != "" && !(v.Id == common.GetIntNoErrByStr(search) || strings.Contains(v.VerifyKey, search) || strings.Contains(v.Remark, search)) { continue } @@ -464,6 +474,18 @@ func (s *Csv) GetClientList(start, length int, search string) ([]*Client, int) { return list, cnt } +func (s *Csv) IsPubClient(id int) bool { + client, err := s.GetClient(id) + if err == nil { + if client.VerifyKey == beego.AppConfig.String("public_vkey") { + return true + } else { + return false + } + } + return false +} + func (s *Csv) GetClient(id int) (c *Client, err error) { if v, ok := s.Clients.Load(id); ok { c = v.(*Client) diff --git a/lib/file/obj.go b/lib/file/obj.go index 934c3d1..4d4ce48 100644 --- a/lib/file/obj.go +++ b/lib/file/obj.go @@ -111,8 +111,9 @@ func (s *Client) HasHost(h *Host) bool { } type Tunnel struct { - Id int //Id - Port int //服务端监听端口 + Id int //Id + Port int //服务端监听端口 + ServerIp string Mode string //启动方式 Target string //目标 TargetArr []string //目标 diff --git a/lib/version/version.go b/lib/version/version.go index 3d73442..71e9e51 100644 --- a/lib/version/version.go +++ b/lib/version/version.go @@ -1,6 +1,6 @@ package version -const VERSION = "0.20.0" +const VERSION = "0.20.1" // Compulsory minimum version, Minimum downward compatibility to this version func GetVersion() string { diff --git a/server/connection/connection.go b/server/connection/connection.go index a0f223e..9806869 100644 --- a/server/connection/connection.go +++ b/server/connection/connection.go @@ -50,7 +50,7 @@ func GetHttpListener() (net.Listener, error) { return pMux.GetHttpListener(), nil } logs.Info("start http listener, port is", httpPort) - return getTcpListener("", httpPort) + return getTcpListener(beego.AppConfig.String("http_proxy_ip"), httpPort) } func GetHttpsListener() (net.Listener, error) { @@ -59,7 +59,7 @@ func GetHttpsListener() (net.Listener, error) { return pMux.GetHttpsListener(), nil } logs.Info("start https listener, port is", httpsPort) - return getTcpListener("", httpsPort) + return getTcpListener(beego.AppConfig.String("http_proxy_ip"), httpsPort) } func GetWebManagerListener() (net.Listener, error) { diff --git a/server/proxy/socks5.go b/server/proxy/socks5.go index 2ad634f..cf4f362 100755 --- a/server/proxy/socks5.go +++ b/server/proxy/socks5.go @@ -251,7 +251,7 @@ func (s *Sock5ModeServer) Auth(c net.Conn) error { //start func (s *Sock5ModeServer) Start() error { - return conn.NewTcpListenerAndProcess(":"+strconv.Itoa(s.task.Port), func(c net.Conn) { + return conn.NewTcpListenerAndProcess(s.task.ServerIp+":"+strconv.Itoa(s.task.Port), func(c net.Conn) { if err := s.CheckFlowAndConnNum(s.task.Client); err != nil { logs.Warn("client id %d, task id %d, error %s, when socks5 connection", s.task.Client.Id, s.task.Id, err.Error()) c.Close() diff --git a/server/proxy/tcp.go b/server/proxy/tcp.go index b6e55cf..b5e8c65 100755 --- a/server/proxy/tcp.go +++ b/server/proxy/tcp.go @@ -32,7 +32,7 @@ func NewTunnelModeServer(process process, bridge *bridge.Bridge, task *file.Tunn //开始 func (s *TunnelModeServer) Start() error { - return conn.NewTcpListenerAndProcess(":"+strconv.Itoa(s.task.Port), func(c net.Conn) { + return conn.NewTcpListenerAndProcess(s.task.ServerIp+":"+strconv.Itoa(s.task.Port), func(c net.Conn) { if err := s.CheckFlowAndConnNum(s.task.Client); err != nil { logs.Warn("client id %d, task id %d,error %s, when tcp connection", s.task.Client.Id, s.task.Id, err.Error()) c.Close() diff --git a/server/proxy/udp.go b/server/proxy/udp.go index d7a3372..885af5a 100755 --- a/server/proxy/udp.go +++ b/server/proxy/udp.go @@ -26,7 +26,10 @@ func NewUdpModeServer(bridge *bridge.Bridge, task *file.Tunnel) *UdpModeServer { //开始 func (s *UdpModeServer) Start() error { var err error - s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.task.Port, ""}) + if s.task.ServerIp == "" { + s.task.ServerIp = "0.0.0.0" + } + s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP(s.task.ServerIp), s.task.Port, ""}) if err != nil { return err } diff --git a/server/server.go b/server/server.go index 60ecec2..b6d8d03 100644 --- a/server/server.go +++ b/server/server.go @@ -255,8 +255,8 @@ func GetTunnel(start, length int, typeVal string, clientId int, search string) ( } //获取客户端列表 -func GetClientList(start, length int, search string) (list []*file.Client, cnt int) { - list, cnt = file.GetCsvDb().GetClientList(start, length, search) +func GetClientList(start, length int, search string, clientId int) (list []*file.Client, cnt int) { + list, cnt = file.GetCsvDb().GetClientList(start, length, search, clientId) dealClientData() return } diff --git a/web/controllers/base.go b/web/controllers/base.go index c4703d2..db35e1e 100755 --- a/web/controllers/base.go +++ b/web/controllers/base.go @@ -140,7 +140,16 @@ func (s *BaseController) SetType(name string) { func (s *BaseController) CheckUserAuth() { if s.controllerName == "client" { - s.StopRun() + if s.actionName == "add" { + s.StopRun() + return + } + if id := s.GetIntNoErr("id"); id != 0 { + if id != s.GetSession("clientId").(int) { + s.StopRun() + return + } + } } if s.controllerName == "index" { if id := s.GetIntNoErr("id"); id != 0 { diff --git a/web/controllers/client.go b/web/controllers/client.go index d234688..f46b494 100644 --- a/web/controllers/client.go +++ b/web/controllers/client.go @@ -19,7 +19,14 @@ func (s *ClientController) List() { return } start, length := s.GetAjaxParams() - list, cnt := server.GetClientList(start, length, s.GetString("search")) + clientIdSession := s.GetSession("clientId") + var clientId int + if clientIdSession == nil { + clientId = 0 + } else { + clientId = clientIdSession.(int) + } + list, cnt := server.GetClientList(start, length, s.GetString("search"), clientId) s.AjaxTable(list, cnt, cnt) } diff --git a/web/controllers/index.go b/web/controllers/index.go index 896e26e..85307c3 100755 --- a/web/controllers/index.go +++ b/web/controllers/index.go @@ -91,6 +91,7 @@ func (s *IndexController) Add() { } else { t := &file.Tunnel{ Port: s.GetIntNoErr("port"), + ServerIp: s.GetString("server_ip"), Mode: s.GetString("type"), Target: s.GetString("target"), Id: int(file.GetCsvDb().GetTaskId()), @@ -144,7 +145,12 @@ func (s *IndexController) Edit() { if t, err := file.GetCsvDb().GetTask(id); err != nil { s.error() } else { - t.Port = s.GetIntNoErr("port") + var portChange bool + if s.GetIntNoErr("port") != t.Port { + portChange = true + t.Port = s.GetIntNoErr("port") + } + t.ServerIp = s.GetString("server_ip") t.Mode = s.GetString("type") t.Target = s.GetString("target") t.Password = s.GetString("password") @@ -152,7 +158,7 @@ func (s *IndexController) Edit() { t.LocalPath = s.GetString("local_path") t.StripPre = s.GetString("strip_pre") t.Remark = s.GetString("remark") - if !tool.TestServerPort(t.Port, t.Mode) { + if portChange && !tool.TestServerPort(t.Port, t.Mode) { s.AjaxErr("The port cannot be opened because it may has been occupied or is no longer allowed.") } if t.Client, err = file.GetCsvDb().GetClient(s.GetIntNoErr("client_id")); err != nil { diff --git a/web/views/client/list.html b/web/views/client/list.html index 6019d1c..913d432 100755 --- a/web/views/client/list.html +++ b/web/views/client/list.html @@ -15,15 +15,18 @@ -