ARTICLE DETAIL

资讯详情

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

CentOS7 OpenSSH 9.8编译安装与sshd安全加固实录

CentOS7 OpenSSH 9.8编译安装与sshd安全加固实录 如果你手头有一台CentOS7云服务器并且最近用漏洞扫描工具扫过外网端口大概率会被OpenSSH的漏洞信息吓一跳。这是我在HoRain云上实测遇到的情况系统自带的OpenSSH 7.4版本已经停止维护远程管理协议本身又是暴露在公网上的高频攻击目标不升级不加固真的睡不着觉。这篇文章就是一次完整的CentOS7 OpenSSH安装与安全配置实录。我会从为什么要换掉旧版本讲起把编译安装新版OpenSSH的完整步骤、sshd_config安全加固的每一项参数、以及我在升级过程中踩过的坑全部摊开来讲。无论你是在VMware里做测试还是管理着一台真实的云服务器只要跟着这套流程走就能把SSH服务从能用提升到敢用。1. 为什么要把CentOS7自带的OpenSSH换掉1.1 旧版本的真实风险不只是扫出几个CVE那么简单CentOS7镜像装完以后默认的OpenSSH版本是7.4p1。这个版本的发布时间是2016年到现在已经过去了很多年。如果你用nmap或者类似工具扫一下大概率会看到类似这样的结果# nmap -sV -p 22 xxx.xxx.xxx.xxx PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.4 (protocol 2.0)版本号暴露在公网上意味着什么意味着攻击者不需要再猜测你的系统类型直接对着CVE库就能拉出一串潜在的漏洞利用点。其中最有名的就是CVE-2024-6387也就是被命名为regreSSHion的漏洞。这个漏洞出在sshd的信号处理逻辑上在特定的glibc版本下存在远程代码执行的风险。虽然利用条件比较苛刻但这就像家门锁被人撬过又装回去了你还能安心吗1.2 CentOS7的维护现状为什么等不到官方补丁这里有一个很多人没注意到的现实问题CentOS7在2024年6月30日已经正式停止维护了。停止维护意味着官方仓库不再推送任何更新包括安全补丁。你就算天天yum update也只能更新到停服前最后一次的软件包版本根本等不到OpenSSH的新版本推送。我遇到过不少朋友说我加了EPEL源能不能直接从yum升级openssh说实话EPEL源里的openssh确实比系统自带新一点但版本更新节奏慢而且它是跟随上游RHEL的稳定策略不会给你推送大版本。更重要的是依赖OpenSSL版本的问题EPEL不敢随便动所以你能拿到的版本依然不够新。1.3 源码编译和第三方RPM包怎么选既然官方不给更新市面上就出现了两条路一条是去找第三方打好的RPM包直接装另一条是下载OpenSSH源码自己编译。我第一次升级的时候偷懒想直接找RPM包。结果发现第三方RPM包有几个很现实的问题编译者用的configure参数你看不到包里是否带了PAM补丁、是否启用了SELinux支持都是黑盒更麻烦的是第三方RPM包经常和系统自带的openssh-libs产生依赖冲突装到一半直接提示要卸载旧包风险非常大。后来我老老实实走源码编译这条路理由很简单所有编译参数都掌握在自己手里出了问题知道去哪里排查而且编译安装到独立前缀目录之后可以和系统自带的旧sshd共存随时可以回滚。1.4 目标版本该选哪个OpenSSH的开源版本节奏比较快我建议不要盲目追最新版。以我实测的CentOS7环境来说选择9.8p1这个版本是合适的它专门修复了CVE-2024-6387同时兼容性经过大量生产环境验证。如果你看到OpenSSH已经出到更高的版本也请先确认一下它的编译依赖是否超出了CentOS7默认的OpenSSL版本否则configure这关就过不去。2. 动手升级前先把这四件事安排明白很多人拿到教程就直接开始编译结果做到一半发现yum装不了依赖、ssh断了连不回去、SELinux挡了启动整个服务器直接裸奔。我自己的经验是升级OpenSSH这种事前面花半小时做准备工作比出问题之后花半天去救服务器划算得多。2.1 备份当前SSH配置和二进制文件备份这一步看起来简单但很多人会漏掉一个关键点只备份了/etc/ssh/目录却忘了备份/usr/sbin/sshd这个二进制文件。# 备份配置目录 cp -rp /etc/ssh /etc/ssh.bak.$(date %Y%m%d) # 备份当前sshd二进制和systemd服务文件 cp -p /usr/sbin/sshd /usr/sbin/sshd.bak cp -p /etc/pam.d/sshd /etc/pam.d/sshd.bak cp -p /etc/sysconfig/sshd /etc/sysconfig/sshd.bak这里要特别说一句PAM配置一定不能漏。OpenSSH编译时如果开启了--with-pam新sshd启动后走的就是PAM认证流程。如果PAM配置不兼容会出现密码正确但登录直接被拒绝的诡异问题。看起来像密码错了实际上是PAM会话建立失败。2.2 修复CentOS7的yum源确保依赖能装上CentOS7停服之后默认源里的mirrorlist已经指向不存在的地址了。你直接yum install大概率会报Could not retrieve mirrorlist。这就是热搜词里centos7更换国内yum源的由来。我的处理方式是切换到vault源这是官方留给停服版本的最后通道# 把旧源的mirrorlist注释掉baseurl切到vault sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-*.repo sed -i s|#baseurlhttp://mirror.centos.org|baseurlhttp://vault.centos.org|g /etc/yum.repos.d/CentOS-*.repo # 重建缓存 yum clean all yum makecache如果你用的是HoRain云这类云平台也可以看看控制台里有没有提供内网镜像源那个速度会更快而且不需要走公网流量。2.3 开启telnet作为应急后门这一步很多人不理解觉得多此一举。我讲一个真实教训有次我在一台实体服务器上升级sshd编译都成功了替换二进制之后想着应该没问题就直接service sshd restart。结果SELinux上下文没刷sshd起不来而远程SSH会话已经被我亲手掐断了。那一刻的感受真的很难形容。所以我现在养成了一个习惯升级sshd之前先开telnet作为保底通道。CentOS7上安装telnet服务非常简单yum install -y telnet-server telnet systemctl enable --now telnet.socket然后确认23端口监听正常ss -lntp | grep 23在云服务器上你还得去安全组或防火墙放行TCP 23端口。telnet是明文协议这个通道只用于应急等新的sshd确认能登录之后必须第一时间关掉systemctl disable --now telnet.socket2.4 安装编译依赖源码编译OpenSSH需要以下工具和库缺一个都会在configure或make阶段报错yum install -y gcc make wget tar yum install -y openssl-devel zlib-devel pam-devel libselinux-devel重点说一下openssl-devel。CentOS7自带的OpenSSL版本是1.0.2k如果你要编译OpenSSH 9.8p1这个版本偏旧configure时大概率会遇到类似这样的报错checking OpenSSL header version... not found这时有两条路可以走一是在configure时指定--with-ssl-dir指向已有的openssl路径二是先编译一份新版OpenSSL装到/usr/local/openssl再让sshd的configure去引用。我实测下来第二条路虽然多花一点时间但最稳妥因为新版OpenSSH对新版OpenSSL的调用逻辑更加顺手。3. 编译安装新版OpenSSH的完整操作3.1 下载源码并校验完整性从OpenSSH官网或者GitHub镜像下载源代码我习惯放到/opt/src目录下统一管理mkdir -p /opt/src cd /opt/src wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz.sig如果下载GitHub镜像的release包也一样记得看下SHA256校验值避免下载到被篡改的文件。官方包一般会给出SHA256摘要验一下再解压sha256sum openssh-9.8p1.tar.gz3.2 编译安装的关键参数解压并进入源码目录之后configure这一步是整个编译安装的核心。我的参数如下tar -zxvf openssh-9.8p1.tar.gz cd openssh-9.8p1 ./configure \ --prefix/usr/local/openssh \ --sysconfdir/etc/ssh \ --with-pam \ --with-zlib \ --with-ssl-dir/usr/local/openssl \ --with-md5-passwords \ --with-selinux每个参数的用意我说一下--prefix/usr/local/openssh把新sshd安装到独立的目录不直接覆盖系统自带文件保留回滚余地。--sysconfdir/etc/ssh让新版sshd继续读取/etc/ssh/sshd_config这个路径这样你现有的公钥、客户端配置都能继续使用。如果漏了这个参数新sshd默认会去/usr/local/openssh/etc下找配置最后你会看到一个没有任何配置也能启动的sshd实际上它什么都没加载非常危险。--with-pam启用PAM认证支持和系统现有的账号认证体系保持一致。--with-ssl-dir指定新版OpenSSL的安装目录。如果前面没有单独编译OpenSSL这里可以省略让configure自动找系统默认路径。--with-selinux支持SELinux上下文检查这个参数在CentOS7上强烈建议保留。3.3 make编译和安装configure成功之后编译就比较机械了make -j$(nproc)-j参数可以指定并行编译的线程数-j$(nproc)的意思是用服务器全部CPU核心来编速度最快。我实测在2核4G的云主机上9.8p1这个版本的编译时间大概是三五分钟。编译通过后先别急着make install先看一眼编译出的新sshd版本./sshd -V这里会输出类似OpenSSH_9.8p1的字样。确认版本没错再执行安装make install3.4 替换旧版sshd并处理SELinux上下文make install之后新sshd装到了/usr/local/openssh/sbin/sshd。现在我们要用新版本替换系统默认的/usr/sbin/sshdcp -p /usr/sbin/sshd /usr/sbin/sshd.bak.$(date %Y%m%d) cp -p /usr/local/openssh/sbin/sshd /usr/sbin/sshd # 刷新SELinux上下文这一步不能省 restorecon -Rv /usr/sbin/sshd如果省略restoreconSELinux会认为这个文件是从奇怪路径复制来的启动时直接拒绝执行。当年我就是卡在这里。然后测试一下配置文件的语法/usr/sbin/sshd -t一切正常的话重启sshd服务systemctl restart sshd systemctl status sshd用新的SSH连接进来测试确认能正常登录之后再看一眼当前的版本ssh -V如果显示的是OpenSSH_9.8p1说明升级成功了一半。为什么说一半因为版本更新只是第一步安全配置才是重头戏。4. sshd_config安全加固从能连上到连得安心4.1 安全的SSH配置长什么样新版OpenSSH装好了但如果sshd_config还是老一套那基本等于穿着一件防弹衣却敞开着门。我自己给HoRain云那台服务器定的基线配置是这样的# 修改监听端口默认22端口是机器人扫描的重灾区 Port 22122 # 协议版本直接锁到21.x协议早该入土了 Protocol 2 # 禁止root直接登录需要用普通用户登录后su切换 PermitRootLogin no # 禁止密码登录只允许密钥认证 PasswordAuthentication no PubkeyAuthentication yes # 禁止空密码 PermitEmptyPasswords no # 登录失败次数限制和超时时间 MaxAuthTries 3 LoginGraceTime 30 # 会话保持检查防止僵尸连接占着线路 ClientAliveInterval 300 ClientAliveCountMax 0 # 只允许指定用户登录避免其他弱账号被利用 AllowUsers ops admin # 关闭DNS反向解析和GSSAPI认证这俩是连接受阻的元凶 UseDNS no GSSAPIAuthentication no逐条说一下关键考量。把SSH放到非22端口说实话防不住有耐心的人毕竟nmap一扫描每个端口都无所遁形。它的真实价值在于过滤掉那些只对着22端口跑的自动化蠕虫和扫描脚本。这些脚本占了暴力破解流量的绝大多数改掉端口之后安全日志的骚扰量能下降好几个数量级。PermitRootLogin no这条很多人觉得不方便因为平时已经习惯了root直接登录。但你想想root是服务器上最高权限的账号如果有人猜到了root密码整台服务器就没了。使用普通用户登录再通过sudo或者su切换root至少多了一道门槛而且审计日志里能看到是谁在什么时候用了root权限。4.2 配置密钥登录的完整步骤密钥认证是这套安全配置的核心。配置之前要注意一个顺序问题千万不要先关掉密码认证再生成密钥否则你很可能把自己锁在门外。正确顺序是先配置好密钥登录确认能用了再回头关闭密码认证。生成密钥推荐使用ed25519算法它比传统的RSA 2048更短但安全性更高而且OpenSSH 9.x系列对它的支持已经非常成熟# 在本地电脑上生成密钥对 ssh-keygen -t ed25519 -C ops-workstation # 然后把公钥拷贝到服务器上 ssh-copy-id -p 22122 ops服务器IP如果你用的不是默认的22端口ssh-copy-id需要指定-p参数。如果没有ssh-copy-id命令也可以手动把公钥追加到服务器的~/.ssh/authorized_keys中mkdir -p ~/.ssh chmod 700 ~/.ssh echo ssh-ed25519 AAAA...你的公钥内容... ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys这里有个权限细节必须强调authorized_keys文件的权限必须是600.ssh目录的权限必须是700。如果权限过于宽松sshd会认为文件不安全直接拒绝加载你的公钥。我见过太多人排查半天最后发现是chmod的问题。密钥配置好后在本地电脑上测试ssh -p 22122 ops服务器IP能直接免密登录说明密钥认证已经生效这时候再回头打开sshd_config把PasswordAuthentication改成no。4.3 用fail2ban拦住暴力破解即便关闭了密码登录SSH服务依然可能被大量无效请求骚扰。Fail2ban是解决这个问题的老牌工具CentOS7上如果需要最新版本建议先装EPEL仓库yum install -y epel-release yum install -y fail2ban然后写一个针对SSH的jail配置# /etc/fail2ban/jail.local [sshd] enabled true port 22122 filter sshd logpath /var/log/secure maxretry 3 bantime 3600 findtime 300含义很简单5分钟内尝试登录失败3次就封禁1小时。这个策略对云服务器尤其管用因为你的SSH端口随时随地都在被互联网扫描器光顾。启动fail2ban并设为开机自启systemctl enable --now fail2ban用fail2ban-client查看封禁效果fail2ban-client status sshd如果看到Banned IP list里有大量陌生的IP地址别慌这正是它工作的证明。4.4 防火墙和安全组联动改完SSH端口之后云服务器控制台的安全组在22端口放行了新端口22122也得放行同时可以考虑把22端口的安全组规则删掉。命令行层的防火墙操作我一般这样处理# 放行新SSH端口 firewall-cmd --permanent --add-port22122/tcp firewall-cmd --reload这里要特别提醒一下先别急着删22端口的放行规则等你确认22122端口能正常SSH登录之后再回头清理22端口的规则。如果你用的是fail2ban它默认会读取sshd_config里的端口配置所以port 22122要写对。这里的顺序逻辑和前面密钥配置是一样的永远给自己留一条能回去的路。5. 升级过程最容易翻车的几个坑这部分是我实际踩过、也帮别人排查过的内容每一个都是真实场景不是网上抄来的。5.1 编译时报错OpenSSL版本不支持我在编译新版OpenSSH时第一次遇到的坑就是系统OpenSSL版本太低。报错信息里面提到了版本检查失败但不会直接告诉你怎么解决。我当时的处理是先确认了一下系统当前的OpenSSL版本openssl version -a如果你看到的版本是OpenSSL 1.0.2k-fips那我建议直接走独立编译OpenSSL的路子编译到/usr/local/openssl目录然后再回头给OpenSSH的configure指定--with-ssl-dir/usr/local/openssl。编译OpenSSL的步骤本身不算复杂但要注意它的configure脚本参数优先用shared方式生成动态库否则后续链接会找不到so文件。5.2 新sshd启动失败问题出在SELinux我前面提到的restorecon就是针对这个坑的。替换完/usr/sbin/sshd之后如果启动sshd时日志里出现类似Permission denied的文字很大概率就是SELinux的上下文类型不对。执行一下restorecon -Rv /usr/sbin/sshd再尝试启动问题基本能解决。如果你实在怀疑SELinux配置有问题可以先用getenforce看当前模式临时用setenforce 0切到宽容模式做对比测试。但记住这是排查手段不是最终方案。排查完之后一定要记得setenforce 1恢复强制模式。我在安全配置的过程中SELinux最终是保持强制开启状态的配合restorecon之后新sshd运行完全正常。5.3 登录时报错Permission denied (publickey)新版本OpenSSH默认对密钥文件的权限要求更加严格。检查一下服务器上的~/.ssh目录和authorized_keys文件权限chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chown -R 用户名:用户名 ~/.ssh还有一个容易被忽略的地方如果服务器的家目录本身权限过于宽松比如/home/ops的权限是777新版sshd的StrictModes特性也会拒绝加载公钥。把家目录改成755或者更严格chmod 755 /home/ops5.4 SSH连接特别慢卡在输密码之前这个问题很常见尤其是新装的服务器。连接建立之后要等十几秒才提示输密码效率很低。根本原因就是sshd默认开启了DNS反向解析和GSSAPI认证。在最开始升级时我就把UseDNS no和GSSAPIAuthentication no写进了sshd_config改完之后连接速度立竿见影。如果你手头已经有一台连接慢的服务器去配置里加这两行重启sshd就行。5.5 改完端口连不上了怎么排查假设你已经改完端口客户端连接还按老端口走肯定连接失败。排查链路我按这个顺序来# 1. 确认sshd正在监听新端口 ss -lntp | grep 22122 # 2. 确认防火墙没拦截 firewall-cmd --list-all # 3. 确认安全组放行了新端口 # 4. 确认客户端用的端口是对的 ssh -p 22122 ops服务器IP这四步检查了服务器进程、本地防火墙、云平台安全组和客户端配置覆盖了95%以上的改端口后连不上问题。还有一个容易被忽视的点是SELinux对端口的限制CentOS7的SELinux默认只允许sshd监听22端口如果你改了端口而不更新SELinux策略sshd启动时可能会被拒绝。处理方式很简单yum install -y policycoreutils-python semanage port -a -t ssh_port_t -p tcp 221226. 安全加固完成后的验证与回退方案6.1 怎么确认加固真正生效配置做完之后别急着收工做一轮完整的验证。我把验证分成三个维度。第一是版本维度/usr/sbin/sshd -V ssh -V确认客户端和服务端都是新版本不存在服务端升级成功、客户端还连着旧协议的版本差。第二是配置维度/usr/sbin/sshd -t sshd -T | grep -E port|permitrootlogin|passwordauthentication|pubkeyauthentication|allowuserssshd -T会输出实际的生效配置这个命令比看配置文件更可靠因为它展示的是sshd真正加载的值。第三是行为维度用密码登录测试一下应该被拒绝用密钥登录测试一下应该成功。再配合fail2ban连续输错几次密码确认IP被封锁。6.2 回滚方案到底怎么做才靠谱任何一个升级操作都必须提前想好如果失败了怎么退回去。我们的整个设计里新sshd安装在/usr/local/openssh系统默认的旧文件都留了备份所以回滚逻辑非常清晰。# 恢复备份的sshd二进制 cp -p /usr/sbin/sshd.bak /usr/sbin/sshd # 恢复备份的配置目录 rm -rf /etc/ssh cp -rp /etc/ssh.bak.日期 /etc/ssh # 重启服务 systemctl restart sshd这里有一个心态层面的建议回滚不是失败而是运维流程的一部分。不要觉得已经花了这么多时间编译安装回滚好丢人。服务器能稳定运行比什么都重要。我在HoRain云上升级第一台服务器时也提前把回滚脚本写好了虽然最后没用上但心里踏实很多。6.3 验证密钥登录和fail2ban的实际效果全部配置完成后我个人习惯再做一次破坏性测试故意用错误的密码登录三次然后看fail2ban有没有把当前IP封掉。fail2ban-client status sshd看到封禁列表里出现自己的测试IP反而很安心说明这个防御闭环真的在运转。测试结束之后再用密钥正常登录一次确认没有被自己的安全策略误伤。再到云控制台看一眼安全组规则确认22端口已经不再对外放行SSH的公网入口只剩下22122。到这一步一台CentOS7云服务器的OpenSSH升级和安全加固才算画上句号。整个流程我在多台服务器上重复过稳定跑了两轮没有出现过回滚的情况。最后再分享一个实用习惯每次升级完sshd我都会把当次的配置基线、编译参数、遇到的坑以简短备注的形式记录在一个运维笔记里。下次遇到同类问题翻笔记比重新摸底快太多了。这套操作看起来步骤多但走完一遍之后你会发现它带来的安全感和掌控感是值得的。
返回列表