mirror of
https://github.com/shanghai-edu/multissh.git
synced 2025-12-16 05:17:52 +00:00
version 0.2
This commit is contained in:
parent
c1c790e653
commit
87e207932f
13 changed files with 638 additions and 316 deletions
79
funcs/ssh_test.go
Normal file
79
funcs/ssh_test.go
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
package funcs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
// "os"
|
||||
//"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
username = "root"
|
||||
password = ""
|
||||
ip = "192.168.80.131"
|
||||
port = 22
|
||||
cmd = "cd /opt;pwd;exit"
|
||||
key = "../server.key"
|
||||
)
|
||||
|
||||
/*
|
||||
func Test_SSH(t *testing.T) {
|
||||
var cipherList []string
|
||||
session, err := connect(username, password, ip, key, port, cipherList)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
cmdlist := strings.Split(cmd, ";")
|
||||
stdinBuf, err := session.StdinPipe()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
var outbt, errbt bytes.Buffer
|
||||
session.Stdout = &outbt
|
||||
|
||||
session.Stderr = &errbt
|
||||
err = session.Shell()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
for _, c := range cmdlist {
|
||||
c = c + "\n"
|
||||
stdinBuf.Write([]byte(c))
|
||||
|
||||
}
|
||||
session.Wait()
|
||||
t.Log((outbt.String() + errbt.String()))
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func Test_SSH_run(t *testing.T) {
|
||||
var cipherList []string
|
||||
session, err := connect(username, password, ip, key, port, cipherList)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
//cmdlist := strings.Split(cmd, ";")
|
||||
//newcmd := strings.Join(cmdlist, "&&")
|
||||
var outbt, errbt bytes.Buffer
|
||||
session.Stdout = &outbt
|
||||
|
||||
session.Stderr = &errbt
|
||||
err = session.Run(cmd)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
t.Log((outbt.String() + errbt.String()))
|
||||
|
||||
return
|
||||
}
|
||||
200
funcs/sshconnect.go
Normal file
200
funcs/sshconnect.go
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
package funcs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/shanghai-edu/multissh/g"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
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 Dossh(username, password, host, key string, cmdlist []string, port, timeout int, cipherList []string, linuxMode bool, ch chan g.SSHResult) {
|
||||
chSSH := make(chan g.SSHResult)
|
||||
if linuxMode {
|
||||
go dossh_run(username, password, host, key, cmdlist, port, cipherList, chSSH)
|
||||
} else {
|
||||
go dossh_session(username, password, host, key, cmdlist, port, cipherList, chSSH)
|
||||
}
|
||||
var res g.SSHResult
|
||||
|
||||
select {
|
||||
case <-time.After(time.Duration(timeout) * time.Second):
|
||||
res.Host = host
|
||||
res.Success = false
|
||||
res.Result = ("SSH run timeout:" + strconv.Itoa(timeout) + " second.")
|
||||
ch <- res
|
||||
case res = <-chSSH:
|
||||
ch <- res
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func dossh_session(username, password, host, key string, cmdlist []string, port int, cipherList []string, ch chan g.SSHResult) {
|
||||
session, err := connect(username, password, host, key, port, cipherList)
|
||||
var sshResult g.SSHResult
|
||||
sshResult.Host = host
|
||||
|
||||
if err != nil {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
|
||||
ch <- sshResult
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
cmdlist = append(cmdlist, "exit")
|
||||
|
||||
stdinBuf, _ := session.StdinPipe()
|
||||
|
||||
var outbt, errbt bytes.Buffer
|
||||
session.Stdout = &outbt
|
||||
|
||||
session.Stderr = &errbt
|
||||
err = session.Shell()
|
||||
if err != nil {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
|
||||
ch <- sshResult
|
||||
return
|
||||
}
|
||||
for _, c := range cmdlist {
|
||||
c = c + "\n"
|
||||
stdinBuf.Write([]byte(c))
|
||||
}
|
||||
session.Wait()
|
||||
if errbt.String() != "" {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = errbt.String()
|
||||
ch <- sshResult
|
||||
} else {
|
||||
sshResult.Success = true
|
||||
sshResult.Result = outbt.String()
|
||||
ch <- sshResult
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func dossh_run(username, password, host, key string, cmdlist []string, port int, cipherList []string, ch chan g.SSHResult) {
|
||||
session, err := connect(username, password, host, key, port, cipherList)
|
||||
var sshResult g.SSHResult
|
||||
sshResult.Host = host
|
||||
|
||||
if err != nil {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
|
||||
ch <- sshResult
|
||||
return
|
||||
}
|
||||
defer session.Close()
|
||||
|
||||
cmdlist = append(cmdlist, "exit")
|
||||
newcmd := strings.Join(cmdlist, "&&")
|
||||
|
||||
var outbt, errbt bytes.Buffer
|
||||
session.Stdout = &outbt
|
||||
|
||||
session.Stderr = &errbt
|
||||
err = session.Run(newcmd)
|
||||
if err != nil {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = fmt.Sprintf("<%s>", err.Error())
|
||||
ch <- sshResult
|
||||
return
|
||||
}
|
||||
|
||||
if errbt.String() != "" {
|
||||
sshResult.Success = false
|
||||
sshResult.Result = errbt.String()
|
||||
ch <- sshResult
|
||||
} else {
|
||||
sshResult.Success = true
|
||||
sshResult.Result = outbt.String()
|
||||
ch <- sshResult
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue