资讯详情

资讯详情

SSH证书登录配置实操:关闭密码认证,彻底防暴力破解

一到年底各种勒索病毒、挖矿木马就像赶集一样集中爆发。我这边还没忙完日常巡检就被某个客户叫起来说服务器CPU飙到100%登录一看一堆来自海外的IP在疯狂尝试SSH密码日志里全是Failed password直接刷了几万条。说实话密码暴力破解这种事儿平时不痛不痒但一旦碰上弱口令、没做失败锁定被攻破只是时间问题。年底这个节点攻击者也是冲业绩的自动化脚本扫全网凡是暴露在公网的22端口几分钟内就会挨一轮爆破。这次我直接把客户的服务器从密码登录切换成了证书登录也就是SSH公钥认证。改完之后不只是这次的爆破被彻底挡住后续的暴力扫描基本也等于作废。这篇文章就把完整的切换思路、实操步骤和排查经验整理出来。无论是只有一台服务器的个人站长还是手里攥着十几台机器的小团队照着这套流程走一遍都能把SSH这扇门从“用钥匙就能捅开”升级成“必须刷卡才能进出”。1. 暴力破解为什么在年底格外凶猛1.1 年底攻击流量飙升的原因如果你在运维一线待过几年会发现一个规律每到11月到次年1月公网扫描和暴力破解的流量明显变多。这背后的逻辑其实很简单攻击者也是要冲KPI的。年底企业都在赶业务、发版、做促销活动云上资产普遍处于高变化状态新开的临时服务器、测试机、数据库公网入口都比平时多暴露面变大自然成为重点目标。另外年底同样是勒索病毒的高发时段。攻击者的套路往往是先用暴力破解拿下一台机器然后横向渗透部署勒索加密或者挖矿程序。你仔细看那些被勒索的案例就会发现很多最初的突破口都是SSH弱口令。所以暴力破解不只是“有人在试密码”这么简单它往往是一整套攻击链的第一步。我自己观察到的现象是年底的爆破流量目标非常明确主要集中在22端口、3389端口这类常见远程管理端口。扫描的IP段也很有规律很多来自云厂商的免费试用机器被黑掉之后沦为肉鸡批量跑字典。这意味着如果你用的是常见用户名root、admin密码又是弱口令被爆破成功基本只是时间问题根本不需要什么高超的技术手段纯靠概率就能撞开。暴力破解的工作原理与失守后的连锁反应暴力破解的本质就是反复尝试用户名和密码组合。攻击者手里通常有一份字典里面是几百万条常见密码和用户名组合通过自动化工具对目标IP进行高频尝试。单看每一次尝试成功率几乎为零但架不住量大。一个带宽充足、线程拉满的爆破脚本几分钟就能打出几万次请求只要你的密码出现在字典里总有被撞开的时候。有人会说我设置了密码失败锁定是不是就安全了这个思路可以缓解风险但要注意两点。第一很多发行版默认并没有开启锁定策略需要额外配置第二锁定策略本身也有副作用攻击者可以利用这个机制故意锁定你的账号制造拒绝服务。而且有些爆破工具会控制频率绕过低次数的锁定阈值。所以单纯依赖密码和锁定策略只是降低了被爆破的概率并没有从根本上解决问题。密码登录还有一个天然缺陷密码本身是可破解的、可猜测的而且服务器端存有密码的校验信息。一旦服务器被拖库密码哈希被拿走后还有被离线爆破的可能。而证书登录走的是非对称加密的密钥对验证攻击者如果想破解就需要拿到你的私钥文件这比猜一个密码的难度高了好几个数量级。这也是为什么在防御暴力破解的时候业界普遍推荐优先关闭密码登录、启用密钥认证。2. 证书登录到底是怎么运作的2.1 密钥对与公钥认证的逻辑拆解很多朋友一听到证书登录第一反应是“这不就是SSL证书吗”其实这里说的是SSH密钥认证也就是用一对密钥来完成身份验证。这对密钥由两个文件组成一个是私钥保留在你自己的电脑上绝对不能外传另一个是公钥可以随意分发需要放到服务器的授权文件里。登录的验证过程听起来玄乎实际上可以这么理解服务器手里有一份你的公钥客户端手里持有对应的私钥。当客户端发起登录请求时服务器会生成一个随机挑战用你的公钥加密后发给客户端。客户端用私钥解密成功再把结果反馈给服务器服务器确认通过后身份验证就完成了。整个过程私钥从不出现在网络上也不会被传输到服务器端。所以这里的两个文件就好比门锁和钥匙的关系服务器端的authorized_keys文件是一串锁芯客户端手里的私钥是唯一匹配的钥匙。攻击者不知道服务器里授权了哪些公钥也没有对应的私钥文件即使他喊破喉咙输入一万个密码也没用因为服务器压根不给他密码验证的机会。2.2 为什么密钥认证天然免疫暴力破解暴力破解的核心条件是“存在一个可尝试的验证通道”。在纯密码登录模式下任何人只要知道IP和用户名就可以连接服务器反复尝试密码。而密钥认证模式下验证通道使用的是加密挑战攻击者没有私钥就无法完成挑战。你无法通过“不断尝试”去猜一个4096位的随机私钥这比从银河系里找出一粒特定沙子还难。还有一层容易被忽略的防护优势关闭密码登录后攻击者发起的每一次密码爆破请求都会被服务器直接拒绝他连输入的入口都没有。这种拒绝不是“密码错了请重试”而是“拒绝算法协商”或“连接被关闭”。爆破工具会立刻判定该主机不可用转而扫描下一个目标。实测下来改完证书登录之后再看服务器日志爆破记录会骤减到接近于零效果立竿见影。3. 完整实操从密码登录平滑切换到证书登录3.1 第一步在本地生成安全的密钥对生成密钥对这一步发生在你的个人电脑上而不是服务器上。我强烈建议用当前最稳妥的ed25519算法它比老一代的RSA密钥更短、生成速度更快、安全性也不输。如果你手里有需要兼容老版本系统的场景再考虑用RSA 4096。以本地Linux或macOS终端为例执行命令ssh-keygen -t ed25519 -a 100 -C your_comment -f ~/.ssh/id_ed25519参数说明-t ed25519 指定算法类型-a 100 表示KDF迭代次数越高越难被暴力破解实测耗时会增加但依然可接受-C 是注释一般写自己的邮箱或机器名方便管理多把钥匙-f 指定生成路径和文件名执行过程会提示你设置passphrase也就是私钥本身的使用口令。这一步很多人会直接回车跳过我不建议这样因为私钥文件一旦被窃取对方拿到就是完全控制权。设置一个passphrase之后即使私钥文件泄露攻击者也不会立刻得手。缺点是每次登录需要输入一次passphrase换来的是更高的安全性值。生成完成后本地会出现两个文件id_ed25519是私钥id_ed25519.pub是公钥。平时备份和分发只需要关心公钥私钥用chmod 600保护起来权限必须是仅本人可读。3.2 第二步把公钥安装到服务器授权列表拿到公钥之后需要把它追加到服务器上对应用户的~/.ssh/authorized_keys文件里。如果你只有一两台服务器用ssh-copy-id最省事ssh-copy-id -i ~/.ssh/id_ed25519.pub userserver_ip这个命令会自动连接服务器使用你输入的密码完成登录然后把公钥追加到authorized_keys里并且自动设置好目录和文件的权限。对新手来说ssh-copy-id能帮你避免很多权限相关的坑。如果手边没有ssh-copy-id也可以手动操作。执行cat ~/.ssh/id_ed25519.pub | ssh userserver_ip mkdir -p ~/.ssh chmod 700 ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys这条命令会在服务器上创建.ssh目录、设置700权限、把公钥追加到authorized_keys再把这个关键文件权限收紧到600。这一步里的权限不能马虎如果authorized_keys的权限过于宽松sshd出于安全考虑会拒绝读取这个文件导致登录失败。安装完之后先在当前终端保持原连接不要断开另开一个新窗口测试密钥登录ssh -i ~/.ssh/id_ed25519 userserver_ip如果不需要指定私钥文件因为默认路径就是~/.ssh/id_ed25519直接ssh userserver_ip即可。能登录成功说明公钥已经生效。3.3 第三步调整服务端关键配置密钥验证跑通之后才是真正的加固环节。编辑服务器的SSH配置文件不同发行版路径略有不同常见的是/etc/ssh/sshd_config。先备份原文件养成好习惯cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak然后修改以下配置项PermitRootLogin prohibit-password PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM no X11Forwarding no逐项解释一下为什么这么设PermitRootLogin prohibit-password允许root使用密钥登录但不允许密码登录。这样即使你用root账户管理机器安全性也有保障。PasswordAuthentication no直接关闭密码验证这是防暴力破解的关键开关。ChallengeResponseAuthentication no关闭密文挑战响应认证避免某些PAM模块重新打开密码验证通道。UsePAM no关闭PAM的登录认证防止PAM配置里残留密码验证逻辑。X11Forwarding no非必要建议关闭减少图形转发相关的攻击面。改完之后先做语法检查确认配置没有写错sshd -t如果命令没有任何输出说明配置语法正确。然后平滑重载服务systemctl reload sshd注意reload不会断开已有的SSH连接新的连接会使用新配置。这一步建议保持在同一个会话里完成避免误操作把自己锁在门外。重载之后再用密钥登录的方式重新建立一个新会话确认还能连上。此时再尝试用密码登录应该会被直接拒绝日志里会显示类似“Permission denied (publickey)”的信息说明密码通道已经被彻底关闭。3.4 第四步最后关闭密码登录前的确认与兜底关闭密码登录是这次加固里风险最高的一步。操作不当很容易出现“密钥不好使密码又关了彻底进不去”的尴尬局面。我的做法是严格执行三条底线第一所有配置修改前备份配置文件并记录原始内容方便回滚。第二至少保持一个已登录的会话不要关闭作为“生命线”。第三在正式关闭PasswordAuthentication之前先在不重启服务的情况下验证密钥登录确保万无一失。如果你用的是云服务器还要提前把自助VNC控制台或救援模式的方法弄清楚。一旦真的被锁在外面还能通过云厂商的网页终端进去改配置。个人开发者的机器尤其要留意没有带外管理的话被锁基本上只能重装系统了。4. 多台服务器的批量部署与密钥日常管理4.1 几十台机器如何快速批量下发公钥如果你管理的不止一台服务器逐台手工执行ssh-copy-id会非常痛苦。我这里的做法是写一个简单循环脚本把需要下发的公钥和服务器列表准备好一次性搞定。假设服务器列表存在servers.txt里每行一个IP或域名可以这么写while read -r host; do ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy$host done servers.txt这个脚本会依次提示输入每台服务器的密码适合密码还不统一的过渡阶段。如果服务器密码已经统一管理可以结合sshpass半自动化但要注意sshpass会把密码暴露给进程列表生产环境慎用。批量操作之后记得抽查几台机器确认密钥登录正常再统一关闭密码登录。对于新服务器上线我建议把下发公钥整合到初始化脚本里而不是每次都手动操作。比如在系统初始化阶段就写入authorized_keys配合配置管理工具统一执行。这样既减少人工操作的失误也保证所有机器最终状态一致。4.2 密钥文件的分级管理与轮换思路当服务器数量变多后密钥管理就成了新的问题。一把私钥通配所有机器看起来方便但风险也集中了。一旦某台机器被入侵攻击者可能捞到你留在服务器上的私钥副本进而横向渗透到其他机器。更稳妥的做法是分级管理普通业务账号用一把密钥管理账号用另一把更高强度的密钥并通过服务器的AllowUsers或Match配置限制不同用户可登录的IP来源。日常开发和测试机器的密钥可以放宽生产环境的密钥必须单独生成不混用。密钥轮换也是老生常谈但最容易忽略的事项。员工的电脑离职、被植入了恶意软件或者私钥曾经被传到过不安全的场合都应该立即更换密钥对。操作流程是生成新密钥对、下发新公钥、验证登录、从授权列表移除旧公钥。注意不要在移除旧公钥前就关掉旧密钥的权限要等新密钥全部生效后再收尾和切换密码登录的顺序是一个道理。5. 切换过程中的高频问题与排查实录5.1 密钥验证成功但登录仍被拒绝这是改完配置之后最常见的问题公钥已经放进authorized_keys密钥登录却一直提示Permission denied。排查顺序我一般是这样第一步查看服务器端日志通常要查/var/log/auth.log或/var/log/secure。重点看最后几行有没有类似“Authentication refused: bad ownership or modes”的报错。如果有说明.ssh目录、authorized_keys文件权限不对。正确要求是~/.ssh目录必须是700authorized_keys文件必须是600并且这两个文件的属主必须是你登录的用户不能是root或者其他人。这个问题在复制公钥、解压备份、用root分发文件时特别容易犯。第二步如果权限正确检查sshd的配置文件是否显式指定了AuthorizedKeysFile路径。有些发行版默认指向/ etc/ssh/authorized_keys或其它路径如果你把公钥放到了用户目录就匹配不上。可以临时在sshd_config里加一行调试输出或者用ssh -vvv观察详细协商过程。第三步确认SELinux或者AppArmor没有拦截sshd读取用户目录。如果系统开了强制模式可能需要执行restorecon -R -v ~/.ssh来重置安全上下文。这一项常被忽略一旦中招日志里看不到权限错误但就是登录不上。5.2 关闭密码登录后自己也进不去了这种翻车场景我见过不止一次多半是配置语法检查漏了、密钥装错了机器、或者修改配置时把PubkeyAuthentication误关掉了。处理办法分两种情况如果你还有云厂商的VNC网页终端直接进入服务器把备份配置恢复回来就行。如果没有带外终端只能通过救援模式挂载磁盘修改配置或者干脆重装代价会大很多。所以我反复强调的“操作前保留旧会话备份配置先测密钥”这套流程一定要执行到位。特别是reload和restart的区别reload平滑应用新配置不会断掉现有连接restart会重新启动sshd进程如果你当前连接是通过sshd承载的在极少数情况下可能被断开。对生产环境来说优先使用reload。5.3 其他容易被忽略的实战细节问为什么生成的密钥登录还要输入passphrase好麻烦。 答passphrase不是每次都要输可以用ssh-agent把私钥加载到内存中。登录当前桌面会话时执行eval $(ssh-agent -s) ssh-add ~/.ssh/id_ed25519之后在这个会话里连接服务器就不再要求输入passphrase了。但要注意ssh-agent只在当前会话中有效重启后就失效需要重新添加。这属于便捷性和安全性的折中我个人的建议是日常开发机器开启生产环境保持每次都输passphrase。问移动端或云服务器的网页终端没有私钥文件怎么办。 答可以把本地公钥先手动粘贴进去但不要直接从服务器导出私钥这样会破坏整个信任模型。更合理的做法是在本地管理好密钥导入到云厂商的密钥管理服务或者用支持密钥认证的SSH客户端连接。问Windows下怎么操作。 答Windows 10以上版本自带OpenSSH客户端生成密钥和上传公钥的方式跟Linux基本一致只是路径在C:\Users\你的用户名.ssh\。如果没有ssh-copy-id用PowerShell执行类型命令也可以或者手动用记事本把公钥内容追加到服务器。不过我还是推荐用Xshell这类工具它的图形界面在密钥生成和代理管理上更直观适合新手。最后再说几句把服务器从密码登录改成证书登录本质上不是增加麻烦而是把安全成本前置。前期生成密钥、下发公钥、修改配置看似多花了一些时间但之后每次登录都更安全也不用再隔三差五盯着日志看谁在爆破自己。我在实际使用中最大的感受是关闭密码登录那一瞬间服务器日志一下子干净了这种“整个世界安静了”的体验是很有成就感的。如果你手里有老系统、老程序还在依赖密码自动登录也没关系可以分阶段来先保证新的运维入口全部用密钥再把一些自动任务逐步改造成密钥方式。还有一个小技巧建议把authorized_keys里的公钥都加上注释标记来源比如哪位同事、哪台电脑、什么时候加的这样后续清理旧key时会轻松很多。希望这篇分享能让你少踩几个坑祝每台服务器都能安稳过冬。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →