ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenSSH升级全攻略:从Linux到Windows的安全加固与实践

OpenSSH升级全攻略:从Linux到Windows的安全加固与实践 1. 到底要不要升级OpenSSH先搞清楚为什么这件事急不得也拖不得先说个真实场景。大部分运维手里都管着几台甚至几十台Linux服务器平时最常做的事就是ssh登上去敲命令。OpenSSH作为系统默认的远程管理通道基本上从装系统那天起就躺在那儿很少有人主动想起来要去升级它。直到某天安全通告发到邮箱说OpenSSH又出了高危漏洞或者等保扫描报告上赫然写着“SSH服务版本过低”你才开始正视这台机器的SSH版本已经落后了好几年。别急着动手。升级OpenSSH这件事虽然原理不复杂但风险极高——它毕竟是你和服务器之间的“生命线”。操作过程中一旦配置写错、编译失败或者服务没起来而你的远程会话又已经断开那基本等于把自己锁在门外。所以我一直强调一个原则升级OpenSSH之前先想想如果断连了你怎么回到这台机器上。有了这一层保底再谈后面的步骤。这篇文章我按实际使用场景来梳理覆盖Linux服务器Alibaba Cloud Linux 3、CentOS、openEuler最常见的三条升级路径再补上Windows服务器开通OpenSSH的过程以及macOS上“软件更新角标”这个看似不相关、但经常和升级一起被拿出来问的小问题。内容偏实操适合运维、测试、开发以及所有需要自己维护服务器的人参考。1.1 为什么OpenSSH是安全风口OpenSSH是几乎所有Linux/Unix系服务器默认自带的远程管理组件也是Windows 10/11和Server 2019之后的可选功能。它负责你每次ssh登录、scp传文件、隧道转发等操作。因为它直接暴露在网络端口上默认22所以也是被扫描和攻击最频繁的服务之一。网上随便一搜就能看到大量针对SSH的暴力破解记录这也就解释了为什么OpenSSH一有漏洞影响力往往就是“严重”级别。这些年OpenSSH出过好几次让人印象深刻的漏洞。有的是远程代码执行有的涉及密钥验证绕过有的能导致中间人攻击。对于生产环境来说哪怕漏洞利用条件比较苛刻只要它出现在安全通告里等保、CVE、企业安全团队都会要求限期修复。所以在大多数情况下“要不要升级”根本不是问题问题是怎么在尽量不影响线上业务的前提下把版本安全地升上去。1.2 升级前必须理清的环境清单我每次升级前都会先把四件事确认清楚缺一个都不开工当前系统版本和SSH版本运行ssh -V和cat /etc/os-release查看记下来备用。是否有人在用这台服务器哪怕只有一个人在用升级期间也可能顶掉会话最好先约个窗口期。之后如何回滚如果是从软件源升级一般保留旧版本包就行如果是源码编译旧版本要么提前备份二进制要么心里有数“升坏了还能从哪台机器回来”。SSH配置有没有被深度定制过如果你改过sshd_config里的端口、认证方式、AllowUsers等参数升级后要确认这些配置仍然生效。把这件事想明白后面每一步操作都踏实得多。2. 系统包管理器升级Alibaba Cloud Linux 3 与 CentOS 的最稳路径服务器上的OpenSSH升级我第一个推荐的方案永远是系统包管理器。用yum/dnf从软件源里直接拉新版好处是依赖自动处理、不会出现路径错乱、回滚容易。这对生产环境来说太重要了。很多同学一听说要升级OpenSSH第一反应就是去网上找源码包编译其实对于CentOS、Alibaba Cloud Linux这类发行版先看软件源比什么都强。2.1 先看发行版的升级通道Alibaba Cloud Linux 3它的软件源仓库里OpenSSH版本通常比较新直接用dnf update openssh就能升到当前仓库里的最新版本。因为这是阿里云维护的发行版安全补丁跟得比较紧大多数情况下不需要折腾源码。CentOS 7/8CentOS 7的问题比较明显——官方源里的OpenSSH还停留在老版本直接yum update openssh往往提示“已经是最新版本”但版本号明显偏旧。这种情况下可以考虑用ELRepo或者专门维护安全更新的第三方源比如linux-repo这类社区源。如果公司有安全合规要求也可以走源码编译。Ubuntu/Debian系一般直接apt update apt upgrade openssh-server openssh-client即可基本没有CentOS那么纠结。我在实际中遇到过很多次这样的情况CentOS 7上跑着OpenSSH 7.4安全检查要求必须升到7.8以上。此时想在官方源里等到新版基本不可能只能换思路。所以对CentOS 7用户来说我的建议是先试ELRepo不行再上源码编译步骤在下一节里详细说。2.2 Alibaba Cloud Linux 3 升级实操在Alibaba Cloud Linux 3上最省事的流程是这样的。先刷新缓存sudo dnf makecache然后直接更新OpenSSH相关组件。注意把client和server一起更新避免两边版本不一致sudo dnf update -y openssh openssh-server openssh-clients如果你有固定的内网源可以配好之后再用同样的命令速度会更快。升级完成后先不要立刻断开当前连接我们应该先启用并重启服务确认sshd能正常起来sudo systemctl enable sshd sudo systemctl restart sshd sudo systemctl status sshd看到active (running)之后再验证版本ssh -V如果输出显示新版本并且你当前的连接没有断开那说明基本稳了。整个过程非常干净依赖也不用自己操心。我个人强烈建议所有Alibaba Cloud Linux 3用户优先用这套流程别一上来就编译源码没必要给自己增加维护成本。2.3 密钥认证优先先备好后路升级前后最怕的事就是密钥失效或权限不对。特别是当你用密码登录、但系统里又开启了PermitRootLogin的时候一旦升级后sshd配置被重置可能会遇到“密码怎么都不对”的尴尬情况。所以升级前我习惯先做两件事。第一确认当前可以通过密钥登录ssh -i ~/.ssh/id_ed25519 userserver如果能免密登录恭喜你后面操作的风险就小了很多。第二把当前sshd_config备份一份sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %F)这样即使升级后默认配置把某些自定义项覆盖了你也可以快速比对和恢复。记住升级OpenSSH这件事真正难的不是“升级”这个动作而是升级后保持服务正常、登录方式不变。3. openEuler 源码编译升级当官方源跟不上时怎么办有些场景下官方源里并没有你想要的版本。比如openEuler、CentOS 7这种系统自带的OpenSSH版本老安全要求又严等安全补丁回移不知道要等到猴年马月。这时候最直接的方案就是源码编译安装。很多人一听源码编译就头皮发麻其实OpenSSH的编译比你想象中简单它依赖的无非是zlib、openssl、pam等基础库这些在大多数服务器上都已经有了。真正麻烦的不是编译而是“编译安装后如何平滑切换服务”以及“编译错了如何回滚”。这一节我把完整的思路和步骤拆开讲。3.1 为什么最终会选择源码编译当系统包管理器这条路走不通的时候源码编译变成了唯一可控的选择。比如我之前在一台openEuler 22.03 LTS上做过升级系统自带的OpenSSH版本是8.2p1但合规要求要升到9.4p1以上。当时的软件源里没有更高版本等安全更新也不现实于是只能把官方openssh源码拉下来自己编译安装。源码编译还有一个好处你可以指定安装路径、指定openssl版本、启用或禁用某些编译特性。比如生产环境如果需要把SSH端口绑定到非标端口或者要禁掉某些不安全的算法编译时都可以做相应配置。当然这些也可以通过配置文件实现但对于特殊需求源码编译给的自由度确实更高。3.2 编译安装步骤拆解以openEuler为例完整流程我梳理一下。首先安装编译依赖。openEuler使用dnfsudo dnf install -y gcc make zlib-devel openssl-devel pam-devel rpm-build然后下载openssh源码包。注意一定要去OpenSSH官方列出的镜像站下载别随便找个第三方打包站点。我一般用这个格式cd /usr/local/src wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz tar -zxvf openssh-9.8p1.tar.gz cd openssh-9.8p1正式编译前先配置。强烈建议指定--prefix/usr和--sysconfdir/etc/ssh因为默认prefix是/usr/local装完之后sshd路径会变成/usr/local/sbin/sshd很多系统脚本里找的还是/usr/sbin/sshd两者不一致会导致服务起不来或管理混乱。./configure --prefix/usr --sysconfdir/etc/ssh --with-pam --with-zlib --with-ssl-dir/usr之后就是经典的make和安装make -j$(nproc)make之后先别急着make install可以先跑一遍测试make tests测试通过后再执行sudo make install安装完成后覆盖一下启动脚本和服务配置。这一步最容易漏。源码install不会自动生成systemd服务文件所以要把系统自带的ssh服务文件处理一下。在openEuler上通常是这样sudo systemctl stop sshd sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak # 根据实际情况把新生成的配置或备份的配置放回去 sudo systemctl daemon-reload sudo systemctl start sshd sudo systemctl status sshd真正生产环境里我还会提前把/usr/sbin/sshd和/usr/bin/ssh都确认一遍版本/usr/sbin/sshd -V /usr/bin/ssh -V如果路径正确、版本正确服务能正常起说明源码升级完成。3.3 源码升级的几个容易忽略的坑这一节我多写几句因为源码编译的坑比包管理器多得多。坑一忘记--sysconfdir导致配置路径不对。默认配置目录是/usr/local/etc如果你不指定升级后sshd配置文件就变成了新路径系统启动脚本和原来的配置全部对不上轻则无法远程登录重则连sshd都起不来。解决方式是编译时老老实实加上--sysconfdir/etc/ssh。坑二没有备份旧sshd二进制。源码install会直接覆盖/usr/sbin/sshd如果新版本有问题你又没留着旧文件想回滚就得重新编译旧版本相当麻烦。我的习惯是编译前先复制一份sudo cp /usr/sbin/sshd /usr/sbin/sshd.bak万一升坏了一条命令就能恢复。坑三PAM模块和登录会话问题。源码编译时如果没开--with-pam很可能导致密码认证正常、但登录后无法正确建立会话甚至出现“用户名密码正确但被秒退”的怪问题。所以在configure参数里一定要带PAM支持。也别乱把系统ssl库替换掉我见过有人为了新特性去单独升级openssl结果整个系统一堆软件编译不过得不偿失。坑四防火墙没放行。升级前后如果改了端口比如从22改成2222别只顾着配置sshd防火墙和SELinux都要同步放行。openEuler默认SELinux开着如果SELinux策略没改即使防火墙放行了端口sshd也可能连不上。这一步是很多人忽略的重灾区。4. Windows 服务器开启 OpenSSH 服务从可选功能到能用的完整过程说完Linux我们把目光放到Windows上。其实Windows上开启OpenSSH服务并不难微软从Windows Server 2019和Windows 10 1809开始把OpenSSH作为独立可选功能内置进系统里了。对于管理员来说不用安装第三方SSH软件直接在系统设置里把功能打开就行。4.1 开启方式和版本确认Windows上开启OpenSSH有两种常见路子。第一种通过图形界面“设置”操作。打开“设置” - “应用” - “可选功能”查看是否已安装“OpenSSH服务器”。如果没有点击“添加功能”搜索“OpenSSH服务器”并安装即可。这种方式适合图形化操作门槛最低。第二种用PowerShell适合批量处理多台机器。在管理员权限的PowerShell里执行Get-WindowsCapability -Online | Where-Object Name -like OpenSSH*如果返回的State为“NotPresent”就执行安装Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0之后启动服务并设置开机自启Start-Service sshd Set-Service -Name sshd -StartupType Automatic验证端口是否监听Get-NetTCPConnection -LocalPort 22看到State为Listen就说明服务起来了。4.2 基本配置与公钥登录Windows版OpenSSH的配置文件在C:\ProgramData\ssh\sshd_config。如果你开启了服务但没这个文件可以用服务启动后自动生成的默认配置。有一点要注意Windows版OpenSSH默认配置和Linux上的有些差异最典型的就是sshd_config里被注释掉的Match Group administrators以及AuthorizedKeysFile路径。Windows的默认authorized_keys文件路径是C:\Users\用户名\.ssh\authorized_keys如果你要把公钥添加到某用户下需要把这个文件放对位置。给Windows服务器配公钥登录的步骤大致如下在本地机器生成密钥对ssh-keygen -t ed25519把公钥写到目标服务器用户目录的C:\Users\用户名\.ssh\authorized_keys确认该用户的.ssh目录权限在Windows上OpenSSH对权限很敏感尤其是Administrators组的用户。如果权限不对即使公钥文件存在也会被拒绝。Windows上配置权限比较麻烦可以用PowerShell来授权。我一般用如下命令快速处理icacls C:\Users\用户名\.ssh\authorized_keys /inheritance:r /grant 用户名:F /grant SYSTEM:F配置完成后再重启sshdRestart-Service sshd然后从客户端尝试ssh 用户名服务器IP正常情况下可以直接免密登录。4.3 Windows 下 OpenSSH 的日常注意点Windows上的OpenSSH虽然好用但它不是Linux那一套。有几个注意点我总结一下默认shell问题Windows的OpenSSH默认shell是cmd.exe登录进去是cmd交互。如果你想用PowerShell或WSL需要修改默认shell的注册表或配置。很多人第一次登录进去看到cmd都以为装错了其实没装错只是默认shell就是cmd。防火墙Windows自带防火墙默认不会自动放行22端口需要手动添加规则New-NetFirewallRule -Name sshd -DisplayName OpenSSH Server (sshd) -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22密码和密钥都可用别把PasswordAuthentication no写在Windows配置里后忘记留一条后路因为Windows密码策略和Linux不同一旦你改错配置又把服务重启了再想进去就只能在控制台操作了。5. macOS 软件更新角标与自带 OpenSSH顺手解决的小事很多人在Mac上折腾OpenSSH不是因为没有ssh命令而是因为macOS里“软件更新”那个带数字的红点角标太烦人。每次系统更新提示一冒出来红点就一直挂在系统设置图标上不点掉强迫症难受点掉又担心会不会手滑把系统升了。5.1 角标与软件更新的关系先解释一下macOS上的这个角标本质上是系统更新提醒。如果你安装了可用的系统更新设置图标的右上角就会出现一个数字角标。它和OpenSSH本身没有直接关系但问题在于——macOS自带的OpenSSH版本也是跟随系统更新的。你每次升级macOS系统SSH组件版本也会跟着变。所以很多用户搜索“macOS 去掉软件更新角标”其实是想在不升级系统大版本的前提下别让系统老在眼前跳提醒。另外如果你想在macOS上手动升级OpenSSH办法之一是用Homebrew安装新版。但这个操作会覆盖系统自带的ssh路径需要自己在PATH里调整后续维护稍微麻烦。我的建议是如果你只是想用新版openssh可以装但最好只在当前用户环境里用别全局替换系统版本避免和系统自带的依赖冲突。5.2 去掉角标的两种办法去掉角标这件事本身不难。第一种办法是通过“系统设置” - “通用” - “软件更新” - “自动更新”关闭相关选项。但说实话这个只能减少自动下载角标不一定立刻消失。第二种办法是用终端命令把它隐藏。OpenSUSE、Fedora那些系统的软件更新角标各有各的隐藏法macOS上则有人直接把更新缓存删掉或者用软件更新的defaults命令。我先说明白这类操作是“表面处理”不是根治。你清理掉角标后系统仍然会不定期重新生成提醒。sudo softwareupdate --clear-catalog这个命令会让macOS暂时不再提醒可用更新。如果你确实不想被红点打扰可以试一下。但要注意这会同时屏蔽掉后续的安全更新提示。从安全角度来说我不建议长期屏蔽尤其OpenSSH这类组件很可能靠系统更新修复漏洞真为了一个角标把安全更新全挡住不值当。我的做法是把系统更新改成手动安装日常看见角标懒得管就点一下忽略选个周末让它升级完重启一次反而是最省心的。6. 升级后的检查清单与安全加固不管你是用包管理器升级还是源码编译升级升完之后别急着下班先按检查清单过一遍。升级OpenSSH不是装完就万事大吉配置是否正确、服务是否常驻、登录是否正常每一项都要亲自验证。6.1 验证服务状态和版本升级后用命令确认服务状态systemctl status sshd然后确认版本号ssh -V sshd -V再验证客户端到自己这台机器的登录是否正常。强烈建议开一个新终端窗口测试不要只在当前已有的连接里操作。这一步看起来多余但很多人就是栽在这里当前会话还连着以为一切正常结果配置里有语法错误服务重启后没起来一断就彻底进不去。验证配置是否有误可以先跑sudo sshd -t它不重启服务只检查配置语法。有输出说明有问题完全没输出表示配置正常。这是每次改配置之后必须执行的一步。6.2 密码登录与权限收紧检查完状态顺手做一下安全加固。很多服务器默认开了密码登录建议在确保密钥可用的情况下逐步收掉密码登录权限。修改/etc/ssh/sshd_config中的几项PermitRootLogin no PubkeyAuthentication yes PasswordAuthentication no但是务必先确认你的公钥已经添加到了服务器上并且用公钥登录通过了再改这项配置。改完执行sudo sshd -t sudo systemctl reload sshd有一次在客户环境里我没检查就改掉密码登录结果客户的跳板机公钥没有同步过去差点把一整个运维团队都锁在外面。从那以后我给自己定了个铁律关密码登录前先用另一个终端验证公钥登录成功再执行修改。这话我跟所有同事都重复过很多遍。另外升级之后记得清理旧进程。源码编译升级时旧sshd进程可能还在跑占着22端口。用ss -tlnp | grep sshd看看当前监听进程如果发现新旧sshd同时存在就手动重启到新版本进程。这个坑常出现在“热升级”场景里旧进程没杀掉、新进程又起不来端口被占服务状态却是正常的假象。7. 实战中踩过的坑与排查经验最后这部分我把这些年做OpenSSH升级时遇到过的典型问题整理成速查表。这些问题不解决轻则升级失败重则远程失联基本每个运维都会碰到。7.1 升级后连不上多半不是服务挂了“升级完就断连”是我见过最多的情况。绝大多数时候不是sshd服务挂了而是以下几种原因你改了端口、防火墙/SELinux没放行配置文件语法错误sshd压根没起来公钥权限不对认证失败服务器上旧的SSH进程占用端口新进程起不来。排查顺序我建议是这样如果你还有救命通道比如通过云平台VNC、控制台或者带外管理先看sshd进程是否存在如果进程在用tail -f /var/log/secure或journalctl -u sshd看日志如果日志提示认证失败就去检查密钥权限如果日志提示“Bind to port 22 failed”说明端口被占或防火墙拦截。如果完全进不去服务器那就只能靠云厂商的“救援模式”或者VNC登录进去处理。这也是为什么我一直强调无论什么时候都要留一个不会因为你ssh操作而消失的登录通道。7.2 常用排查速查表我整理了一张速查表按症状给操作建议方便你在现场快速定位。症状可能原因排查方向升级后连接超时服务没起来 / 防火墙拦截systemctl status sshd看22端口是否监听密码正确但登录失败PAM配置丢失或版本不匹配检查/etc/pam.d/sshd确认openssh版本对应公钥认证不生效authorized_keys路径或权限不对检查authorized_keys所在目录和文件权限客户端用ssh -vvv看详情sshd启动报“Bad configuration option”新版本删除了旧配置项逐行检查sshd_config删除过期参数编译后版本不对prefix路径覆盖了旧文件但PATH顺序问题用which ssh/which sshd确认实际调用路径服务状态正常但连不上旧sshd进程占住端口ss -tlnp | grep 22确认监听进程二进制路径这些经验不是我凭空想出来的是每一次踩坑后记下来的。尤其是“Bad configuration option”这个报错源码升到新版后最容易遇到——新版OpenSSH对配置项的要求更严格某些旧配置直接不认比如UseDNS在新版里虽然还存在但某些编译选项下会被禁用日志里就会报warning。遇到这类问题一个一个注释排查别偷懒。7.3 升级完别急着走收尾工作才是重点最后再分享一个实际的收尾习惯。升级OpenSSH之后我一般会做三件事第一把当前版本号、升级时间、升级方式记录到变更文档里。以后出了问题查文档就知道当时这台机器是怎么装的不用再重新摸索一遍。第二检查相关日志滚动配置。OpenSSH日志量大如果服务器的日志策略没跟上几天就能把磁盘塞满。升级后顺带看一眼/etc/logrotate.d/syslog或者journald的日志限制别让ssh日志成为新的故障点。第三把新版本对应的ssh-keygen用法过一遍。服务器上如果有旧格式的host key新版OpenSSH可能不再支持影响范围包括已保存的主机密钥信任关系。升级完最好用ssh-keygen -A重新生成所需的host key然后重启sshd。这一步能避免一个很隐蔽的问题用户客户端提示host key已变更怀疑被中间人攻击。我个人在实际操作中的体会是OpenSSH升级说难也难说简单也简单关键不是你敲了多少条命令而是你把这些命令背后的依赖、风险和后路都想清楚了。只要每次动手前留好退路、动手后把检查清单走完不管是在Alibaba Cloud Linux 3上用一条dnf命令升级还是在openEuler上吭哧吭哧编译半小时都能做到心里有底、手上有数。
返回列表