Windows环境下如何向外部SSH命令传入密钥口令?
问题原因及解决方案
核心问题
Windows自带的OpenSSH客户端在请求私钥口令时,直接与终端(TTY)交互,而非读取标准输入(stdin)。你通过Symfony Process的InputStream写入的内容,ssh根本不会接收,所以才会出现进程卡住、无输出的情况。
可行解决方案
1. 使用ssh-agent管理密钥(推荐,安全且便捷)
Windows自带OpenSSH Authentication Agent服务,只需一次性输入私钥口令,后续所有ssh连接都会自动复用密钥,无需重复输入:
- 启动服务:按下Win+R输入
services.msc,找到「OpenSSH Authentication Agent」并设置为自动启动,启动服务。 - 在命令行添加私钥:
ssh-add C:\Users\MYUSERNAMEHERE\.ssh\id_rsa-redacted - 之后你的PHP脚本无需处理口令,直接运行原ssh命令即可:
$process = new Process('ssh connectionnamehere ls -Al'); $process->run(); var_dump( $process->isSuccessful(), $process->getExitCode(), $process->getOutput() );
2. 用plink替代原生ssh(适用于必须传口令的场景)
Putty的命令行工具plink支持通过参数或标准输入传递私钥口令,Windows下可单独安装Putty套件获取:
- 直接通过参数传递口令(注意:硬编码口令有安全风险,建议用环境变量替代):
$process = new Process('plink connectionnamehere -pw MYSSHPASSWORDHERE ls -Al'); $process->run(); var_dump($process->getOutput(), $process->getErrorOutput());
3. 使用无口令私钥(仅测试环境可用)
生成不带口令的私钥对替换现有密钥,这样ssh连接无需输入口令,但私钥一旦泄露,任何人都能访问你的服务器,生产环境绝对禁止使用:
ssh-keygen -t rsa -N "" -f C:\Users\MYUSERNAMEHERE\.ssh\id_rsa-new
对当前代码的说明
你当前的代码存在两个问题:
- 启动进程后立刻写入输入并关闭,但此时ssh可能还未完成初始化,没准备好接收输入。
- 最关键的是,ssh的口令请求不读取stdin,所以无论怎么写输入流都无效,进程会一直等待终端的手动输入,导致退出码为
null(进程未结束)。
内容的提问来源于stack exchange,提问作者Álvaro González
相关产品推荐
相关产品推荐

