服务器被黑这件事,八成是从SSH端口开始的。打开/var/log/auth.log看一眼,满屏都是暴力破解的失败记录——从凌晨到半夜,脚本在不停地试密码。如果你的服务器只靠密码保护,相当于把门锁换成了一条细绳。
这个问题的答案其实很清楚:生产环境和公网可访问的服务器,必须用SSH密钥认证并关闭密码登录。只在物理隔离的内网、个人实验环境等特殊场景下,密码登录才勉强可用。下面把两种方式的优劣对比和配置流程讲清楚。
先看本质区别:怎么证明“你是你”
密码登录:你把一串秘密(密码)通过网络发给服务器,服务器验证这串秘密对不对。在这个过程中,密码是在网络中传输的。虽然OpenSSH对密码做了加密,但本质上每次登录都在传递同一个秘密。更致命的是,脚本可以在几秒内发送上万次尝试——这就是暴力破解的根基。
密钥认证:你生成一对数学上配对的密钥——公钥放在服务器上,私钥留在自己电脑里。登录时,服务器用公钥生成一个随机挑战,只有你手里的私钥能算出正确的响应。私钥永远不出现在网络中,只做本地计算。攻击者想通过密钥登录,必须拿到你的私钥文件,这比猜密码难了几个数量级。
数据说话了:哪个更安全
生产环境的数据最有说服力。有运维人员在云平台管理了成百上千台虚拟机,统计出的结论是:所有因为SSH被入侵的安全事件,根本原因都是用户主动把默认的密钥认证改成了密码认证。而使用密钥认证的机器,即使私钥文件没有额外加密(比如生成时没设passphrase),也没有出现过一例因SSH被入侵导致的安全事故。
这个结论跟行业共识完全吻合——密码登录最大的风险来自自动化暴力破解工具,它们每秒可以尝试成千上万个密码组合。
但是:密钥也不是绝对免死金牌
密钥认证确实更安全,但前提是你把私钥管好。最典型的两个风险场景:
场景一:私钥文件被偷
如果你把私钥文件(比如id_ed25519)放在电脑桌面上没有任何保护,别人拿到这个文件就能用你的身份登录所有服务器。所以生成密钥的时候一定要设passphrase——相当于给私钥再加一把锁。即使文件被偷,没有passphrase也用不了。
场景二:ssh-agent使用不当
很多人会把密钥加到ssh-agent里省去输入passphrase的麻烦。但如果你离开工位时没锁屏,攻击者可以直接用已经加载了密钥的ssh-agent访问你的所有服务器。解决办法:在ssh-agent里设置短时效(比如几分钟后自动过期),或者养成随手锁屏的习惯。
一个关键误区:密钥本身安全,不等于你的登录行为安全
有人会问:如果我设的passphrase跟密码一样简单,那跟密码登录有什么区别?
区别在于攻击面。密码登录时,攻击者直接对着公网服务器暴力破解,几秒钟就能试上千次。密钥登录时,攻击者必须先拿到你的私钥文件,然后还要猜passphrase。前者是远程攻击,后者是本地攻击——门槛差着数量级。
另一个角度:密码是可猜测的,而私钥是数学上生成的随机串。即使是40位的复杂密码,其熵值也远低于2048位RSA密钥或256位Ed25519密钥。
怎么配置密钥认证:三步走
第一步:生成本地密钥对
在自己电脑上执行(Windows用WSL或Git Bash):
ssh-keygen -t ed25519 -C "你的邮箱"
-t ed25519是目前最推荐的算法,比RSA更快更安全。如果系统太老不支持Ed25519,可以用ssh-keygen -t rsa -b 4096。
系统会问你保存位置(默认回车就行)和passphrase——强烈建议设一个,不然私钥文件就是裸奔的。
第二步:把公钥拷到服务器
最省事的方法是用ssh-copy-id:
ssh-copy-id root@你的服务器IP
输入一次密码,公钥就自动添加到服务器的~/.ssh/authorized_keys里了。
没有ssh-copy-id的话,手动把~/.ssh/id_ed25519.pub的内容追加到服务器的~/.ssh/authorized_keys文件里也行。
第三步:测试通过后,禁用密码登录
先用密钥登录一遍确认能通,然后编辑服务器的/etc/ssh/sshd_config:
PasswordAuthentication no
重启SSH服务:
systemctl restart sshd
从此只有持有你私钥的人才能登录。
什么情况下可以保留密码登录?
内网环境:如果你的SSH端口不对公网开放,密码登录的风险被大幅降低。有观点认为,物理隔离或内网环境下的密码登录和密钥认证安全性差异不大,因为攻击者无法从公网发起暴力破解。
个人实验环境:一台只在自己家路由器后面、不对外暴露端口的树莓派,用密码登录问题不大。但任何暴露在公网22端口的服务器,都必须用密钥认证并关闭密码登录。这是没有商量余地的底线。
一句话结论:公网服务器永远用密钥认证,密码登录只配留在内网实验环境里。
推荐文章