container_network/crawler/ssh/client/client.go

128 lines
2.5 KiB
Go
Raw Normal View History

2018-04-19 15:46:38 +00:00
package client
import (
"bytes"
"fmt"
"io/ioutil"
"time"
2018-04-28 15:01:45 +00:00
"git.loafle.net/commons/logging-go"
cuej "git.loafle.net/commons/util-go/encoding/json"
2018-04-26 08:50:26 +00:00
ocmsc "git.loafle.net/overflow/commons-go/model/sensorconfig"
2018-04-19 15:46:38 +00:00
"golang.org/x/crypto/ssh"
)
type SSHConfig struct {
User string
Auth []ssh.AuthMethod
Host string
Port int
}
type SSHClient struct {
conf *SSHConfig
}
func (cli *SSHClient) Session() (*ssh.Session, error) {
sshConfig := &ssh.ClientConfig{
User: cli.conf.User,
Auth: cli.conf.Auth,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: time.Second * 10,
}
addr := fmt.Sprintf("%s:%d", cli.conf.Host, cli.conf.Port)
connection, err := ssh.Dial("tcp", addr, sshConfig)
if err != nil {
return nil, err
}
session, err := connection.NewSession()
if 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 {
session.Close()
return nil, err
}
return session, nil
}
func (cli *SSHClient) RunCommand(command string) ([]byte, error) {
session, err := cli.Session()
if nil != err {
return nil, err
}
defer func() {
session.Close()
}()
var b bytes.Buffer
session.Stdout = &b
logging.Logger().Debugf("%s \n", command)
if err := session.Run(command); nil != err {
return nil, err
}
return b.Bytes(), nil
}
func parsePrivateKey(keyPath, pw string) (ssh.Signer, error) {
buff, err := ioutil.ReadFile(keyPath)
if err != nil {
return nil, err
}
if pw == "" {
return ssh.ParsePrivateKey(buff)
}
return ssh.ParsePrivateKeyWithPassphrase(buff, []byte(pw))
}
2018-04-26 08:50:26 +00:00
func New(target *ocmsc.Target) (*SSHClient, error) {
2018-04-19 15:46:38 +00:00
connection := target.Connection
auth := target.Auth
ip := connection.IP
port, _ := cuej.NumberToInt(connection.Port)
user := auth["id"].(string)
pw := auth["pw"].(string)
keyFilePathObj := auth["keyFilePath"]
keyFilePath := ""
sshAuth := make([]ssh.AuthMethod, 0)
if keyFilePathObj != nil {
keyFilePath = keyFilePathObj.(string)
if "" != keyFilePath {
key, err := parsePrivateKey(keyFilePath, pw)
if err != nil {
return nil, err
}
sshAuth = append(sshAuth, ssh.PublicKeys(key))
}
}
sshAuth = append(sshAuth, ssh.Password(pw))
sshConf := &SSHConfig{
User: user,
Auth: sshAuth,
Host: ip,
Port: port,
}
return &SSHClient{
conf: sshConf,
}, nil
}