// initAuthMethod initiates SSH authentication method. func initAuthMethod() { var signers []ssh.Signer // If there's a running SSH Agent, try to use its Private keys. sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) if err == nil { agent := agent.NewClient(sock) signers, _ = agent.Signers() } // Try to read user's SSH private keys form the standard paths. files := []string{ os.Getenv("HOME") + "/.ssh/id_rsa", os.Getenv("HOME") + "/.ssh/id_dsa", } for _, file := range files { data, err := ioutil.ReadFile(file) if err != nil { continue } signer, err := ssh.ParsePrivateKey(data) if err != nil { continue } signers = append(signers, signer) } authMethod = ssh.PublicKeys(signers...) }
func NewSshExecWithAuth(user string) *SshExec { sshexec := &SshExec{} authSocket := os.Getenv("SSH_AUTH_SOCK") if authSocket == "" { log.Fatal("SSH_AUTH_SOCK required, check that your ssh agent is running") return nil } agentUnixSock, err := net.Dial("unix", authSocket) if err != nil { log.Fatal(err) return nil } agent := agent.NewClient(agentUnixSock) signers, err := agent.Signers() if err != nil { log.Fatal(err) return nil } sshexec.clientConfig = &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ssh.PublicKeys(signers...)}, } return sshexec }
func main() { if !(len(os.Args) > 1) { log.Fatal("action required.") } action := os.Args[1] os.Args = append(os.Args[:1], os.Args[2:]...) flag.Parse() authSocket := os.Getenv("SSH_AUTH_SOCK") if authSocket == "" { log.Fatal("SSH_AUTH_SOCK required, check that your ssh agent is running") } agentUnixSock, err := net.Dial("unix", authSocket) if err != nil { log.Fatal(err) } agent := agent.NewClient(agentUnixSock) signers, err := agent.Signers() if err != nil { log.Fatal(err) } clientConfig = &ssh.ClientConfig{ User: sshUser, Auth: []ssh.AuthMethod{ssh.PublicKeys(signers...)}, } hostsList := strings.Split(hosts, ",") if !(len(hostsList) > 0) { log.Fatal("one or more hosts required, use the -host flag") } stderrChan = make(chan string, 0) stdoutChan = make(chan string, 0) go consoleWriter() switch action { case "deploy": if etcdBinary != "" { deployFromEtcdBinary(etcdBinary, hostsList) os.Exit(0) } if gitCommit != "" { deployFromGitCommit(gitCommit, hostsList) os.Exit(0) } if gitTag != "" { deployFromGitTag(gitTag, hostsList) os.Exit(0) } case "version": etcdVersion(hostsList) } }
func executeCmd(cmd string, machine *Machine) { for i, user := range machine.PotentialUsers { sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) if err != nil { log.Fatal(err) } agent := agent.NewClient(sock) signers, err := agent.Signers() if err != nil { log.Fatal(err) } auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)} cfg := &ssh.ClientConfig{ User: user, Auth: auths, } cfg.SetDefaults() client, errConnect := ssh.Dial("tcp", machine.DialAddr(), cfg) if errConnect != nil { authError := strings.Contains(errConnect.Error(), "unable to authenticate") if authError && i <= (len(machine.PotentialUsers)-1) { continue } printState(machine.String(), errConnect.Error()) return } session, errSession := client.NewSession() if errSession != nil { printState(machine.String(), errSession.Error()) return } errRun := session.Run(cmd) if errRun != nil { printState(machine.String(), errRun.Error()) return } printState(machine.String(), "SUCCESS") return } }
func main() { sock, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")) if err != nil { log.Fatal(err) } agent := agent.NewClient(sock) signers, err := agent.Signers() if err != nil { log.Fatal(err) } // An SSH client is represented with a ClientConn. Currently only // the "password" authentication method is supported. // // To authenticate with the remote server you must pass at least one // implementation of AuthMethod via the Auth field in ClientConfig. auths := []ssh.AuthMethod{ssh.PublicKeys(signers...)} config := &ssh.ClientConfig{ User: "******", Auth: auths, } // config := &ssh.ClientConfig{ // User: "******", // Auth: []ssh.AuthMethod{ // ssh.Password("yourpassword"), // }, // } client, err := ssh.Dial("tcp", "128.199.236.127:22", config) if err != nil { panic("Failed to dial: " + err.Error()) } // Each ClientConn can support multiple interactive sessions, // represented by a Session. session, err := client.NewSession() if err != nil { panic("Failed to create session: " + err.Error()) } defer session.Close() out, err := session.StdoutPipe() if err != nil { panic("Failed to create session pipe: " + err.Error()) } scanner := bufio.NewScanner(out) go func() { for scanner.Scan() { fmt.Printf("new line received: %s\n", scanner.Text()) } }() if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading standard input:", err) } //if err := session.Run("while [ 1 ];do date;sleep 1;done"); err != nil { if err := session.Run("`"); err != nil { panic("Failed to run: " + err.Error()) } session.Wait() }