一、执行shell命令
1.1 官方ssh库 golang.org/x/crypto/ssh
定义全局变量
var (
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
sftpClient *sftp.Client
err error
)
定义一个ssh连接函数
func SShConnect(user, publicKeyFile, host string, port int) (*ssh.Client, error) {
privateKeyBytes, err := ioutil.ReadFile(publicKeyFile)
if err != nil {
log.Fatal(err)
}
log.Println("privateKeyBytes: ",privateKeyBytes)
key, err := ssh.ParsePrivateKey(privateKeyBytes)
if err != nil {
log.Fatal(err)
}
log.Println("key: ",key)
clientConfig = &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(key),
},
Timeout: 30 * time.Second,
//这个是问你要不要验证远程主机,以保证安全性。这里return nil不验证
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
addr = fmt.Sprintf("%s:%d", host, port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
return client, nil
}
主函数执行并打印
func main() {
sshCli, err := SShConnect("root", "I:\Document And Settings2\Administrator\Desktop\id_rsa", "192.168.9.21", 22)
if err != nil {
log.Fatal("连接失败: ", err)
return
}
defer sshCli.Close()
sshSession, err := sshCli.NewSession()
if err != nil {
log.Fatal("SSH连接失败: ", err)
}
var execResult = make([]byte, 1024)
execResult,err = sshSession.Output("df -hT")
if err != nil {
log.Fatal("执行失败: ", err)
}
log.Println(string(execResult))
}
1.2 简单的SSH easyssh-proxy
GitHub上有相关示例,Golang软件包,可通过SSH和SCP下载通过轻松地远程执行ProxyCommand和上传文件. 个人未发现可以复制远程机器文件到本机
二、复制远程文件到本地
2.1 SFTP包 sftp 结合crypto/ssh,实现复制远程文件到本机
func main() {
sshCli, err := SShConnect("root", "I:\Document And Settings2\Administrator\Desktop\id_rsa", "192.168.9.21", 22)
if err != nil {
log.Fatal("SSH连接失败: ", err)
}
defer sshCli.Close()
sftpCli,err := SFtpConnect(sshCli)
if err != nil {
log.Fatal("SFtp连接失败: ", err)
}
defer sftpCli.Close()
var buf = make([]byte, 1024)
sftpF, err := sftpCli.Open("/tmp/a.txt")
if err != nil {
log.Fatal("打开远程文件连接失败: ", err)
}
for {
file, err := os.OpenFile("./xxx.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
defer file.Close()
if err != nil {
log.Fatal("打开本地文件失败:", err)
}
n, _ := sftpF.Read(buf)
if n == 0 {
break
}
file.Write(buf[:n]) // 写数据到本地文件
}
}