pupirka
/
sshclient.go
99 строк · 2.8 Кб
1package main
2
3import (
4"bytes"
5"errors"
6"fmt"
7"golang.org/x/crypto/ssh"
8"io/ioutil"
9"time"
10)
11
12var sshkkeysAlgo = []string{
13"diffie-hellman-group1-sha1",
14"diffie-hellman-group14-sha1",
15"ecdh-sha2-nistp256",
16"ecdh-sha2-nistp384",
17"ecdh-sha2-nistp521",
18"diffie-hellman-group-exchange-sha1",
19"diffie-hellman-group-exchange-sha256",
20"curve25519-sha256@libssh.org",
21}
22var sshChippers = []string{
23"aes128-gcm@openssh.com",
24"cast128-cbc",
25"aes128-ctr", "aes192-ctr", "aes256-ctr",
26"3des-cbc", "blowfish-cbc", "twofish-cbc", "twofish256-cbc", "twofish192-cbc", "twofish128-cbc", "aes256-cbc", "aes192-cbc", "aes128-cbc", "arcfour",
27}
28
29//connect and run command, return []byte
30func SshClientRun(device *Device) ([]byte, error) {
31
32auth, err := SshClientDeviceAuth(device)
33if err != nil {
34return []byte{}, err
35}
36device.LogDebug(fmt.Sprintf("SshClientRun: Get auth (%t)", auth))
37
38config := &ssh.ClientConfig{
39Config: ssh.Config{
40KeyExchanges: sshkkeysAlgo,
41Ciphers: sshChippers,
42},
43User: device.Username,
44Auth: auth,
45HostKeyCallback: ssh.InsecureIgnoreHostKey(),
46Timeout: time.Duration(device.Timeout) * time.Second,
47}
48address := SshAddressFormat(device)
49client, err := ssh.Dial("tcp", address, config)
50if err != nil {
51return nil, errors.New("SshClientRun: DialSSH error:" + err.Error())
52}
53defer client.Close()
54device.LogDebug(fmt.Sprintf("SshClientRun: ssh Dial running %s", device.Name))
55session, err := client.NewSession()
56if err != nil {
57return nil, errors.New("SshClientRun: NewSession error:" + err.Error())
58}
59defer session.Close()
60device.LogDebug(fmt.Sprintf("SshClientRun: ssh session running %s", device.Name))
61var b bytes.Buffer
62session.Stdout = &b
63
64if err := session.Run(device.Command); err != nil {
65return nil, errors.New("SshClientRun: Run command error:" + err.Error())
66}
67device.LogDebug(fmt.Sprintf("SshClientRun: Read bytes good %s", device.Name))
68return b.Bytes(), nil
69}
70
71//prepare auth method for client
72func SshClientDeviceAuth(device *Device) ([]ssh.AuthMethod, error) {
73var auth []ssh.AuthMethod
74if device.Authkey == false {
75if device.Password == "" {
76return nil, errors.New("SshClientDeviceAuth: Password empty")
77}
78auth = append(auth, ssh.Password(device.Password))
79return auth, nil
80}
81
82flp := fmt.Sprintf("%s/%s", ConfigV.GetString("path.key"), device.Key)
83key, err := ioutil.ReadFile(flp)
84if err != nil {
85return nil, errors.New("SshClientDeviceAuth: read key file:" + err.Error())
86}
87signer, err := ssh.ParsePrivateKey(key)
88if err != nil {
89return nil, errors.New("SshClientDeviceAuth: parse private file:" + err.Error())
90}
91auth = append(auth, ssh.PublicKeys(signer))
92return auth, nil
93}
94
95func SshAddressFormat(device *Device) string {
96str := fmt.Sprintf("%s:%d", device.Address, device.PortSSH)
97device.LogDebug(fmt.Sprintf("SshAddressFormat: addres (%s)", str))
98return str
99}
100