第一次看到SSH密钥登录报"bad permissions"错误时,我也是一头雾水。明明密钥文件存在,密码也没输错,怎么就登录不了呢?后来才发现,这其实是SSH对密钥文件权限的严格检查机制在起作用。简单来说,就是你的私钥文件权限太宽松了,SSH认为这样不安全,所以拒绝使用这个密钥。
典型的错误提示长这样:
bash复制Permissions 0644 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/root/.ssh/id_rsa": bad permissions
这种情况特别容易发生在跨平台操作时,比如从Windows电脑把密钥文件上传到Linux服务器。Windows和Linux的权限系统完全不同,文件上传后权限往往会出问题。我去年就遇到过三次类似情况,都是团队里新来的开发同事从Windows上传密钥导致的。
SSH协议从设计之初就把安全性放在首位。想象一下,你的私钥就像家门钥匙 - 你会随便把钥匙给别人吗?当然不会!SSH也是这么想的。如果私钥文件可以被其他用户读取,就相当于把钥匙放在门口的地毯下,任何人都能拿走。
具体来说,SSH要求:
我见过不少人为图省事,直接给密钥文件777权限(所有人可读可写可执行)。这相当于把银行账户密码贴在办公室墙上!一旦私钥泄露:
去年某公司数据泄露事件,就是因为开发人员把密钥文件权限设成了644,导致黑客轻易获取了服务器权限。
首先,我们需要查看.ssh目录和密钥文件的当前权限:
bash复制ls -ld ~/.ssh
ls -l ~/.ssh/id_rsa
正常应该看到类似这样的输出:
bash复制drwx------ 2 user user 4096 Jan 1 12:00 /home/user/.ssh
-rw------- 1 user user 1679 Jan 1 12:00 /home/user/.ssh/id_rsa
如果权限不对,比如看到-rw-r--r--(644)或者更宽松的权限,就需要修复了。
bash复制chmod 700 ~/.ssh
bash复制chmod 600 ~/.ssh/id_rsa
虽然不严格要求,但最好也设置合适的权限:
bash复制chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/known_hosts
chmod 644 ~/.ssh/authorized_keys
重新尝试SSH登录:
bash复制ssh -i ~/.ssh/id_rsa user@remote-server
如果还是不行,可以加上-v参数查看详细日志:
bash复制ssh -v -i ~/.ssh/id_rsa user@remote-server
这是最容易出问题的场景。我建议:
bash复制scp -p id_rsa user@remote-server:~/.ssh/
bash复制rsync -avz -e ssh id_rsa user@remote-server:~/.ssh/
有时候,即使你设置了正确权限,登录时还是报错。这可能是因为:
bash复制ls -Z ~/.ssh/id_rsa
如果显示异常,可以恢复默认上下文:
bash复制restorecon -Rv ~/.ssh
为了避免频繁输入密码,同时保持安全性,可以使用ssh-agent:
bash复制eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
这样密钥会保存在内存中,比放在磁盘上更安全。
有时候问题可能出在SSH客户端配置上。检查/etc/ssh/ssh_config或~/.ssh/config中是否有影响权限检查的配置:
bash复制StrictModes no # 不推荐关闭,这会降低安全性
如果问题依旧,查看系统日志:
bash复制journalctl -u sshd -f
或者
bash复制tail -f /var/log/auth.log
我通常在~/.bashrc中添加以下函数,方便快速修复权限:
bash复制fixsshperms() {
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/known_hosts
chmod 644 ~/.ssh/authorized_keys
echo "SSH permissions fixed"
}
如果是多台服务器,可以用ansible playbook:
yaml复制- hosts: all
tasks:
- name: Fix .ssh directory permissions
file:
path: ~/.ssh
mode: '0700'
- name: Fix private key permissions
file:
path: ~/.ssh/id_rsa
mode: '0600'
记住,SSH密钥是你服务器的第一道防线。保持密钥文件权限正确是最基本的安全措施。每次传输密钥后都检查权限,养成这个习惯能避免很多麻烦。