Ubuntu下NodeJS生成id_rsa文件格式无效问题求助
解决SSH私钥写入后格式无效的问题
我在GitHub Action环境里处理过类似的SSH密钥问题,你遇到的invalid format错误通常是由几个常见原因导致的,咱们一步步排查解决:
1. 替换appendFile为writeFile
你当前使用的appendFile会把密钥追加到文件末尾,如果id_rsa文件之前已经存在(比如GitHub Runner默认生成过,或者之前步骤创建过),就会导致密钥内容被拼接,格式彻底混乱。应该用writeFile覆盖写入,确保文件里只有你的私钥:
import { writeFile } from 'fs'; const createFile = promisify(writeFile); // 用writeFile替代appendFile,确保文件内容仅为目标私钥 await createFile(`${ssh}/id_rsa`, action.deployKey, { encoding: 'utf8' });
2. 修复私钥的换行与空格问题
GitHub Action环境中,多行私钥存储为环境变量时,换行符可能被转义成\n或者直接丢失;另外你代码里的action.deployKey首尾有多余空格,也会破坏密钥格式。可以先做格式修复:
// 还原被转义的换行符,同时去掉首尾多余空格 const fixedDeployKey = action.deployKey.replace(/\\n/g, '\n').trim(); await createFile(`${ssh}/id_rsa`, fixedDeployKey, { encoding: 'utf8' });
3. 设置严格的文件权限
SSH对私钥文件的权限要求极高,必须是600(仅所有者可读可写),否则即使密钥格式正确,也会被判定无效。写入文件后一定要修改权限:
import { chmod } from 'fs'; const chmodFile = promisify(chmod); // 写入后立即设置权限为600 await chmodFile(`${ssh}/id_rsa`, 0o600);
4. 确保.ssh目录存在
虽然GitHub Runner默认会有~/.ssh目录,但保险起见可以先检查并创建:
import { mkdir } from 'fs'; const mkdirDir = promisify(mkdir); // 递归创建目录,防止不存在的情况 await mkdirDir(ssh, { recursive: true });
整合后的完整代码
import { isNullOrUndefined } from "./util"; import { promisify } from 'util'; import { writeFile, chmod, mkdir } from 'fs'; // 直接从环境变量获取密钥(替换你示例中的硬编码) const deployKey = process.env.action_deployKey; const sshDir = `${process.env.HOME}/.ssh`; const sshKeyPath = `${sshDir}/id_rsa`; // 封装工具函数 const createDir = promisify(mkdir); const writeKeyFile = promisify(writeFile); const setKeyPerms = promisify(chmod); // 1. 确保目录存在 await createDir(sshDir, { recursive: true }); // 2. 修复密钥格式 const fixedDeployKey = deployKey.replace(/\\n/g, '\n').trim(); // 3. 写入密钥并设置权限 await writeKeyFile(sshKeyPath, fixedDeployKey, { encoding: 'utf8' }); await setKeyPerms(sshKeyPath, 0o600);
最后补充个小提醒:在GitHub仓库Secrets里添加私钥时,直接粘贴完整的多行私钥即可,GitHub会自动处理换行符的存储,不需要手动添加转义字符。
内容的提问来源于stack exchange,提问作者James Ives
相关产品推荐
相关产品推荐

