本文介绍如何在 go 中绕过 shell 命令拼接,直接通过 os.open 读取本地公钥文件并以标准输入(stdin)方式传输至远程服务器的 authorized_keys,避免 shell 注入、路径错误与跨平台兼容性问题。 本文介绍如何在 go 中绕过 shell 命令拼接,直接通过 os.open 读取本地公钥文件并以标准输入(stdin)方式传输至远程服务器的 authorized_keys,避免 shell 注入、路径错误与跨平台兼容性问题。在自动化部署或基础设施管理场景中,经常需要通过 Go 程序将本地生成的 SSH 公钥安全地追加到远程 Linux/macOS 服务器的 ~/.ssh/authorized_keys 文件中。许多开发者最初尝试用 exec.Command 模拟终端管道命令(如 cat key.pub | ssh user@host 'cat >> ~/.ssh/authorized_keys'),但这种方式存在严重缺陷:不仅因字符串拼接易引发 shell 注入和路径解析错误(如示例中误写为 ~/.shh/authorized_keys),更因 exec.Command 的参数传递机制不支持 Unix 管道符 | ------ 它只会把整个字符串当作单一命令名执行,导致运行失败。正确的做法是解耦「读取」与「传输」逻辑:由 Go 直接打开公钥文件,再将其作为 stdin 注入 ssh 子进程。这样既规避了 shell 解析依赖,又确保了二进制安全传输(无换行截断、编码失真风险),且天然兼容 macOS、Linux 等不同系统。以下为推荐实现方案:import ( "log" "os" "os/exec" "path/filepath")func copySSHPubKeyToServer(pubKeyPath, userAtHost string) error { // 1. 安全读取公钥文件(自动处理路径) absPath, err := filepath.Abs(pubKeyPath) if err != nil { return err } file, err := os.Open(absPath) if err != nil { return err } defer file.Close() // 2. 构建 ssh 命令:注意目标路径应为 ~/.ssh/authorized_keys(非 .shh!) cmd := exec.Command("ssh", userAtHost, "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys") cmd.Stdin = file // 3. 执行并捕获输出(便于调试) output, err := cmd.CombinedOutput() if err != nil { log.Printf("SSH command failed: %s", string(output)) return err } return nil}// 使用示例func main() { homeDir := fileUtil.FindUserHomeDir() // 假设该工具函数已定义 pubKeyPath := filepath.Join(homeDir, ".ssh", "foobar.pub") userAtHost := "alice@example.com" if err := copySSHPubKeyToServer(pubKeyPath, userAtHost); err != nil { log.Fatal("Failed to install SSH key:", err) } log.Println("SSH public key successfully installed.")}? 关键优势说明: 幻导航网 发现优质实用网站,开启网络探索之旅!
相关推荐
兔头?几秒前
JVM学习文档小小张说故事3 分钟前
Python 的 int 为什么不会溢出?拆开 PyLongObject 和它背后那串变长数组潇湘秦7 分钟前
SQL Server 2016+ 整数类型元数据扩宽(秒级变更)完整说明晴天¥11 分钟前
记一次Oracle 归档进程卡死怎么去有效排查小手cool20 分钟前
PostgreSQL 基础入门:从安装到核心概念Bushlet21 分钟前
Mysql建库及建表流程总结威哥爱编程36 分钟前
Python 智能体开发实战 03:聊十轮就“失忆”,账单还翻倍?管好上下文,Token 立省一半情 九37 分钟前
MCP 开发环境搭建:Mac 与 Windows 跑通 Python 服务和 stdio 客户端梦幻通灵38 分钟前
MybatisPlus使用数据库递增ID实现方案【持续更新】