package main import ( "fmt" "io" "log" "os" "os/exec" "strings" "syscall" "unsafe" "github.com/creack/pty" "github.com/gliderlabs/ssh" gossh "golang.org/x/crypto/ssh" ) func main() { ssh.Handle(func(s ssh.Session) { authorizedKey := gossh.MarshalAuthorizedKey(s.PublicKey()) io.WriteString(s, fmt.Sprintf("\r\n%s\r\n", strings.Repeat("-", 88))) io.WriteString(s, fmt.Sprintf("public key used by %s:\n", s.User())) io.WriteString(s, fmt.Sprintf("%v", s.PublicKey())) io.WriteString(s, fmt.Sprintf("\r\n%s\r\n", strings.Repeat("-", 88))) s.Write(authorizedKey) io.WriteString(s, fmt.Sprintf("\r\n%s\r\n", strings.Repeat("-", 88))) cmd := exec.Command("/bin/bash") ptyReq, winCh, isPty := s.Pty() if isPty { cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term)) f, err := pty.Start(cmd) if err != nil { panic(err) } go func() { for win := range winCh { setWinsize(f, win.Width, win.Height) } }() go func() { io.Copy(f, s) // stdin }() io.Copy(s, f) // stdout cmd.Wait() } else { io.WriteString(s, "No PTY requested.\n") s.Exit(1) } }) publicKeyOption := ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool { log.Println("type: ", key.Type()) if key.Type() == "sk-ecdsa-sha2-nistp256@openssh.com" { return true } return false //return true // allow all keys, or use ssh.KeysEqual() to compare against known keys }) log.Println("Listening :222...") log.Fatal(ssh.ListenAndServe(":2222", nil, publicKeyOption)) } func setWinsize(f *os.File, w, h int) { syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&struct{ h, w, x, y uint16 }{uint16(h), uint16(w), 0, 0}))) }