diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..2ef5d5f --- /dev/null +++ b/.drone.yml @@ -0,0 +1,20 @@ +kind: pipeline +name: default +steps: +- name: build + image: golang:1.17.2 + commands: + - git tag $DRONE_TAG + - bash make.sh + - echo -n "latest,${DRONE_TAG#v}" > .tags +- name: gitea_release + image: plugins/gitea-release + settings: + api_key: + from_secret: gitea_api_key + base_url: https://kumoly.io + files: dist/* + checksum: + - sha256 +trigger: + event: tag \ No newline at end of file diff --git a/.gitignore b/.gitignore index 94fc4f2..2610592 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.parcel-cache \ No newline at end of file +.parcel-cache +dist \ No newline at end of file diff --git a/README.md b/README.md index 3453f79..29aeb70 100644 --- a/README.md +++ b/README.md @@ -1 +1,28 @@ -# goshell \ No newline at end of file +# gterm + + +## Usage + +```shell +Usage: gterm [options] + -addr string + address to bind (default ":8000") + -allow string + restrict ip + -dev + is development mode + -log-level int + log level (default 9) + -name string + the application title (default "gterm") + -shell string + the shell behind (default "bash") + -v show version +``` + +## Install + +```shell +sudo rm -f /usr/local/bin/gterm +sudo sh -c "curl -fsSL RELEASE_URL | tar -C /usr/local/bin/ -xz" +``` \ No newline at end of file diff --git a/cmd/gterm/main.go b/cmd/gterm/main.go index b04b814..8a138a0 100644 --- a/cmd/gterm/main.go +++ b/cmd/gterm/main.go @@ -2,27 +2,78 @@ package main import ( "flag" + "fmt" + "net/http" + "os" + "kumoly.io/lib/klog" "kumoly.io/lib/ksrv" "kumoly.io/tools/gterm" ) +var Version = "0.0.0" +var Build = "alpha" + var ( - flagAppName string = "gterm" - flagAddr string - flagShell string + flagAllowIP string + flagAppName string = "gterm" + flagAddr string + flagShell string + flagLogLevel int + flagDev bool + flagVer bool ) func init() { + flag.StringVar(&flagAppName, "name", "gterm", "the application title") flag.StringVar(&flagAddr, "addr", ":8000", "address to bind") flag.StringVar(&flagShell, "shell", "bash", "the shell behind") + flag.BoolVar(&flagDev, "dev", false, "is development mode") + flag.IntVar(&flagLogLevel, "log-level", 9, "log level") + flag.StringVar(&flagAllowIP, "allow", "", "restrict ip") + flag.BoolVar(&flagVer, "v", false, "show version") + + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: gterm [options]\n") + flag.PrintDefaults() + } } func main() { flag.Parse() + if flagVer { + fmt.Printf("%v - %v\n", Version, Build) + return + } + + klog.LEVEL = klog.Llevel(flagLogLevel) + klog.PROD = !flagDev - server := ksrv.New() g := gterm.New() + g.AppName = flagAppName + g.Cmd = flagShell - server.Handle(g).Listen(flagAddr).Serve() + server := &http.Server{ + Addr: flagAddr, + Handler: Middleware(g), + } + server.ListenAndServe() +} + +func Middleware(next http.Handler) http.Handler { + log := klog.Sub(flagAppName) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if err := recover(); err != nil { + log.Error(err) + } + }() + if flagAllowIP != "" { + if !ksrv.MatchIPGlob(ksrv.GetIP(r), flagAllowIP) { + w.WriteHeader(http.StatusForbidden) + w.Write([]byte("permission denied")) + } + } + next.ServeHTTP(w, r) + }) } diff --git a/go.mod b/go.mod index ec12ecc..03cd0c3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.17 require ( github.com/creack/pty v1.1.17 github.com/gorilla/websocket v1.4.2 - github.com/rs/xid v1.3.0 kumoly.io/lib/klog v0.0.8 kumoly.io/lib/ksrv v0.0.2-0.20211112060911-0d61b343a298 ) diff --git a/go.sum b/go.sum index cbad9e5..78f97c1 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,6 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/gterm.go b/gterm.go index b8ea01d..07712ad 100644 --- a/gterm.go +++ b/gterm.go @@ -14,14 +14,13 @@ import ( "github.com/creack/pty" "github.com/gorilla/websocket" - "github.com/rs/xid" "kumoly.io/lib/klog" "kumoly.io/lib/ksrv" "kumoly.io/lib/ksrv/engine" "kumoly.io/tools/gterm/public" ) -//go:embed index.html +//go:embed public/index.html var index string var tmpl *engine.Engine @@ -68,10 +67,23 @@ func New() *GTerm { // if g.BufferSize == 0 { // g.BufferSize = 512 // } + go func() { + //print pool + log := klog.Sub("gterm") + for { + cons := []string{} + for k := range pool { + cons = append(cons, k) + } + log.Info("current connections: ", cons) + time.Sleep(5 * time.Minute) + } + + }() return >erm{ AppName: "GTERM", Cmd: "bash", - Envs: os.Environ(), + Envs: append(os.Environ(), "TERM=xterm-256color"), Timeout: 20 * time.Second, ErrorLimit: 10, BufferSize: 512, @@ -111,7 +123,7 @@ func (g *GTerm) App(w http.ResponseWriter, r *http.Request) { } func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) { - id := ksrv.GetIP(r) + " : " + xid.New().String() + id := fmt.Sprintf("[%02d] %s", ctr(), ksrv.GetIP(r)) pool[id] = make(chan struct{}, 1) defer func() { close(pool[id]) @@ -226,7 +238,7 @@ func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) { if !ok { dataType = "uunknown" } - l.Info(fmt.Sprintf("received %s (type: %v) message of size %v byte(s) from xterm.js with key sequence: %v", dataType, messageType, dataLength, dataBuffer)) + l.Debug(fmt.Sprintf("received %s (type: %v) message of size %v byte(s) from xterm.js with key sequence: %v", dataType, messageType, dataLength, dataBuffer)) // process if dataLength == -1 { // invalid @@ -243,7 +255,7 @@ func (g *GTerm) WS(w http.ResponseWriter, r *http.Request) { l.Warn(fmt.Sprintf("failed to unmarshal received resize message '%s': %s", string(resizeMessage), err)) continue } - l.InfoF(klog.H{"rows": ttySize.Rows, "columns": ttySize.Cols}, "resizing tty...") + l.DebugF(klog.H{"rows": ttySize.Rows, "columns": ttySize.Cols}, "resizing tty...") if err := pty.Setsize(tty, &pty.Winsize{ Rows: ttySize.Rows, Cols: ttySize.Cols, diff --git a/index.html b/index.html index 768a919..7b81359 100644 --- a/index.html +++ b/index.html @@ -41,7 +41,7 @@
- +