/
ssh.go
127 lines (109 loc) · 2.81 KB
/
ssh.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
package ssh
import (
"fmt"
"io/ioutil"
"net"
"os"
"os/exec"
"time"
"golang.org/x/crypto/ssh"
"k8s.io/client-go/util/homedir"
)
func QuickConnectAndRun(host, cmd string) error {
s, err := QuickConnectUsingDefaultSSHKey(host)
if err != nil {
return err
}
s.Stdout = os.Stdout
s.Stderr = os.Stderr
return s.Run(cmd)
}
func QuickConnectAndGetRunOutput(host, cmd string) ([]byte, error) {
s, err := QuickConnectUsingDefaultSSHKey(host)
if err != nil {
return nil, err
}
return s.CombinedOutput(cmd)
}
func QuickConnectUsingDefaultSSHKey(host string) (*ssh.Session, error) {
return Connect("root", "", host, GetDefaultPrivateKeyFile(), 22, nil)
}
func Connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
config ssh.Config
session *ssh.Session
err error
)
// get auth method
auth = make([]ssh.AuthMethod, 0)
if key == "" {
auth = append(auth, ssh.Password(password))
} else {
pemBytes, err := ioutil.ReadFile(key)
if err != nil {
return nil, err
}
var signer ssh.Signer
if password == "" {
signer, err = ssh.ParsePrivateKey(pemBytes)
} else {
signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password))
}
if err != nil {
return nil, err
}
auth = append(auth, ssh.PublicKeys(signer))
}
if len(cipherList) == 0 {
config = ssh.Config{
Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
}
} else {
config = ssh.Config{
Ciphers: cipherList,
}
}
clientConfig = &ssh.ClientConfig{
User: user,
Auth: auth,
Timeout: 30 * time.Second,
Config: config,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
// connet to ssh
addr = fmt.Sprintf("%s:%d", host, port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
// create session
if session, err = client.NewSession(); err != nil {
return nil, err
}
modes := ssh.TerminalModes{
ssh.ECHO: 0, // disable echoing
ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
return nil, err
}
return session, nil
}
func GetDefaultPrivateKeyFile() string {
home := homedir.HomeDir()
return home + "/.ssh/id_rsa"
}
func GetDefaultPublicKeyFile() string {
home := homedir.HomeDir()
return home + "/.ssh/id_rsa.pub"
}
func ScpFileToRemote(source, dst, host string) error {
cmd := exec.Command("scp", source, fmt.Sprintf("root@%s:%s", host, dst))
return cmd.Run()
}