CentOS系统的包管理安全底线其实就一句话:只从官方仓库拉取软件包,并且强制启用GPG校验。任何绕过这两道关卡的操作,都是在服务器上亲手打开后门。很多运维人员为了图方便,直接复制网上不明来源的repo文件,或者用"--nogpgcheck"参数跳过签名验证,这种操作和把服务器root密码贴在公网上没有本质区别。

为什么必须死守官方仓库

CentOS官方仓库里的每一个软件包,都经过了发行版维护团队的编译、测试和签名。这些包不仅与系统其他组件做过兼容性验证,更重要的是,它们来自受控的构建环境。第三方仓库比如EPEL、Remi虽然也是知名源,但它们的安全审计标准和官方并不在同一级别。EPEL由Fedora社区维护,已经算是相对可信的第三方,但Remi这类个人维护的仓库,其包构建过程你完全无法追溯。真正危险的是那些来路不明的一键安装脚本里带的repo文件,它们可能指向任何人控制的服务器,包里面植入后门、挖矿程序甚至rootkit都是常规操作。

判断一个仓库是否属于"官方"范畴,最简单的标准就是看域名。CentOS 7及之前的官方仓库域名是"mirror.centos.org",CentOS Stream以及后续的Rocky Linux、AlmaLinux等衍生发行版也都有各自的官方镜像域名。任何使用IP地址、短链接或者奇怪域名的仓库源,都应该直接拒绝。如果你需要安装官方仓库里没有的软件,优先考虑通过源码编译安装,或者使用容器化方案隔离运行环境,而不是盲目添加第三方源。

GPG校验的工作原理与重要性

GPG签名校验解决的核心问题是"这个包在传输过程中有没有被篡改"。当你执行"yum install"或者"dnf install"时,包管理器会做两件事:第一,从仓库下载RPM包;第二,用仓库的公钥验证这个包的GPG签名。如果签名不匹配,说明这个包要么在传输过程中损坏了,要么被人替换过。无论是哪种情况,包管理器都应该拒绝安装。

CentOS系统的官方GPG公钥在系统安装时就已经内置,路径通常在"/etc/pki/rpm-gpg/"目录下。你可以用"rpm -qa gpg-pubkey*"命令查看当前系统已经导入的所有公钥。每个官方仓库的repo配置文件里,都应该明确指定"gpgcheck=1"以及对应的"gpgkey"路径。如果你看到一个repo文件里写的是"gpgcheck=0",这就是一个巨大的安全漏洞,需要立即修复。

实战:正确配置YUM/DNF仓库文件

一个安全的repo配置文件应该长成下面这样。注意"gpgcheck=1"是硬性要求,"enabled=1"只对需要启用的仓库设置,不需要的仓库应该设为0或者直接删除对应的repo文件。

[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

这里有几个容易出错的地方需要特别注意。"mirrorlist"和"baseurl"一般只保留一个即可,mirrorlist会自动选择最快的镜像站,但如果你需要固定使用某个特定镜像源以保证一致性,就只写baseurl。"gpgkey"后面的路径必须指向真实存在的公钥文件,如果文件路径写错或者文件被删除,包管理器会直接报错拒绝安装,这是正常的安全机制,不要试图绕过它。

导入和验证GPG公钥的正确方法

如果你需要手动导入某个仓库的GPG公钥,标准做法是:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

导入之后,用以下命令验证公钥是否成功导入以及查看公钥详情:

rpm -qa gpg-pubkey* | grep centos
rpm -qi gpg-pubkey-f4a80eb5-53a7ff4b

这里有一个很多运维人员忽略的细节:公钥本身也有有效期。虽然CentOS官方公钥的有效期通常设置得很长,但如果你使用的是第三方仓库,一定要定期检查公钥是否过期。过期的公钥会导致GPG校验失败,而有些人遇到校验失败的第一反应是关掉gpgcheck,这是典型的错误操作。正确的做法是去仓库官网重新获取最新的公钥文件并导入。

强制全局启用GPG校验

除了在每个repo文件里单独设置"gpgcheck=1",你还可以在"/etc/yum.conf"或者"/etc/dnf/dnf.conf"主配置文件里设置全局默认值。在配置文件的"[main]"段落中加入:

gpgcheck=1

这样设置之后,所有仓库默认都必须进行GPG校验。即使某个repo文件里忘记写"gpgcheck=1",全局设置也会生效。但反过来,如果repo文件里明确写了"gpgcheck=0",它会覆盖全局设置。所以安全加固的正确流程是:先在主配置文件里设置全局gpgcheck=1,然后逐一检查"/etc/yum.repos.d/"目录下的所有repo文件,确保没有任何一个文件里出现"gpgcheck=0"。

处理离线环境下的GPG校验问题

很多企业生产环境是纯内网部署,无法连接互联网。这种情况下,运维人员通常会搭建本地镜像仓库。本地仓库同样必须配置GPG校验,不能因为"反正是内网"就关掉签名验证。搭建本地仓库时,你需要用官方ISO镜像或者从官方镜像站同步RPM包,同时把官方的GPG公钥文件一并复制到内网服务器上。本地仓库的repo配置文件和公网仓库的配置几乎一样,只是把baseurl指向内网地址,gpgkey指向本地公钥文件路径即可。

一个常见的错误做法是:用createrepo命令自己创建了一个本地仓库,里面放了一些从各种渠道收集来的RPM包,然后因为没有GPG签名,就直接把gpgcheck关掉。这种情况下,你完全无法保证这些RPM包的安全性。正确的做法是,如果你需要自己打包RPM,就应该建立自己的GPG密钥对,用私钥对包进行签名,然后把公钥部署到所有需要安装这些包的服务器上。这个过程虽然繁琐,但这是唯一能保证包来源可信的方法。

检测和清理系统中的第三方源

建议你立刻在服务器上执行以下命令,全面审计当前的仓库配置:

ls -la /etc/yum.repos.d/
cat /etc/yum.repos.d/*.repo | grep -E "gpgcheck|baseurl|mirrorlist"

重点检查有没有gpgcheck=0的配置,有没有指向非官方域名的baseurl。如果你发现了可疑的repo文件,不要直接删除,先用"yum repolist"查看这个仓库里安装了哪些包,评估影响范围之后再决定是迁移到官方源还是彻底移除。对于已经通过第三方仓库安装的软件包,可以用以下命令列出它们的来源:

rpm -qa --qf "%{NAME} %{VENDOR}\n" | grep -v "CentOS"

任何VENDOR字段不是CentOS官方或者你信任的供应商的包,都应该重点关注和审查。

纵深防御:包管理安全的补充措施

只依赖GPG校验还不够,因为它只能验证包的来源真实性,无法防御仓库服务器本身被攻破后分发恶意包的情况。虽然这种情况极少发生,但作为安全从业者,纵深防御思维必不可少。建议配合以下措施:定期使用"rpm -Va"命令校验已安装包的文件完整性,这个命令会检查每个包的文件权限、文件类型、MD5校验和等是否和安装时一致;对于核心系统文件,还可以叠加AIDE或者Tripwire这类文件完整性监控工具;另外,生产环境的软件包变更应该有严格的变更管理流程,任何新包的安装都应该经过审批和记录。

CentOS 7已经在2024年6月30日停止维护,如果你还在使用CentOS 7,迁移到Rocky Linux或者AlmaLinux是当务之急。这两个发行版完全兼容CentOS的生态,而且有活跃的安全更新支持。迁移过程中,仓库配置和GPG公钥都需要更新为新发行版的对应文件,这个步骤不能省略或者沿用旧的CentOS配置。