forked from drnic/tmate-bootstrap
/
tmate-bootstrap.go
134 lines (102 loc) · 2.94 KB
/
tmate-bootstrap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
import (
"github.com/danhigham/pty"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
"os/signal"
"os/exec"
"regexp"
"net"
"fmt"
)
func log_action(text string) {
os.Stdout.Write([]byte("-----> " + text + "\n"))
}
func main() {
log_action("Extracting payload...")
home := os.Getenv("HOME")
payload_target := fmt.Sprint(home, "/", "payload.tgz")
// write payload.tgz to $HOME
b, _ := Asset("payload/payload.tgz")
err := ioutil.WriteFile(payload_target, b, 0644)
if err != nil { panic(err) }
// decompress payload.tgz
unzip_cmd := exec.Command("tar", "xvzf", payload_target, "-C", home)
out, err := unzip_cmd.CombinedOutput()
os.Stdout.Write(out)
// exec child process
if len(os.Args) > 1 {
go func() {
log_action("Running child process")
child_bin, args := os.Args[1], os.Args[2:len(os.Args)]
child_cmd := exec.Command(child_bin, args...)
out, err = child_cmd.CombinedOutput()
os.Stdout.Write(out)
if err != nil {
os.Stdout.Write([]byte(err.Error()))
}
}()
}
// give tmate +x permissions
log_action("Fixing permissions")
tmate_bin := fmt.Sprint(home, "/", "bin", "/", "tmate")
exec_perm_cmd := exec.Command("chmod", "+x", tmate_bin)
out, _ = exec_perm_cmd.CombinedOutput()
os.Stdout.Write(out)
// add lib folder to LD_LIBRARY_PATH
log_action("Setting env")
lib_folder := fmt.Sprint(home, "/", "lib")
os.Setenv("LD_LIBRARY_PATH", os.Getenv("LD_LIBRARY_PATH") + ":" + lib_folder)
os.Setenv("TERM", "screen-256color")
// generate ssh keys
log_action("Generating SSH key")
ssh_key_cmd := exec.Command("ssh-keygen", "-q", "-t", "rsa", "-f", "/home/vcap/.ssh/id_rsa", "-N", "")
out, _ = ssh_key_cmd.CombinedOutput()
os.Stdout.Write(out)
// start tmate
log_action("Starting tmate...")
tmate_cmd := exec.Command(tmate_bin)
f, err := pty.Start(tmate_cmd)
if err != nil {
os.Stdout.Write([]byte(err.Error()))
}
pty.Setsize(f, 1000, 1000)
go func(r io.Reader) {
sessionRegex, _ := regexp.Compile(`Remote\ssession\:\sssh\s([^\.]+\.tmate.io)`)
for {
buf := make([]byte, 1024)
_, err := r.Read(buf[:])
if err != nil {
return
}
matches := sessionRegex.FindSubmatch(buf)
if len(matches) > 0 {
log.Print("=====> " + string(matches[1]))
// result := "=====> " + string(matches[1])
// os.Stdout.Write([]byte(result))
}
}
}(f)
// set up a reverse proxy
serverUrl, _ := url.Parse("http://127.0.0.1:8080")
reverseProxy := httputil.NewSingleHostReverseProxy(serverUrl)
http.Handle("/", reverseProxy)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
l, _ := net.Listen("tcp", ":" + os.Getenv("PORT"))
go func(){
for _ = range c {
// sig is a ^C, handle it
log.Print("Stopping tmate...")
l.Close()
f.Close()
}
}()
http.Serve(l, nil)
log.Print(err)
}