Skip to content

Commit

Permalink
Merge pull request #22 from wrfly/develop
Browse files Browse the repository at this point in the history
audit and share tty
  • Loading branch information
wrfly authored Oct 27, 2018
2 parents 5f64d3a + 8a3a45f commit cfaae51
Show file tree
Hide file tree
Showing 21 changed files with 519 additions and 175 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ vendor/
# from gotty
static
js/node_modules/*

# log file
log/
29 changes: 8 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ proto:

## --- these stages are copied from gotty for asset building --- ##
.PHONY: asset
asset: clear static/js/gotty-bundle.js static/index.html static/favicon.png static/css/index.css static/css/xterm.css static/css/xterm_customize.css
asset: clear static/js static/css static/html
go-bindata -nometadata -prefix static -pkg route -ignore=\\.gitkeep -o route/asset.go static/...
gofmt -w route/asset.go

Expand All @@ -84,38 +84,25 @@ clear:
static:
mkdir -p static

static/index.html: static resources/index.html resources/list.html
cp resources/index.html static/index.html
cp resources/list.html static/list.html

static/favicon.png: static resources/favicon.png
static/html: static
cp resources/*.html static/
cp resources/favicon.png static/favicon.png

static/js: static
static/js: static js/dist/gotty-bundle.js
mkdir -p static/js

static/js/gotty-bundle.js: static/js js/dist/gotty-bundle.js
cp resources/*.js static/js/
cp js/dist/gotty-bundle.js static/js/gotty-bundle.js
cp resources/control.js static/js/control.js

static/css: static
static/css: static js/node_modules/xterm/dist/xterm.css
mkdir -p static/css

static/css/index.css: static/css resources/index.css resources/list.css
cp resources/index.css static/css/index.css
cp resources/list.css static/css/list.css

static/css/xterm_customize.css: static/css resources/xterm_customize.css
cp resources/xterm_customize.css static/css/xterm_customize.css

static/css/xterm.css: static/css js/node_modules/xterm/dist/xterm.css
cp resources/*.css static/css
cp js/node_modules/xterm/dist/xterm.css static/css/xterm.css

js/node_modules/xterm/dist/xterm.css:
cd js && \
npm install

js/dist/gotty-bundle.js: js/src/* js/node_modules/webpack
js/dist/gotty-bundle.js: js/node_modules/webpack
cd js && \
`npm bin`/webpack

Expand Down
3 changes: 2 additions & 1 deletion README.ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ docker run --rm -ti --name web-tty \
- [x] 代理模式 (本地连接到远程机器上的容器)
- [x] 认证(仅限代理模式)
- [x] 超时自动断开
- [ ] 历史记录审计
- [x] 历史记录审计
- [x] 实时共享输入输出
- [x] 容器日志
- [x] 自定义执行命令

Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,38 @@ Now you will see all the containers of all the servers via *<http://localhost:80
- [x] proxy mode (client -> server's containers)
- [x] auth(only in proxy mode)
- [x] TTY timeout (idle timeout)
- [ ] history audit
- [x] history audit (just `cat` the history logs after enable this feature)
- [x] real time sharing (like screen sharing)
- [x] container logs (just click the container name)
- [x] exec arguments (append an extra "?cmd=xxx" argument to exec URL)

### Audit exec history and container outputs

```bash
docker run --rm -ti --name web-tty \
-p 8080:8080 \
-e WEB_TTY_AUDIT=true \
-v `pwd`/container-logs:/log \
-v /var/run/docker.sock:/var/run/docker.sock \
wrfly/container-web-tty
```

After you exec some commands, you will see the inputs and outputs under the
`container-logs` directory, you can use `cat` or `tail -f` to see the changes.

### Real-time sharing

```bash
docker run --rm -ti --name web-tty \
-p 8080:8080 \
-e WEB_TTY_SHARE=true \
-v /var/run/docker.sock:/var/run/docker.sock \
wrfly/container-web-tty
```

By enabling this feature, you can share the container's inputs and outputs
with others via the share link (click the container's image to get the link).

## Show-off

List the containers on your machine:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.7
0.1.8
69 changes: 69 additions & 0 deletions audit/audit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package audit

import (
"context"
"fmt"
"io"
"os"
"path"
"strings"
"time"

"github.com/sirupsen/logrus"
)

type LogOpts struct {
Dir, ContainerID, ClientIP string
}

func LogTo(ctx context.Context, r io.Reader, opts LogOpts) {
logDir := opts.Dir
if !strings.HasPrefix(logDir, "/") {
pwd, err := os.Getwd()
if err != nil {
logrus.Errorf("audit get pwd error: %s", err)
return
}
logDir = path.Join(pwd, logDir)
}

logDir = path.Join(logDir, opts.ContainerID[:12])
_, err := os.Stat(logDir)
if os.IsNotExist(err) {
logrus.Debugf("create dir %s", logDir)
if err := os.MkdirAll(logDir, 0755); err != nil {
logrus.Errorf("mkdir error: %s", err)
return
}
}
fPath := path.Join(logDir, fmt.Sprintf("%s-%d.log",
strings.Split(opts.ClientIP, ":")[0], time.Now().Unix()),
)

f, err := os.Create(fPath)
if err != nil {
logrus.Errorf("audit create file [%s] error: %s", fPath, err)
return
}
defer f.Close()

buff := make([]byte, 2048)
var start int64
for ctx.Err() == nil {
n, err := r.Read(buff)
if err != nil {
if err == io.EOF {
return
}
logrus.Errorf("audit read container error: %s", err)
return
}

_, err = f.WriteAt(buff[:n], start)
if err != nil {
logrus.Errorf("audit write file error: %s", err)
return
}
start += int64(n)
}
}
21 changes: 20 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,29 @@ type ControlConfig struct {
}

type ServerConfig struct {
Addr string
Address string
Port int
GrpcPort int
IdleTime time.Duration

Credential string
EnableReconnect bool
ReconnectTime int
MaxConnection int
WSOrigin string
Term string `default:"xterm"`
ShowLocation bool
EnableShare bool

// audit
EnableAudit bool
AuditLogDir string `default:"log"`

Control ControlConfig

// EnableBasicAuth bool `default:"false"`
// Once bool `default:"false"`
// TitleVariables map[string]interface{}
}

type Config struct {
Expand Down
1 change: 1 addition & 0 deletions container/grpc/grpc_tty.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (enj *execWrapper) ResizeTerminal(width int, height int) (err error) {
}
return
}

func (enj *execWrapper) resize(width int, height int) error {
return enj.exec.Send(&pb.ExecOptions{
Ws: &pb.WindowSize{
Expand Down
58 changes: 40 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@ import (
"gopkg.in/urfave/cli.v2"

"github.com/wrfly/container-web-tty/config"
"github.com/wrfly/container-web-tty/util"
)

func main() {
conf := config.New()
appFlags := []cli.Flag{
&cli.StringFlag{
Name: "addr",
EnvVars: envVars("address"),
EnvVars: util.EnvVars("address"),
Usage: "server binding address",
Value: "0.0.0.0",
Destination: &conf.Server.Addr,
Destination: &conf.Server.Address,
},
&cli.IntFlag{
Name: "port",
Aliases: []string{"p"},
EnvVars: envVars("port"),
EnvVars: util.EnvVars("port"),
Usage: "HTTP server port, -1 for disable the HTTP server",
Value: 8080,
Destination: &conf.Server.Port,
Expand All @@ -36,95 +37,116 @@ func main() {
Name: "debug",
Aliases: []string{"d"},
Value: false,
EnvVars: envVars("debug"),
EnvVars: util.EnvVars("debug"),
Usage: "debug mode (log-level=debug enable pprof)",
Destination: &conf.Debug,
},
&cli.StringFlag{
Name: "backend",
Aliases: []string{"b"},
EnvVars: envVars("backend"),
EnvVars: util.EnvVars("backend"),
Value: "docker",
Usage: "backend type, 'docker' or 'kube' or 'grpc'(remote)",
Destination: &conf.Backend.Type,
},
&cli.StringFlag{
Name: "docker-host",
EnvVars: append(envVars("docker-host"), "DOCKER_HOST"),
EnvVars: append(util.EnvVars("docker-host"), "DOCKER_HOST"),
Value: "/var/run/docker.sock",
Usage: "docker host path",
Destination: &conf.Backend.Docker.DockerHost,
},
&cli.StringFlag{
Name: "docker-ps",
EnvVars: envVars("docker-ps"),
EnvVars: util.EnvVars("docker-ps"),
Usage: "docker ps options",
Destination: &conf.Backend.Docker.PsOptions,
},
&cli.StringFlag{
Name: "kube-config",
EnvVars: envVars("kube-config"),
Value: kubeConfigPath(),
EnvVars: util.EnvVars("kube-config"),
Value: util.KubeConfigPath(),
Usage: "kube config path",
Destination: &conf.Backend.Kube.ConfigPath,
},
&cli.StringFlag{
Name: "extra-args",
EnvVars: envVars("extra-args"),
EnvVars: util.EnvVars("extra-args"),
Usage: "pass extra args to the backend",
},
&cli.IntFlag{
Name: "grpc-port",
EnvVars: envVars("grpc-port"),
EnvVars: util.EnvVars("grpc-port"),
Usage: "grpc server port, -1 for disable the grpc server",
Value: -1,
Destination: &conf.Server.GrpcPort,
},
&cli.StringFlag{
Name: "grpc-servers",
EnvVars: envVars("grpc-servers"),
EnvVars: util.EnvVars("grpc-servers"),
Usage: "upstream servers, for proxy mode(grpc address and port), use comma for split",
},
&cli.StringFlag{
Name: "grpc-auth",
EnvVars: envVars("grpc-auth"),
EnvVars: util.EnvVars("grpc-auth"),
Usage: "grpc auth token",
Value: "password",
Destination: &conf.Backend.GRPC.Auth,
},
&cli.StringFlag{
Name: "idle-time",
EnvVars: envVars("idle-time"),
EnvVars: util.EnvVars("idle-time"),
Usage: "time out of an idle connection",
},
&cli.BoolFlag{
Name: "control-all",
Aliases: []string{"ctl-a"},
EnvVars: envVars("ctl-a"),
EnvVars: util.EnvVars("ctl-a"),
Usage: "enable container control",
Destination: &conf.Control.All,
},
&cli.BoolFlag{
Name: "control-start",
Aliases: []string{"ctl-s"},
EnvVars: envVars("ctl-s"),
EnvVars: util.EnvVars("ctl-s"),
Usage: "enable container start ",
Destination: &conf.Control.Start,
},
&cli.BoolFlag{
Name: "control-stop",
Aliases: []string{"ctl-t"},
EnvVars: envVars("ctl-t"),
EnvVars: util.EnvVars("ctl-t"),
Usage: "enable container stop ",
Destination: &conf.Control.Stop,
},
&cli.BoolFlag{
Name: "control-restart",
Aliases: []string{"ctl-r"},
EnvVars: envVars("ctl-r"),
EnvVars: util.EnvVars("ctl-r"),
Usage: "enable container restart",
Destination: &conf.Control.Restart,
},
&cli.BoolFlag{
Name: "enable-share",
Aliases: []string{"share"},
EnvVars: util.EnvVars("share"),
Usage: "enable share the container's terminal",
Destination: &conf.Server.EnableShare,
},
&cli.BoolFlag{
Name: "enable-audit",
Aliases: []string{"audit"},
EnvVars: util.EnvVars("audit"),
Usage: "enable audit the container outputs",
Destination: &conf.Server.EnableAudit,
},
&cli.StringFlag{
Name: "audit-dir",
EnvVars: util.EnvVars("audit-dir"),
Value: "log",
Usage: "container audit log dir path",
Destination: &conf.Server.AuditLogDir,
},
&cli.BoolFlag{
Name: "help",
Aliases: []string{"h"},
Expand Down
Loading

0 comments on commit cfaae51

Please sign in to comment.