如何在PHP中通过SSH在另一台服务器执行CLI命令?
在PHP中通过SSH执行远程服务器CLI命令的解决方案
当然可行!你遇到的问题核心原因是PHP运行用户和你本地命令行用户的权限/SSH认证环境不一致——PHP通常以www-data(Apache/Nginx的运行用户)身份执行,而你手动用命令行登录的是自己的用户,两者的SSH密钥配置是分开的,所以直接在exec里跑ssh命令会因为认证失败卡壳。
下面是一步步的解决办法:
1. 先确认PHP的运行用户
先创建一个测试PHP文件,执行以下代码:
<?php echo exec('whoami'); ?>
访问这个文件,你会看到PHP当前的运行用户(一般是www-data,也可能是apache、nginx之类的),记下来这个用户名。
2. 给PHP运行用户配置SSH免密登录
因为PHP执行时没法手动输入SSH密码,所以必须配置免密登录:
- 切换到PHP运行用户:
sudo su - www-data # 把www-data换成你刚才查到的用户名 - 生成SSH密钥对(一路回车,不要设置密码):
ssh-keygen -t rsa - 将公钥复制到目标服务器(执行时需要手动输入目标服务器的登录密码一次):
ssh-copy-id my.otherserver.com - 测试免密登录是否成功:在当前用户下执行
ssh my.otherserver.com "date"
如果能正常返回目标服务器的时间,说明免密配置成功了。
3. 回到PHP代码测试
现在再执行你的PHP代码:
<?php // 可以用第二个参数获取完整输出 exec('ssh my.otherserver.com "date"', $output); var_dump($output); ?>
这时候应该就能正常拿到远程服务器的执行结果了。
额外注意事项
- 如果目标服务器的SSH端口不是默认的22,需要在命令里指定端口:
exec('ssh -p 2222 my.otherserver.com "date"', $output); - 确保目标服务器上的
~/.ssh/authorized_keys文件权限是600,~/.ssh目录权限是700,否则SSH会拒绝认证。 - 如果你不想给PHP运行用户单独生成密钥,也可以在命令里指定自定义密钥文件(要确保密钥文件权限是
600且PHP用户能读取):exec('ssh -i /path/to/your/private/key my.otherserver.com "date"', $output); - 备选方案:如果需要更复杂的SSH操作,可以使用PHP的第三方库比如
phpseclib,它不需要依赖系统SSH命令,纯PHP实现,灵活性更高,但需要额外安装。
内容的提问来源于stack exchange,提问作者sdexp
相关产品推荐
相关产品推荐

