Go语言标准库中虽然没有原生的SSH实现,但官方维护的golang.org/x/crypto/ssh包提供了完整的SSH协议支持,能够帮助我们快速实现SSH客户端认证和远程命令执行功能。

环境准备与依赖安装
首先需要安装SSH相关的依赖包,执行以下命令获取依赖:
go get golang.org/x/crypto/ssh
SSH客户端认证方式实现
密码认证方式
密码认证是最简单的SSH认证方式,只需要提供用户名、密码和目标服务器地址即可完成认证。下面是密码认证的完整实现代码:
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
)
// 密码认证创建SSH客户端配置
func passwordAuthConfig(user, password string) *ssh.ClientConfig {
return &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
// 忽略主机密钥验证,生产环境建议替换为真实的主机密钥校验逻辑
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
}
func main() {
// 目标服务器信息
user := "root"
password := "your_server_password"
host := "192.168.0.1:22"
// 创建客户端配置
config := passwordAuthConfig(user, password)
// 建立SSH连接
client, err := ssh.Dial("tcp", host, config)
if err != nil {
fmt.Printf("建立SSH连接失败: %vn", err)
return
}
defer client.Close()
fmt.Println("SSH密码认证成功,连接已建立")
}
密钥认证方式
密钥认证比密码认证更安全,适合生产环境使用。需要先准备本地私钥文件,默认路径为~/.ssh/id_rsa,实现代码如下:
package main
import (
"fmt"
"io/ioutil"
"golang.org/x/crypto/ssh"
)
// 密钥认证创建SSH客户端配置
func keyAuthConfig(user, keyPath string) (*ssh.ClientConfig, error) {
// 读取私钥文件内容
keyData, err := ioutil.ReadFile(keyPath)
if err != nil {
return nil, fmt.Errorf("读取私钥文件失败: %v", err)
}
// 解析私钥
signer, err := ssh.ParsePrivateKey(keyData)
if err != nil {
return nil, fmt.Errorf("解析私钥失败: %v", err)
}
return &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}, nil
}
func main() {
user := "root"
keyPath := "/root/.ssh/id_rsa"
host := "192.168.0.1:22"
config, err := keyAuthConfig(user, keyPath)
if err != nil {
fmt.Printf("创建认证配置失败: %vn", err)
return
}
client, err := ssh.Dial("tcp", host, config)
if err != nil {
fmt.Printf("建立SSH连接失败: %vn", err)
return
}
defer client.Close()
fmt.Println("SSH密钥认证成功,连接已建立")
}
远程命令执行实现
完成SSH认证并建立连接后,就可以创建会话执行远程命令了。下面是执行单条命令并获取输出结果的代码:
package main
import (
"fmt"
"io/ioutil"
"golang.org/x/crypto/ssh"
)
func keyAuthConfig(user, keyPath string) (*ssh.ClientConfig, error) {
keyData, err := ioutil.ReadFile(keyPath)
if err != nil {
return nil, fmt.Errorf("读取私钥文件失败: %v", err)
}
signer, err := ssh.ParsePrivateKey(keyData)
if err != nil {
return nil, fmt.Errorf("解析私钥失败: %v", err)
}
return &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}, nil
}
func executeCommand(client *ssh.Client, cmd string) (string, error) {
// 创建会话
session, err := client.NewSession()
if err != nil {
return "", fmt.Errorf("创建会话失败: %v", err)
}
defer session.Close()
// 执行命令并获取输出
output, err := session.Output(cmd)
if err != nil {
return "", fmt.Errorf("执行命令失败: %v", err)
}
return string(output), nil
}
func main() {
user := "root"
keyPath := "/root/.ssh/id_rsa"
host := "192.168.0.1:22"
config, err := keyAuthConfig(user, keyPath)
if err != nil {
fmt.Printf("创建认证配置失败: %vn", err)
return
}
client, err := ssh.Dial("tcp", host, config)
if err != nil {
fmt.Printf("建立SSH连接失败: %vn", err)
return
}
defer client.Close()
// 执行远程命令
cmd := "ls -l /tmp"
result, err := executeCommand(client, cmd)
if err != nil {
fmt.Printf("执行命令失败: %vn", err)
return
}
fmt.Printf("命令执行结果:n%sn", result)
}
常见问题与注意事项
- 生产环境中不要使用
ssh.InsecureIgnoreHostKey(),应该提前获取服务器的主机公钥并校验,避免中间人攻击。 - 密钥认证时如果私钥有密码保护,需要使用
ssh.ParsePrivateKeyWithPassphrase方法解析私钥。 - 执行长时间运行的命令时,建议设置会话的超时时间,避免连接长时间阻塞。
- 如果需要执行交互式命令,需要额外处理会话的输入输出流,使用
session.Stdin、session.Stdout、session.Stderr进行读写操作。
总结
通过golang.org/x/crypto/ssh包,我们可以轻松实现Go语言的SSH客户端认证和远程命令执行功能。密码认证适合临时测试场景,密钥认证更适合生产环境。实际使用时需要根据需求选择合适的认证方式,同时注意安全性和异常处理,保证程序的稳定性。
GoSSH客户端认证远程命令执行ssh_client修改时间:2026-07-01 02:24:39