package main import ( "bytes" "fmt" "github.com/gliderlabs/ssh" "github.com/kr/pty" "io" "log" "net/http" "os/exec" ) var ( metrics_num_passwords int ) func main() { log.Println("Starting SSH listener") //// start the ssh server //go func() { // listenErr := ssh.ListenAndServe(":2222", nil, ssh.PasswordAuth(handlePass)) // if listenErr != nil { // log.Fatalln(listenErr.Error()) // } //}() go func() { // star the metrics listener log.Println("Starting HTTP metrics listener") http.HandleFunc("/metrics", metricsHandler) listenErr := http.ListenAndServe(":8080", nil) if listenErr != nil { log.Fatalln(listenErr.Error()) } }() ssh.Handle(handleConnection) log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.PasswordAuth(handlePass))) } func handleConnection(s ssh.Session) { cmd := exec.Command("bash") p, _ := pty.Start(cmd) go func() { var readErr error for readErr == nil { // create two buffers, one for storing the char input (buf) // and the other for storing complete commands (commandBuffer) buf := make([]byte, 1024) for { _, readErr = s.Read(buf) input := string(bytes.Trim(buf, "\x00")) log.Println(input) io.WriteString(s, input) } s.Close() return } }() io.Copy(s, p) s.Close() } func filter(buffer string) string { //if strings.Contains(buffer, "wget") == false { // return "\n" //} //return buffer // all ways return a newline -> track what is input log.Printf("%s", buffer) return "\n" } func handlePass(ctx ssh.Context, pass string) bool { metrics_num_passwords++ log.Printf("%s@%s: '%s'", ctx.User(), ctx.RemoteAddr().String(), pass) return true } // Handle HTTP /metrics requests func metricsHandler(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "num_passwords %d\n", metrics_num_passwords) }