goph:Go 语言 SSH 客户端库,密码/私钥/Agent 多认证 + 跳板机 + SFTP 文件传输
来源:微信公众号
goph 是一个专注于简单性和易用性的 Go SSH 客户端库,用优雅的 API 设计,只需几行代码就能完成复杂的 SSH 操作。
GitHub:https://github.com/melbahja/goph
文档:https://pkg.go.dev/github.com/melbahja/goph
核心特性
多样化的认证方式
| 认证方式 | 说明 |
|---|---|
| 密码认证 | 最简单直接 |
| 私钥认证 | 支持 RSA、ED25519 等 |
| 带密码的私钥 | 自动处理 passphrase |
| SSH Agent | 自动检测本地 agent |
| 键盘交互 | 支持双因素认证 |
| 多种认证组合 | 可同时尝试多种方式 |
连接能力
- Known Hosts 验证:默认开启,安全第一
- SOCKS5 代理:通过代理服务器连接
- 跳板机支持:轻松穿透堡垒机
- 自定义端口和超时:完全可控
文件操作
- 文件上传(本地 → 远程)
- 文件下载(远程 → 本地)
- SFTP 操作:Open、Create、Chmod 等
上下文控制
- 命令超时(通过 Context 设置超时)
- 优雅取消(支持 SIGINT 信号)
- 并发控制(在其他 goroutine 中取消)
安装
go get github.com/melbahja/goph/v2
快速开始
package main
import (
"log"
"fmt"
"github.com/melbahja/goph/v2"
)
func main() {
// 创建 SSH 连接(使用密码)
client, err := goph.New("root", "192.1.1.3",
goph.WithPassword("your_password"))
if err != nil {
log.Fatal(err)
}
defer client.Close()
// 执行远程命令
out, err := client.Run("ls /tmp/")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
三步完成:创建连接 → 执行命令 → 获取结果。
实用示例
私钥认证
client, err := goph.New("root", "192.1.1.3",
goph.WithKeyFile("/home/user/.ssh/id_rsa", ""),
)
多种认证组合
client, err := goph.New("root", "192.1.1.3",
goph.WithPassword("try_password_first"),
goph.WithKeyFile("/home/user/.ssh/id_rsa", ""),
goph.WithDefaultAgent(),
)
文件上传下载
// 上传文件
err := client.Upload("/local/file.txt", "/remote/file.txt")
// 下载文件
err := client.Download("/remote/file.txt", "/local/file.txt")
通过跳板机连接
// 先连接跳板机
jump, err := goph.New("jumpuser", "bastion.example.com",
goph.WithKeyFile("/home/user/.ssh/id_rsa", ""),
)
defer jump.Close()
// 通过跳板机连接目标主机
client, err := goph.New("root", "internal-host",
goph.WithKeyFile("/home/user/.ssh/id_rsa", ""),
goph.WithJump(jump),
)
SOCKS5 代理连接
client, err := goph.New("root", "target-host",
goph.WithPassword("pass"),
goph.WithProxy("socks5://127.0.0.1:1080"),
)
// 带认证的代理
client, err = goph.New("root", "target-host",
goph.WithPassword("pass"),
goph.WithProxy("socks5://user:pass@127.0.0.1:1080"),
)
命令超时控制
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 1 秒后自动发送 SIGINT 并返回错误
out, err := client.RunContext(ctx, "sleep 5")
执行脚本文件
cmd, err := client.ScriptFile(ctx, "/path/to/script.sh")
// 指定解释器
cmd, err = client.ScriptFile(ctx, "/path/to/script.php",
goph.WithPath("/usr/bin/php"))
安全特性
默认启用 Known Hosts 验证,自动使用 ~/.ssh/known_hosts 验证主机:
client, err := goph.New("root", "192.1.1.3",
goph.WithPassword("pass"),
)
检查并添加信任主机:
found, err := goph.CheckKnownHost("myhost", remoteAddr, publicKey, "")
if !found {
goph.AddKnownHost("myhost", remoteAddr, publicKey, "")
}
工具函数
// 检查 SSH Agent 是否可用
if goph.HasAgent() {
fmt.Println("SSH agent 可用")
}
// 获取默认 known_hosts 路径
path, _ := goph.DefaultKnownHostsPath()
// 解析私钥文件
signer, _ := goph.ParseKeyFile("/home/user/.ssh/id_rsa", "passphrase")
常见问题
如何执行 sudo 命令?
cmd, _ := client.Command("sudo", "-S", "systemctl", "restart", "nginx")
cmd.Stdin = strings.NewReader("your_sudo_password\n")
out, _ := cmd.CombinedOutput()
支持 Windows 吗? 支持!纯 Go 实现,跨平台兼容 Windows、Linux、macOS。
适用场景
- 自动化运维脚本
- 远程命令执行
- 文件传输工具
- CI/CD 流水线
- 服务器管理平台
设计优势
| 优势 | 说明 |
|---|---|
| API 简洁 | 学习成本低 |
| 功能全面 | 认证、文件传输、代理、跳板机 |
| 安全优先 | known_hosts 验证默认开启 |
| 现代 Go | 支持上下文控制 |
| 跨平台 | 纯 Go 实现 |