golang实现ssh远程操作
场景
配合flag
加几个参数方便在镜像里远程执行脚本命令,好多基础docker镜像里不含ssh
go语言实现ssh操作,可以自定义ssh端口
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
"log"
)
func main() {
// 远程服务器的连接信息
sshConfig := &ssh.ClientConfig{
User: "root", // 远程服务器的用户名
Auth: []ssh.AuthMethod{
ssh.Password("Server2008!"), // 远程服务器的密码
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// 远程服务器的地址
sshAddress := "172.20.51.110:22" // 远程服务器的IP地址或主机名和SSH端口号
// 要执行的远程命令
remoteCommand := "ip a"
// SSH 连接远程服务器
sshClient, err := ssh.Dial("tcp", sshAddress, sshConfig)
if err != nil {
log.Fatal(err)
}
defer sshClient.Close()
// 创建会话
session, err := sshClient.NewSession()
if err != nil {
log.Fatal(err)
}
defer session.Close()
// 执行远程命令
output, err := session.CombinedOutput(remoteCommand)
if err != nil {
log.Fatal(err)
}
// 输出命令执行结果
fmt.Println(string(output))
}
使用key认证
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
"io/ioutil"
"log"
"os"
)
func main() {
// 远程服务器的SSH连接信息
sshUser := "username" // 远程服务器的用户名
sshPrivateKeyPath := "/path/to/key" // SSH私钥文件的路径
sshServer := "remote_server" // 远程服务器的IP地址或主机名
// SSH连接配置
sshConfig := &ssh.ClientConfig{
User: sshUser,
Auth: []ssh.AuthMethod{
publicKeyFile(sshPrivateKeyPath),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// 连接远程服务器
sshClient, err := ssh.Dial("tcp", sshServer+":22", sshConfig)
if err != nil {
log.Fatal(err)
}
defer sshClient.Close()
// 创建会话
session, err := sshClient.NewSession()
if err != nil {
log.Fatal(err)
}
defer session.Close()
// 执行Shell命令
output, err := session.CombinedOutput("ls -l")
if err != nil {
log.Fatal(err)
}
// 输出结果
fmt.Println(string(output))
}
// 从私钥文件中获取公钥
func publicKeyFile(file string) ssh.AuthMethod {
buffer, err := ioutil.ReadFile(file)
if err != nil {
log.Fatal(err)
}
key, err := ssh.ParsePrivateKey(buffer)
if err != nil {
log.Fatal(err)
}
return ssh.PublicKeys(key)
}
使用Golang SSH如果想本地脚本远程执行
package main
import (
"flag"
"fmt"
"golang.org/x/crypto/ssh"
"io/ioutil"
"log"
// "os"
)
func main() {
var sshUser, sshPrivateKeyPath, sshServer, localScriptPath string
flag.StringVar(&sshUser, "u", "root", "远程服务器的用户名.")
flag.StringVar(&sshPrivateKeyPath, "k", "/root/.ssh/id_rsa", "SSH私钥文件的路径.")
flag.StringVar(&sshServer, "s", "127.0.0.1", "远程服务器的IP地址或主机名.")
flag.StringVar(&localScriptPath, "f", "", "本地脚本文件的路径.")
flag.Parse()
// 远程服务器的SSH连接信息
// sshUser := root // 远程服务器的用户名
// sshPrivateKeyPath := "/root/.ssh/id_rsa" // SSH私钥文件的路径
// sshServer := "127.0.0.1" // 远程服务器的IP地址或主机名
// 本地脚本文件路径
// localScriptPath := "/data/test-go/ssh/666.sh" // 本地脚本文件的路径
// 读取本地脚本文件内容
scriptBytes, err := ioutil.ReadFile(localScriptPath)
if err != nil {
log.Fatal(err)
}
// SSH连接配置
sshConfig := &ssh.ClientConfig{
User: sshUser,
Auth: []ssh.AuthMethod{
publicKeyFile(sshPrivateKeyPath),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// 连接远程服务器
sshClient, err := ssh.Dial("tcp", sshServer+":22", sshConfig)
if err != nil {
log.Fatal(err)
}
defer sshClient.Close()
// 创建会话
session, err := sshClient.NewSession()
if err != nil {
log.Fatal(err)
}
defer session.Close()
// 执行远程脚本
output, err := session.CombinedOutput(string(scriptBytes))
if err != nil {
log.Fatal(err)
}
// 输出结果
fmt.Println(string(output))
}
// 从私钥文件中获取公钥
func publicKeyFile(file string) ssh.AuthMethod {
buffer, err := ioutil.ReadFile(file)
if err != nil {
log.Fatal(err)
}
key, err := ssh.ParsePrivateKey(buffer)
if err != nil {
log.Fatal(err)
}
return ssh.PublicKeys(key)
}