基于OCI自定义镜像创建计算实例后SSH连接报permission denied求助
OCI自定义镜像SSH登录Permission Denied问题解决方案
根因定位
你遇到的偶发可登录、重启后必失败的现象,核心是sshd的StrictModes校验被触发:默认sshd开启StrictModes配置,会严格校验用户家目录、.ssh目录、authorized_keys文件的权限和属主,只要权限过松(比如其他用户有读写权限)就会直接拒绝公钥认证,返回permission denied,具体触发原因通常为以下两类:
- 自定义业务镜像内置了安全加固类开机脚本/服务,启动后会自动修改.ssh目录或authorized_keys文件的权限为不符合要求的值(比如将authorized_keys权限改为644、修改文件属主为root等)
- 镜像残留的旧cloud-init缓存导致公钥写入时的权限设置异常,或镜像中的cloud-init ssh模块被修改,没有正确设置对应权限
验证步骤
- 使用同事的密钥登录异常实例,依次执行以下命令检查权限配置:
- 检查ubuntu用户家目录权限:
ls -ld /home/ubuntu,正常应为755权限,属主ubuntu:ubuntu - 检查.ssh目录权限:
ls -ld /home/ubuntu/.ssh,正常必须为700权限,属主ubuntu:ubuntu - 检查密钥文件权限:
ls -l /home/ubuntu/.ssh/authorized_keys,正常必须为600权限,属主ubuntu:ubuntu - 检查是否存在额外ACL权限:
getfacl /home/ubuntu/.ssh/authorized_keys,如果存在除ubuntu外其他用户的权限规则,也会触发校验拦截
- 检查ubuntu用户家目录权限:
- 检查sshd配置:
grep -E 'StrictModes|AuthorizedKeysFile' /etc/ssh/sshd_config,确认StrictModes为开启状态,AuthorizedKeysFile路径为默认的.ssh/authorized_keys - 检查开机执行逻辑:遍历
/etc/rc.local、/etc/profile.d/目录下的脚本、/etc/systemd/system/下的自定义服务,定位是否有修改.ssh目录权限的逻辑 - 本地开启debug模式连接确认错误类型:执行
ssh -v ubuntu@instance_public_IP,如果日志中Offering public key后直接返回permission denied,即可确认是sshd权限校验拦截导致
解决方案
- 修复镜像内置权限逻辑:找到镜像中修改.ssh目录权限的开机脚本,删除对应逻辑,或调整脚本中设置的权限为700(.ssh目录)、600(authorized_keys文件),确保符合sshd要求
- 通过cloud-init用户数据覆盖权限(无需修改原始镜像):在创建实例的metadata中新增user_data配置,在所有开机脚本执行完成后修正权限,Terraform配置示例如下:
metadata = { ssh_authorized_keys = file(var.ssh_public_key_path) user_data = base64encode(<<-EOF #cloud-config runcmd: - chown -R ubuntu:ubuntu /home/ubuntu/.ssh - chmod 700 /home/ubuntu/.ssh - chmod 600 /home/ubuntu/.ssh/authorized_keys - systemctl restart sshd EOF ) } - 清理镜像cloud-init缓存:制作自定义镜像前,先在源实例执行
cloud-init clean --logs清除残留的cloud-init状态,避免新实例初始化时执行异常 - 适配非标准sshd配置:如果镜像中的sshd修改了AuthorizedKeysFile的默认路径,将公钥写入配置指定的路径即可
内容的提问来源于stack exchange,提问作者Maciej Zwoliński
相关产品推荐
相关产品推荐

