升级Debian12与PHP8.2后PHP的ssh2_auth_pubkey_file认证失败
解决Debian 12 + PHP 8.2下ssh2_auth_pubkey_file公钥认证失败问题
以下是针对问题的具体排查和解决步骤:
1. 严格检查密钥文件及目录权限
SSH对公钥/私钥的权限要求非常严格,即使PHP能读取文件,权限不符合要求也会导致认证失败:
- 设置私钥权限为600:
chmod 600 /root/.ssh/id_rsa - 设置公钥权限为644:
chmod 644 /root/.ssh/id_rsa.pub - 设置.ssh目录权限为700:
chmod 700 /root/.ssh - 确认所有文件/目录归属root用户组:
chown -R root:root /root/.ssh
2. 显式指定公钥文件路径
PHP的ssh2_auth_pubkey_file函数有时无法自动从私钥关联公钥,需要显式传入公钥路径参数。修正代码示例:
$host = 'remote-server.com'; $user = 'root'; $pubKeyPath = '/root/.ssh/id_rsa.pub'; $privKeyPath = '/root/.ssh/id_rsa'; $connection = ssh2_connect($host, 22); if (!$connection) { die("无法连接远程服务器"); } // 显式传入公钥、私钥路径,空字符串表示无密码 if (ssh2_auth_pubkey_file($connection, $user, $pubKeyPath, $privKeyPath, '')) { echo "认证成功"; } else { die("认证失败"); }
3. 转换密钥为PEM格式(兼容PHP ssh2扩展)
Debian 12的PHP 8.2 ssh2扩展对OpenSSH原生格式密钥的兼容性可能存在问题,直接转换现有密钥格式:
- 转换私钥为PEM格式:
ssh-keygen -p -m PEM -f /root/.ssh/id_rsa(执行后按提示回车,无需修改密码) - 转换公钥为PEM格式:
ssh-keygen -f /root/.ssh/id_rsa.pub -e -m PEM > /root/.ssh/id_rsa_pem.pub - 之后在PHP代码中使用转换后的PEM格式公钥路径
4. 检查远程服务器SSH配置
如果远程服务器的sshd禁用了ssh-rsa算法,会导致认证失败:
- 登录远程服务器,编辑
/etc/ssh/sshd_config,添加或修改:PubkeyAcceptedAlgorithms +ssh-rsa - 重启sshd服务:
systemctl restart sshd - 查看远程服务器的认证日志(
/var/log/auth.log),搜索认证失败记录,获取具体错误原因(比如是否存在密钥格式不支持、用户权限限制等)
5. 排查PHP运行环境的限制
- 检查系统是否启用了AppArmor或SELinux,这些安全模块可能限制PHP访问密钥文件:
- 临时关闭AppArmor测试:
systemctl stop apparmor,如果认证成功,需要调整AppArmor规则允许PHP访问密钥路径
- 临时关闭AppArmor测试:
- 确认PHP定时任务的环境变量与root命令行一致,比如
HOME变量是否正确指向/root,避免ssh2扩展找不到默认的.ssh目录
内容的提问来源于stack exchange,提问作者clarkk
相关产品推荐
相关产品推荐

