diff --git a/README.md b/README.md
index 38ea871..1353616 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
LOGO designed by 熊大 .
-
+
:trollface: Nezha Monitoring: Self-hosted, lightweight server and website monitoring and O&M tool.
diff --git a/cmd/agent/main.go b/cmd/agent/main.go index d6bacd6..a8ee913 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -465,6 +465,7 @@ func handleTerminalTask(task *pb.Task) { read, err := tty.Read(buf) if err != nil { conn.WriteMessage(websocket.TextMessage, []byte(err.Error())) + conn.Close() return } conn.WriteMessage(websocket.BinaryMessage, buf[:read]) diff --git a/cmd/agent/pty/pty.go b/cmd/agent/pty/pty.go index c9841fc..845a634 100644 --- a/cmd/agent/pty/pty.go +++ b/cmd/agent/pty/pty.go @@ -61,7 +61,7 @@ func (pty *Pty) killChildProcess(c *exec.Cmd) error { c.Process.Kill() } // Kill the whole process group. - syscall.Kill(-pgid, syscall.SIGTERM) + syscall.Kill(-pgid, syscall.SIGKILL) // SIGKILL 直接杀掉 SIGTERM 发送信号,等待进程自己退出 return c.Wait() } diff --git a/cmd/dashboard/controller/common_page.go b/cmd/dashboard/controller/common_page.go index 123d4ab..9f2d6c9 100644 --- a/cmd/dashboard/controller/common_page.go +++ b/cmd/dashboard/controller/common_page.go @@ -20,13 +20,14 @@ import ( "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" "github.com/naiba/nezha/pkg/utils" + "github.com/naiba/nezha/pkg/websocketx" "github.com/naiba/nezha/proto" "github.com/naiba/nezha/service/singleton" ) type terminalContext struct { - agentConn *websocket.Conn - userConn *websocket.Conn + agentConn *websocketx.Conn + userConn *websocketx.Conn serverID uint64 host string useSSL bool @@ -294,7 +295,7 @@ func (cp *commonPage) terminal(c *gin.Context) { return } cloudflareCookies, _ := c.Cookie("CF_Authorization") - // CloudflareCookies合法性验证 + // Cloudflare Cookies 合法性验证 // 其应该包含.分隔的三组BASE64-URL编码 if cloudflareCookies != "" { encodedCookies := strings.Split(cloudflareCookies, ".") @@ -330,7 +331,7 @@ func (cp *commonPage) terminal(c *gin.Context) { } } - conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) + wsConn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ Code: http.StatusInternalServerError, @@ -343,7 +344,8 @@ func (cp *commonPage) terminal(c *gin.Context) { }, true) return } - defer conn.Close() + defer wsConn.Close() + conn := &websocketx.Conn{Conn: wsConn} log.Printf("NEZHA>> terminal connected %t %q", isAgent, c.Request.URL) defer log.Printf("NEZHA>> terminal disconnected %t %q", isAgent, c.Request.URL) @@ -402,7 +404,7 @@ func (cp *commonPage) terminal(c *gin.Context) { }() var dataBuffer [][]byte - var distConn *websocket.Conn + var distConn *websocketx.Conn checkDistConn := func() { if distConn == nil { if isAgent { diff --git a/go.mod b/go.mod index e3c0499..f312b76 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,8 @@ require ( github.com/ory/graceful v0.1.3 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/robfig/cron/v3 v3.0.1 - github.com/shirou/gopsutil/v3 v3.22.9 + github.com/samber/lo v1.33.0 + github.com/shirou/gopsutil/v3 v3.22.10 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.13.0 github.com/stretchr/testify v1.8.1 @@ -87,6 +88,7 @@ require ( github.com/ugorji/go/codec v1.2.7 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/net v0.1.0 // indirect golang.org/x/sys v0.1.0 // indirect golang.org/x/term v0.1.0 // indirect diff --git a/go.sum b/go.sum index f0a8d71..e64bb56 100644 --- a/go.sum +++ b/go.sum @@ -296,8 +296,10 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= -github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= +github.com/samber/lo v1.33.0 h1:2aKucr+rQV6gHpY3bpeZu69uYoQOzVhGT3J22Op6Cjk= +github.com/samber/lo v1.33.0/go.mod h1:HLeWcJRRyLKp3+/XBJvOrerCQn9mhdKMHyd7IRlgeQ8= +github.com/shirou/gopsutil/v3 v3.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg= +github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= @@ -325,6 +327,7 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw= github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE= +github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= @@ -370,6 +373,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/pkg/websocketx/safe_conn.go b/pkg/websocketx/safe_conn.go new file mode 100644 index 0000000..f442c12 --- /dev/null +++ b/pkg/websocketx/safe_conn.go @@ -0,0 +1,25 @@ +package websocketx + +import ( + "sync" + + "github.com/gorilla/websocket" + "github.com/samber/lo" +) + +type Conn struct { + *websocket.Conn + writeLock sync.Mutex +} + +func (conn *Conn) WriteMessage(msgType int, data []byte) error { + conn.writeLock.Lock() + defer conn.writeLock.Unlock() + var err error + lo.TryCatchWithErrorValue(func() error { + return conn.Conn.WriteMessage(msgType, data) + }, func(res any) { + err = res.(error) + }) + return err +} diff --git a/service/singleton/singleton.go b/service/singleton/singleton.go index e43acc4..cd1956a 100644 --- a/service/singleton/singleton.go +++ b/service/singleton/singleton.go @@ -12,7 +12,7 @@ import ( "github.com/naiba/nezha/pkg/utils" ) -var Version = "v0.14.6" // !!记得修改 README 中的 badge 版本!! +var Version = "v0.14.7" // !!记得修改 README 中的 badge 版本!! var ( Conf *model.Config