ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SSH弱加密算法修复实战:从原理到配置的完整指南

SSH弱加密算法修复实战:从原理到配置的完整指南 1. SSH服务原理与常见攻击手段先搞清楚要修什么前两天帮客户做等保整改安全扫描报告上赫然列着一条SSH服务支持弱加密算法。这条在等保2.0里几乎是必查项我经手过的项目十个里有八个中招。很多第一次碰到这个问题的同事会发懵觉得SSH本身就是加密连接怎么还会分强算法弱算法其实SSH从建立连接到传输数据涉及密钥交换、对称加密、完整性校验、主机认证四类算法任何一类用的是老弱算法整个通道的安全强度就会被拉到木桶最短那块板上。这篇文章就把这个问题掰开揉碎从协议原理和攻击手段讲起再到完整修复流程、常见踩坑和回滚预案照着操作就行。1.1 SSH协议握手与算法协商机制SSH连接建立的核心是“算法协商”。客户端发起连接后双方先交换版本号然后各自发送一条KEXINIT消息里面列出了自己支持的所有算法清单包括密钥交换算法、主机密钥类型、对称加密算法、MAC完整性算法。服务端收到后会取两边清单的交集按优先级选择第一个双方都支持的算法组合然后才进入密钥交换和用户认证阶段。这个过程可以类比成两个公司开会定加密方案甲方说我能用AES和DES乙方也说我能用AES和DES为了“兼容”双方顺手选了DES那后面所有传输内容的安全强度就只剩DES级别了。SSH也一样只要服务端配置里保留了弱算法哪怕客户端支持更强的新算法攻击者也有机会在握手时诱导双方降级到那个最弱的组合上。理解这一点就明白为什么“支持弱算法”不是小问题——它相当于给别人留了一把后门钥匙虽然平时用不上但关键时刻真能打开门。1.2 常见攻击手段攻击者如何利用弱算法针对SSH的攻击手段里和算法问题直接相关的有几个典型方向。第一是暴力破解和弱口令这类攻击靠的是弱密码跟加密算法关系不大但很多人在加固时容易漏掉“密码策略登录限速”的配套措施。第二是中间人攻击攻击者站在客户端和服务端之间在算法协商阶段篡改KEXINIT消息强制双方使用它指定的弱算法然后再破解会话密钥或直接监听内容。第三是利用特定算法的已知漏洞比如CBC模式的比特翻转攻击、RC4的统计偏差问题这些漏洞都建立在“服务端还在支持这类算法”的基础上。最近还有一个绕不开的案例就是2023年底公开的Terrapin攻击编号CVE-2023-48795。攻击者通过中断TCP连接改变SSH握手过程中的序列号实现前缀截断进而移除安全通道中的部分协议消息达到降级或者干扰连接的目的。受影响的算法包括CBC模式下未启用Encrypt-then-MAC的组合以及ChaCha20-Poly1305OpenSSH 9.6之后的版本通过引入strict key exchange机制修复。这个案例告诉我们SSH加固不能只看老问题算法协商、完整性保护、版本升级是一整套事。2. 弱加密算法隐患解析与修复思路设计2.1 哪些算法算“弱”弱在哪安全扫描报告里常出现的弱算法主要集中在四类对称加密算法Ciphers、密钥交换算法KexAlgorithms、MAC完整性算法MACs、主机密钥类型HostKeyAlgorithms。我整理了一个速查表方便对照手里的扫描报告。类别典型弱算法主要风险对称加密arcfour/RC4、aes128-cbc、aes256-cbc、3des-cbc、blowfish-cbcRC4存在统计偏差可恢复明文CBC模式易受比特翻转和CPNI-957037明文恢复攻击密钥交换diffie-hellman-group1-sha1、diffie-hellman-group14-sha1、group-exchange-sha11024位DH参数受Logjam攻击影响SHA-1哈希强度不足MAC算法hmac-md5、hmac-md5-96、hmac-sha1MD5/SHA-1的碰撞攻击复杂度已大幅下降完整性校验强度不够主机密钥ssh-dss(DSA)、1024位RSA主机密钥DSA签名依赖随机数kk可预测会直接泄露私钥密钥长度不足拿CBC模式来说早在2008年就有研究者公布了针对SSH的CPNI-957037攻击攻击者能够从约2的32次方个密文块中恢复出32字节的明文。听着好像要求很高但对于攻击者来说这些成本完全可控不能因为它“难利用”就不修。RC4更不用说RFC 7465已经明确禁止在TLS里使用在SSH里同样不推荐。2.2 修复思路算法白名单、密钥轮换、版本升级三步走修复弱加密算法核心思路不是“把报告里显示fail的算法删掉”这么简单而是把四类算法都改成现代安全强度的白名单同时重建主机密钥、评估OpenSSH版本是否需要升级。我习惯把这项工作拆成三步。第一步是算法策略整改。修改/etc/ssh/sshd_config里的Ciphers、KexAlgorithms、MACs三个指令从默认的全量算法列表改成白名单模式。第二步是主机密钥轮换。删除DSA、低长度RSA等弱主机密钥生成并启用ed25519密钥这是目前推荐度最高、性能和安全性都更好的选择。第三步是版本升级评估。如果你的OpenSSH版本低于9.6建议排期升级因为Terrapin等新攻击需要靠版本更新来彻底收敛而且新版OpenSSH对旧算法的默认配置也更严格。这三步为什么必须一起做因为算法白名单管的是“会话加密用哪种算法”主机密钥管的是“服务端身份用什么证明”版本升级管的是“协议层自身有没有漏洞”。只改配置不换密钥老密钥的弱强度会一直留在服务器上只换密钥不升版本Terrapin这类协议层攻击照样能打穿。它们解决的是不同层面的问题但最终的目标一致——让SSH从握手到传输都走可信路径。3. 完整修复操作流程从扫描到上线一次搞定3.1 第一步基线扫描与影响面评估动手改配置之前先摸清现状。我会先看版本运行ssh -V确认OpenSSH版本接着用ssh-audit工具扫描本机所有算法支持情况这是目前最顺手的SSH安全审计工具。ssh -V ssh-audit localhostssh-audit输出会逐项列出版本信息、算法列表并用[fail]、[warn]、[info]标注风险等级。比如输出里有(cip) aes128-cbc -- [fail] using weak cipher mode这行就是标准结论。如果你看不了ssh-audit的完整输出nmap --script ssh2-enum-algos也能枚举出目标22端口所有支持的算法适合批量巡检多台机器。nmap -Pn -p 22 --script ssh2-enum-algos 192.168.1.10拿到算法清单后还有个重要工作确认现有客户端兼容性。去日志里翻一翻看平时都有哪些IP和客户端版本连上过这台机器做到心里有数。grep Accepted /var/log/secure | awk {print $9} | sort | uniq -c | sort -rn这一步千万不能省。很多加固翻车不是算法配得不对而是没搞清楚“网上还有哪些老客户端在连这台机器”。你这边把CBC全关了那边一台工业交换机、一套老版本自动化平台直接连不上业务就停了。3.2 第二步修改sshd_config启用安全算法白名单修改前先备份配置文件这是所有生产操作的前提。备份文件名带日期方便回滚时找。cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %F)然后在配置文件末尾追加以下三个指令。先给一份兼容性较好的标准安全配置适合大多数业务场景。# /etc/ssh/sshd_config 追加内容 Ciphers aes256-gcmopenssh.com,aes128-gcmopenssh.com,aes256-ctr,aes192-ctr,aes128-ctr KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256 MACs hmac-sha2-256-etmopenssh.com,hmac-sha2-512-etmopenssh.com,umac-128-etmopenssh.com,hmac-sha2-256,hmac-sha2-512如果业务环境要求比较严比如金融、政务类项目可以上更严格的配置只保留GCM和Curve25519这类现代算法。# 严格安全配置示例 Ciphers aes256-gcmopenssh.com,aes128-gcmopenssh.com KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,diffie-hellman-group16-sha512 MACs hmac-sha2-256-etmopenssh.com,hmac-sha2-512-etmopenssh.com配置完成后先做语法检查语法有问题直接修不要跳过。sshd -tsshd -t没有任何输出说明语法没问题如果输出了错误信息比如Bad SSH2 cipher spec多半是算法名称写错了或者当前OpenSSH版本不支持某算法需要核对后调整。这个校验动作相当于开车前看油表花不了几秒能避免后续重启失败导致远程断连的尴尬。3.3 第三步轮换主机密钥接下来处理主机密钥。先看一下当前有哪些主机密钥再决定删什么、留什么。ls -l /etc/ssh/ssh_host_*常见的弱主机密钥包括ssh_host_dsa_key、ssh_host_rsa_key如果长度只有1024位以及ssh_host_ecdsa_key如果业务没有特殊要求也可以一并换掉。推荐的做法是保留并启用ed25519密钥这是目前最稳健的选择。ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N 第二条命令生成一个4096位的RSA备用密钥是为了兼容那些还不支持ed25519的老客户端。生成完后删掉DSA密钥文件同时检查sshd_config里有没有对应的HostKey配置行如果有就要同步删掉或注释掉否则重启时sshd会因为找不到密钥文件而启动失败。rm -f /etc/ssh/ssh_host_dsa_key /etc/ssh/ssh_host_dsa_key.pub密钥文件权限也必须正确私钥权限600属主root:root公钥权限644。ssh-keygen默认会设置好权限但如果你是从备份恢复的文件很容易遇到权限过大的问题。检查命令如下。chmod 600 /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key chmod 644 /etc/ssh/ssh_host_ed25519_key.pub /etc/ssh/ssh_host_rsa_key.pub chown root:root /etc/ssh/ssh_host_*3.4 第四步平滑重载、验证与切换先区分两个命令systemctl reload sshd是平滑重载配置文件已建立的连接不受影响systemctl restart sshd是重启服务会重新加载主机密钥但已经建立的长连接一般也不会断因为连接会话由独立的子进程维持。这里我的习惯是只改算法配置用reload换了主机密钥就必须restart。systemctl reload sshd重载完成后第一时间用客户端验证实际协商出来的算法这是判断“配置是否真正生效”的金标准。ssh -vv user192.168.1.10 21 | grep -iE kex|host key algorithm|cipher|MAC正常输出会看到类似下面的内容debug1: kex: algorithm: curve25519-sha256 debug1: kex: host key algorithm: ssh-ed25519 debug1: kex: client-server cipher: aes128-ctr MAC: hmac-sha2-256 compression: none debug1: kex: server-client cipher: aes128-ctr MAC: hmac-sha2-256 compression: none这说明双方实际用的算法已经是新的了。再用ssh-audit localhost扫一遍和前面的基线输出对比确认fail和warn级别项已经清除。最后检查一下服务监听和日志确认没有报错。ss -lntp | grep :22 journalctl -u sshd -f重载后留观察窗口看日志里有没有客户端反复尝试连接失败的情况我一般观察半小时到一个小时确认稳定后再进入下一个批次。4. 常见问题与排查技巧实录4.1 客户端连不上no matching cipher found这个问题几乎每个做过SSH加固的人都会遇到。症状是某个客户端连的时候直接报错常见的报错信息是Unable to negotiate with 192.168.1.10 port 22: no matching cipher found。原因很清楚你开了白名单但客户端支持的算法全被白名单过滤掉了一个交集都没有。处理方式分两步。第一步确认当前sshd实际生效的算法配置用sshd -T看运行配置。第二步看对端日志/var/log/secure或/var/log/auth.log里通常会明确写出服务端愿意接受哪些算法。如果这个客户端确实业务必须用且无法升级就不要整体开放弱算法而是用Match块按来源IP定向兼容。# 仅对指定网段保留旧算法 Match Address 10.10.0.0/16 Ciphers aes128-cbc这里有个细节OpenSSH 6.5以上支持在算法指令前加表示追加而非覆盖。但这个方案是临时兼容用的后续还是要推动客户端升级毕竟堡垒都是要从内部攻破的。4.2 主机密钥变更引发known_hosts告警换完主机密钥客户端的known_hosts记录就失效了。客户端下次连接会弹出REMOTE HOST IDENTIFICATION HAS CHANGED的警告这是SSH防中间人攻击的正常机制不是故障。有些同事第一反应是直接编辑known_hosts删行也能解决但更规范的做法是用密钥指纹校验后再更新。ssh-keygen -R 192.168.1.10 ssh-keyscan -t ed25519 192.168.1.10 ~/.ssh/known_hostsssh-keygen -R删除旧记录ssh-keyscan重新获取新的主机公钥。如果客户端数量多建议提前把新指纹发给相关人员或者在堡垒机、跳板机上统一更新避免第二天早上大家同时连不上开始互相猜疑。4.3 sshd启动失败与权限问题修改配置后systemctl restart sshd结果服务起不来报错Permissions 0644 for /etc/ssh/ssh_host_rsa_key are too open。这个错误是因为密钥文件权限过大sshd拒绝用不安全的权限加载私钥。解决办法就是前面说的把私钥改成600、公钥644。还有一种启动失败的情况配置里写了HostKey对应的文件但文件被删了报错sshd: no hostkeys available或者sshd: hostkey /etc/ssh/ssh_host_dsa_key not found。遇到这种先检查文件是否还在再检查配置里有没有残留的HostKey行。我的经验是一次性处理多台机器时脚本里如果只删了文件、没同步改配置最容易触发这个问题。4.4 回滚预案出事别慌三步还原加固操作本身并不复杂真正考验人的是“万一出问题怎么快速恢复”。回滚预案要提前写好我的做法是三步。第一步恢复配置文件。启动命令里的sshd_config.bak.$(date %F)就是为此准备的回滚时把备份复制回去。cp /etc/ssh/sshd_config.bak.2025-01-01 /etc/ssh/sshd_config systemctl reload sshd第二步如果备份文件也没了就从软件包默认配置里恢复。基于RPM的系统可以用rpm -V openssh-server查看配置被改动的地方再用rpm -qf /etc/ssh/sshd_config确认属于哪个包重新提取默认文件。第三步如果连sshd都启动不了、远程完全连不上只能通过带外管理通道处理比如云控制台的VNC、物理服务器的IPMI。所以做SSH加固时我强烈建议保持一个“保命窗口”——在操作前先开启一个新的已登录会话窗口不要关闭一旦修改导致sshd异常还能通过这个已建立的连接把配置改回去。我见过太多同事改配置改到一半把自己锁在门外的案例最后只能去机房按电源键。我个人在实际操作中的体会是SSH加固这件事真正消耗精力的不是那几行配置而是升级前后的兼容性管理和灰度切换。给客户做过一次整改改完算法白名单、换完主机密钥业务方的老自动化平台连不上了最后靠着Match块定向兼容才没影响生产任务。后来我就把自己的流程固定下来先扫描、再评估、后配置、再验证每一步都留记录和回滚点。最后分享一个小技巧如果你不确定当前这台机器的SSH实际支持哪些算法用ssh -Q cipher、ssh -Q kex、ssh -Q mac三个命令就能把本机内置支持的算法全列出来写配置时对照这个列表就不会拼错算法名。
返回列表