OpenSSH密钥交换算法加固:告别安全扫描中的弱算法告警 1. 项目概述为什么你的SSH配置总被安全扫描“点名”最近在帮几个朋友的公司做安全合规检查发现一个高频出现的问题无论是Nessus、OpenVAS还是商业化的漏洞扫描器总有一堆服务器因为SSH的密钥交换算法KexAlgorithms配置不当而被标记为“中危”甚至“高危”漏洞。报告里常常写着“使用弱密钥交换算法如diffie-hellman-group1-sha1”搞得运维同学很紧张业务方也频频追问。其实这问题说大不大说小也不小。说它不大是因为在双方都使用现代SSH客户端和服务端的场景下实际被利用的风险相对可控说它不小是因为在合规审计如等保、PCI DSS和安全评级中这类“已知弱点”的配置会直接拉低整体评分甚至影响业务上线。OpenSSH作为最主流的远程管理协议其安全性配置一直是纵深防御中容易被忽视的一环。很多人安装完系统默认的/etc/ssh/sshd_config文件用到底却不知道里面可能藏着一些为了兼容老旧设备而保留的、现已不被推荐的算法。密钥交换算法顾名思义是SSH连接建立初期客户端和服务器用来安全协商出一个后续加密通信所用的“会话密钥”的算法。如果这个协商过程本身使用的算法存在理论上的弱点比如基于过时的SHA1哈希或者使用不够安全的Diffie-Hellman群组那么整个连接的安全性基石就不够稳固。我处理过不下百台服务器的此类问题从CentOS 7到Ubuntu 22.04从物理机到容器镜像。核心解决思路就一条在sshd_config配置文件中明确指定一套强健、现代的KexAlgorithms密钥交换算法列表并禁用那些已知的弱算法。这不仅能让你轻松通过各种安全扫描更是提升服务器整体安全水位的一个扎实步骤。接下来我就把手把手的配置方法、背后的原理以及我踩过的坑都分享出来。2. 核心原理密钥交换算法KEX到底是什么为什么弱算法有风险在深入配置之前我们得先搞明白我们在调整什么。SSH连接建立过程大致分为几个阶段协议版本协商、密钥交换、用户认证和连接通道建立。其中密钥交换Key Exchange 简称KEX是第二阶段也是最关键的安全基石阶段。2.1 密钥交换过程简述算法协商客户端连接服务器时双方会交换各自支持的算法列表包括密钥交换算法、加密算法、消息认证码算法等。它们会从各自列表的第一个开始匹配选择第一个双方都支持的算法。密钥生成与交换使用协商好的密钥交换算法客户端和服务器在不安全的网络上通过数学计算通常是基于离散对数或椭圆曲线问题共同生成一个只有双方知道的共享秘密。这个过程中交换的只是公开参数即使被窃听也无法推算出最终的共享秘密。派生会话密钥利用这个共享秘密结合连接期间交换的随机数称为“交换哈希”通过一个密钥派生函数生成后续用于对称加密如AES和完整性校验如HMAC的实际会话密钥。所以KexAlgorithms这个配置项定义的就是服务器端愿意参与协商的密钥交换算法列表及其优先级顺序。2.2 弱算法风险何在安全扫描器标记的“弱算法”通常指以下几类基于SHA1的算法例如diffie-hellman-group-exchange-sha1、diffie-hellman-group14-sha1。SHA1哈希算法早在2005年就被发现存在碰撞漏洞理论上的安全性已大打折扣。虽然在实际的SSH KEX场景中直接攻击的难度依然很高但出于“深度防御”原则和安全合规要求应当禁用。使用小质数群组的Diffie-Hellman算法例如diffie-hellman-group1-sha1对应768位模数。这类算法的安全性依赖于“离散对数问题”的难度而小质数群组模数位数低使得暴力计算或预计算攻击成为可能。早在2015年就有研究团队成功对768位DH群组进行了实际破解。已被证明存在潜在问题的算法如diffie-hellman-group-exchange-sha256虽然使用SHA256但其基于的“Group Exchange”模式在特定实现下可能存在信息泄露风险因此一些严格的安全基线也建议优先使用固定群的算法。注意风险是相对的。如果你的服务器只被内部、可控的、使用现代OpenSSH客户端7.3的管理员访问那么即使启用了弱算法实际连接时也会优先协商到更强的算法如curve25519-sha256。风险主要存在于1存在老旧客户端如某些嵌入式设备、老版本Windows工具强制使用弱算法连接2满足合规性要求3防范潜在的降级攻击虽然现代SSH实现已很难成功。3. 实战配置手把手调整OpenSSH的KexAlgorithms理论懂了我们直接上操作。整个过程分为诊断、配置、验证三步。3.1 第一步诊断当前服务器的KEX算法配置在修改之前必须先查看当前配置了解现状。查看sshd当前生效的配置# 查看sshd_config中关于KexAlgorithms的配置行 sudo grep -i ^KexAlgorithms /etc/ssh/sshd_config如果没有任何输出说明使用的是OpenSSH的默认算法列表。查看sshd实际支持的算法列表更准确# 使用ssh-keyscan或ssh命令查看服务器提供的算法 ssh -Q kex localhost或者更直接地模拟一个连接并查看详细的协商日志需要调整客户端日志级别ssh -vvv -o KexAlgorithmsdiffie-hellman-group1-sha1 localhost 21 | grep -i kex algorithm这条命令会强制客户端使用弱算法尝试连接在-vvv的详细输出中你可以看到服务器是否接受该算法。使用nmap进行外部扫描模拟攻击者或审计视角# 安装nmap如果尚未安装 # sudo yum install nmap 或 sudo apt install nmap # 扫描目标服务器的SSH算法支持情况 nmap --script ssh2-enum-algos -p 22 你的服务器IP这个nmap脚本会列出服务器支持的所有密钥交换、加密、MAC等算法非常直观。3.2 第二步编辑sshd_config配置文件现在开始修改。强烈建议在修改前备份原配置文件sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %Y%m%d)使用你熟悉的编辑器如vim, nano打开配置文件sudo vim /etc/ssh/sshd_config找到或添加KexAlgorithms配置行。一个安全且兼容性较好的现代配置如下# 在文件末尾或Ciphers/MACs配置附近添加 KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256配置行详解curve25519-sha256,curve25519-sha256libssh.org这是当前首选的算法。基于椭圆曲线Curve25519速度快安全性高且被认为能更好地抵抗某些类型的密码学攻击。libssh.org是libssh库的实现标识。ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521基于NIST标准椭圆曲线的算法广泛支持是良好的备选。虽然对NIST曲线存在一些讨论但在实践中它们仍然是安全可靠的选择。diffie-hellman-group-exchange-sha256允许客户端请求特定大小的DH群组灵活性高。一些严格策略可能禁用它但对于通用场景保留它可以提高兼容性。diffie-hellman-group16-sha512, diffie-hellman-group18-sha512使用大群组group16: 4096位 group18: 8192位和SHA512的DH算法强度非常高但计算开销也稍大。diffie-hellman-group14-sha256使用2048位群组的DH算法是之前多年的“安全基准”现在依然是安全的选择但优先级应放在更现代的曲线算法之后。关键点列表的顺序就是优先级顺序。服务器会按这个顺序与客户端提供的列表进行匹配选择第一个双方都支持的。所以把最安全、最快的算法如curve25519放在最前面。需要禁用的弱算法确保它们不在列表中diffie-hellman-group1-sha1diffie-hellman-group14-sha1diffie-hellman-group-exchange-sha1ecdh-sha2-nistp256-cert-v01openssh.com证书相关变种通常不需要3.3 第三步应用配置并验证检查配置文件语法在重启服务前先检查配置是否有语法错误。sudo sshd -t如果没有任何输出表示语法正确。如果报错请根据错误信息修正配置行。重启sshd服务# Systemd系统CentOS 7, Ubuntu 16.04, Debian 8 sudo systemctl restart sshd # SysVinit系统旧版 sudo service ssh restart验证新配置是否生效方法A从另一台机器使用nmap再次扫描最客观。nmap --script ssh2-enum-algos -p 22 你的服务器IP查看输出的kex_algorithms部分应该只包含你配置的那些强算法不再有-sha1或group1等弱算法。方法B使用特定弱算法尝试连接应该失败。ssh -o KexAlgorithmsdiffie-hellman-group1-sha1 用户名你的服务器IP预期结果应该是连接超时或立即失败并提示no matching key exchange method found。方法C使用正常客户端连接并查看日志。ssh -vvv 用户名你的服务器IP 21 | grep -i kex algorithm在详细输出中你应该能看到类似kex algorithm: curve25519-sha256的日志表明成功协商到了你列表中的首选算法。4. 兼容性考量与降级处理当老旧设备还需要连接时怎么办在实际生产环境中一刀切地禁用所有旧算法可能会“误伤”一些老旧但重要的设备或软件。我遇到过工厂里的工控机跑着很老的Linux、某些网络设备交换机、路由器的管理接口或者一些遗留的自动化脚本它们内置的SSH客户端可能只支持老旧的算法。处理原则安全与兼容的平衡隔离网络区别对待这是最推荐的方式。将必须使用老旧协议/算法的设备划分到独立的管理VLAN或网段在该网段对应的SSH服务监听端口可以是非22端口上配置一套兼容性策略。而面向互联网或办公网的SSH服务22端口则使用最严格的策略。# 在sshd_config中使用Match块针对不同地址或用户进行配置 # 严格策略默认 KexAlgorithms curve25519-sha256,ecdh-sha2-nistp256,diffie-hellman-group16-sha512 # 为来自特定管理网段的连接启用兼容模式 Match Address 192.168.100.0/24 KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1注意号表示在原有列表基础上追加而不是覆盖。更安全的做法是为兼容性监听另一个端口并在该端口的配置中单独设置算法列表。升级客户端如果可能推动老旧设备或软件的升级。例如为老版本Windows安装新版的OpenSSH for Windows或使用Putty的最新版本。使用跳板机Bastion Host不允许老旧设备直接连接核心服务器。让它们先连接到一台专门配置了兼容性算法的“跳板机”再从跳板机用强算法连接到目标服务器。实操心得在金融行业的一次合规改造中我们遇到一批无法升级的ATM机管理终端。最终方案是在核心服务器上创建了一个非标端口如2222在该端口的sshd配置中通过Match Address针对这些终端的管理IP单独放行了diffie-hellman-group14-sha1。同时在防火墙上严格限制了只有这些特定IP能访问2222端口。这样既满足了扫描器对22端口“零弱算法”的要求又保证了业务的连续性。关键是要有清晰的记录和审批流程明确哪些设备、为什么需要例外。5. 进阶加固结合Ciphers和MACs的全局安全配置只调整KexAlgorithms是远远不够的。一个完整的SSH加固配置通常需要联动修改加密算法Ciphers和消息认证码算法MACs形成一套组合拳。一个完整的、偏严格的安全配置示例适用于OpenSSH 7.3及以上版本# /etc/ssh/sshd_config # 密钥交换算法本文核心 KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512 # 加密算法对称加密 Ciphers chacha20-poly1305openssh.com,aes256-gcmopenssh.com,aes128-gcmopenssh.com,aes256-ctr,aes192-ctr,aes128-ctr # 消息认证码算法完整性校验 MACs hmac-sha2-256-etmopenssh.com,hmac-sha2-512-etmopenssh.com,umac-128-etmopenssh.com # 其他重要安全选项 Protocol 2 # 禁用老旧的SSHv1 PermitRootLogin prohibit-password # 禁止root密码登录建议改为no或prohibit-password PasswordAuthentication no # 禁用密码认证强制使用密钥 PubkeyAuthentication yes PermitEmptyPasswords no ChallengeResponseAuthentication no UsePAM yes X11Forwarding no AllowTcpForwarding no # 按需开启 ClientAliveInterval 300 ClientAliveCountMax 2配置解析与取舍Ciphers优先选择带AEAD认证加密模式的算法如chacha20-poly1305和aes-gcm它们将加密和完整性校验合二为一更高效安全。aes-ctr是传统的加密模式作为兼容备选。MACs优先选择-etmEncrypt-then-MAC模式的算法这种模式能更好地防止某些定时攻击。hmac-sha2系列是目前的主流。取舍上述配置可能过于严格会拒绝一些老旧的客户端如老版本macOS的Terminal、某些IoT设备。你需要根据你的客户端生态进行调整。一个更兼容但仍安全的Ciphers列表可以是aes256-gcmopenssh.com,aes128-gcmopenssh.com,aes256-ctr,aes192-ctr,aes128-ctr,chacha20-poly1305openssh.com。如何测试你的配置对客户端的影响可以使用在线工具如ssh-audit或本地脚本模拟不同版本的SSH客户端来测试你的服务器配置。但最直接的方法是收集你们公司所有类型的运维终端Windows上的Putty/Xshell/MobaXterm、macOS Terminal、Linux各发行版、各种编程语言/工具的SSH库版本用它们实际连接测试一次。6. 自动化与持续监控让安全配置一劳永逸手动配置几十上百台服务器不现实也容易出错。我们需要自动化。6.1 使用配置管理工具Ansible示例下面是一个Ansible Playbook片段用于批量配置SSH的KEX算法--- - name: Harden SSH Key Exchange Algorithms hosts: all_servers become: yes tasks: - name: Backup original sshd_config ansible.builtin.copy: remote_src: yes src: /etc/ssh/sshd_config dest: /etc/ssh/sshd_config.bak_{{ ansible_date_time.date }} - name: Set strong KexAlgorithms in sshd_config ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: ^#?KexAlgorithms line: KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512 state: present backup: yes - name: Validate sshd_config syntax ansible.builtin.command: sshd -t changed_when: false failed_when: false register: sshd_check - name: Fail if sshd_config syntax is invalid ansible.builtin.fail: msg: sshd_config syntax check failed. Please check the configured KexAlgorithms line. when: sshd_check.rc ! 0 - name: Restart sshd service ansible.builtin.service: name: sshd state: restarted when: sshd_check.rc 0这个Playbook会先备份然后确保KexAlgorithms行被设置为强算法列表进行语法检查最后在语法正确的情况下重启服务。6.2 集成到镜像或容器构建过程对于使用Docker或虚拟机模板的场景应该在基础镜像或模板制作阶段就完成安全配置。Dockerfile示例FROM ubuntu:22.04 RUN apt-get update apt-get install -y openssh-server # 创建目录并生成主机密钥 RUN mkdir /var/run/sshd RUN ssh-keygen -A # 复制预先准备好的、已加固的sshd_config文件 COPY hardened_sshd_config /etc/ssh/sshd_config EXPOSE 22 CMD [/usr/sbin/sshd, -D]关键这个hardened_sshd_config文件就是你本地已经测试好的、包含强KexAlgorithms等配置的完整文件。6.3 持续监控与合规检查配置不是一劳永逸的。OpenSSH版本会更新新的漏洞和算法建议也会出现。你需要建立监控机制。定期扫描使用Nessus、OpenVAS或商业扫描器定期如每月对服务器进行SSH专项漏洞扫描。使用ssh-audit进行专项检查ssh-audit是一个优秀的命令行工具能给出详细的配置评分和建议。# 安装 pip install ssh-audit # 审计你的服务器 ssh-audit 你的服务器IP它会输出一个报告明确告诉你哪些算法弱、哪些好并给出修改建议。集中日志分析将SSH的日志/var/log/auth.log或/var/log/secure集中到SIEM如Elastic Stack中。可以设置告警规则监控是否有连接尝试使用已被你禁用的弱算法日志中会有no matching key exchange method等记录这可能是攻击者探测或老旧客户端异常的信号。7. 常见问题与故障排查实录在实际操作中你肯定会遇到各种问题。这里把我遇到过的典型问题和解决方法列出来。7.1 问题重启sshd服务失败报错“Invalid configuration value”可能原因KexAlgorithms或Ciphers,MACs的配置行有语法错误。常见错误包括算法名称拼写错误如curve25519-sha256写成curve25519-sha256。使用了当前OpenSSH版本不支持的算法比如在很老的版本上配置了chacha20-poly1305openssh.com。列表中存在重复的算法。逗号后面有空格在某些版本中可能导致解析问题。排查步骤运行sudo sshd -t它会精确指出哪一行、哪个附近有错误。对照官方文档或ssh -Q kex的输出检查算法名。简化列表进行测试。先只配置一个确认可用的算法如curve25519-sha256重启服务看是否成功再逐步添加。7.2 问题配置生效后特定客户端如老版本Java应用无法连接现象客户端连接时报错Algorithm negotiation failed或no matching key exchange method。原因客户端支持的算法列表与你服务器配置的列表没有交集。解决方案确定客户端支持的算法如果客户端是你可控的尝试在其机器上运行ssh -Q kex如果是OpenSSH或查阅其文档。对于Java应用使用的可能是JSch或Apache MINA SSHD库需要查对应库版本的文档。在服务器端添加兼容算法在服务器的KexAlgorithms列表末尾追加客户端支持的、相对最强的那个算法。例如如果客户端只支持diffie-hellman-group14-sha256那么就在列表最后加上它。务必加在最后以确保其他现代客户端优先使用更安全的算法。升级客户端库这是根本解决办法。联系开发团队升级应用依赖的SSH库版本。7.3 问题安全扫描器仍然报告存在弱算法漏洞现象你已经确认sshd_config配置正确且用ssh -Q kex和nmap扫描都显示弱算法已禁用但扫描器如Nessus的报告依然显示存在diffie-hellman-group1-sha1漏洞。可能原因及排查扫描器缓存扫描器可能有缓存尝试清除扫描任务的缓存或重新运行扫描。多个SSH服务实例服务器上可能运行着多个sshd进程或监听在不同端口的sshd服务而你只修改了其中一个配置文件。用netstat -tlnp | grep :22或ss -tlnp | grep sshd检查监听22端口的进程及其启动命令确认它使用的是你修改的/etc/ssh/sshd_config。配置未生效确保修改配置后重启的是正确的sshd服务。对于Systemd使用sudo systemctl restart sshd对于通过inetd/xinetd或容器内启动的重启方式可能不同。扫描器误报或规则过时有些扫描器插件规则可能比较老旧或过于敏感。你可以手动验证用nmap --script ssh2-enum-algos扫描如果结果中没有弱算法那么你的配置是正确的。可以将此结果作为证据向审计或安全团队申请对扫描结果进行“误报”确认或规则调整。7.4 问题配置后SSH连接速度变慢现象启用新的KEX算法特别是diffie-hellman-group16/18-sha512后感觉连接建立阶段变慢了。原因更大的Diffie-Hellman群组4096位、8192位需要更多的计算资源来进行密钥交换。解决方案调整算法优先级将计算量大的算法如diffie-hellman-group18-sha512在列表中的位置往后放。将curve25519-sha256和ecdh-sha2-nistp256这类基于椭圆曲线、速度快且安全的算法放在最前面。评估是否必要对于绝大多数场景curve25519-sha256和ecdh-sha2-nistp256提供的安全性已经足够。可以考虑将diffie-hellman-group16/18-sha512从默认列表中移除或者仅在与特定高安全要求的客户端连接时通过Match块启用。硬件性能如果服务器CPU资源非常紧张可以考虑升级硬件。但在云时代这通常不是问题。一个折中的、兼顾安全与性能的算法列表参考KexAlgorithms curve25519-sha256,curve25519-sha256libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256这个列表移除了计算最重的group16/18-sha512保留了足够安全的选项兼容性也比较好。安全扫描通常也能通过。