news 2026/10/8 2:54:20

KeyarchOS日志审计实战:基于src.rpm构建logwatch RPM包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KeyarchOS日志审计实战:基于src.rpm构建logwatch RPM包

前几天在给一台浪潮信息KeyarchOS(KOS)服务器做日志审计的时候,发现系统里日志文件越堆越多,却没有一个能每天早上自动汇总关键事件的工具。翻遍系统默认仓库,logwatch没有被收录;直接去网上找一个现成RPM,装完又是一堆Perl依赖问题,要么版本不对、要么路径跑偏。折腾下来,最靠谱的办法就是从官方src.rpm开始,在KOS上完整走一遍rpmbuild编译、配置、部署的流程。这篇文章就是把整个过程复盘一遍,适配对象是浪潮信息KeyarchOS,软件版本logwatch-7.3.6-55。适合两类人:一是KOS上做基础运维、希望把日志分析自动化补全的同学;二是想把主流开源组件迁移到KOS上做成正式RPM包的编译党。我会把中间踩过的坑、改过的spec、验证过的命令全部列出来。

1. 为什么要在KeyarchOS上给logwatch做适配

1.1 先搞清楚KOS是什么

浪潮信息KeyarchOS(KOS)本质上是面向数据中心场景的企业级Linux发行版,底层沿用标准Linux内核,包管理、服务管理、网络配置这些习惯和主流企业级Linux生态保持一致。它针对浪潮自家服务器硬件做了很多专项优化,比如固件带外管理、驱动适配、安全加固等。对运维来说,刚上手KOS时基本不会有陌生感,dnf install、systemctl这些命令照用不误。

但问题也出在这里。主流企业级Linux生态的软件仓库虽然庞大,却不可能把每个实用小工具都收录进去。logwatch这类“日志分析辅助工具”在默认源里的地位相当边缘,要么没有,要么版本落后。我在KOS上dnf search logwatch的结果是空的,第一反应是从CentOS生态找一个二进制包直接装,结果装上之后logwatch --version报缺少Perl模块。这就是典型的“二进制包能装上,但跑不起来”。

所以“适配”这两个字,不是简单把软件拷过来,而是要让它在KOS的目录结构、Perl路径、依赖声明都正确的前提下,作为系统原生软件包运行起来,并且能被dnf统一管理。

1.2 logwatch能解决什么实际问题

logwatch是一个用Perl写的日志分析聚合工具。它的工作模式很简单:定期扫描指定日志,把sshd登录失败、sudo提权记录、磁盘空间不足、服务重启、防火墙拦截这些事件分类汇总,生成一份可读的摘要报告,再通过邮件发送给管理员。

服务器日志管理有个真实痛点:日志量太大,人工翻不动。/var/log/secure一天能刷几百行,大部分是无效信息,但里面偶尔藏着暴力破解的关键迹象。logwatch的价值就是它内置了30多类服务的解析脚本,自动做排序、去重、归纳,最后只把核心信息呈现出来。相比自己写shell脚本轮询,logwatch的规则沉淀和输出格式都是现成的,省掉很多重复造轮子的时间。

选择7.3.6-55而不是更新版本,是经过考虑的。7.3.6这个上游版本在主流企业级生态里已经非常稳定,各功能模块基本冻结,不会频繁变动。55这个release号代表发行版维护补丁已经叠加了很多轮,比较成熟。另外,logwatch的核心依赖是Perl环境和少量Perl模块,版本越新越可能要求更新的Perl构建特性,反而增加适配复杂度。稳字当头,选这个版本最合适。

1.3 不直接装二进制的三个理由

我一开始图省事,尝试过直接装CentOS/RHEL系的logwatch RPM,也试过从GitHub拉源码make install,两条路都走不通,或者说不值得走。

第一条路是二进制兼容风险。不同发行版对Perl模块的路径定义有差异,/usr/lib/perl5和/usr/share/perl5的划分规则不一定一样,依赖的perl模块版本也可能和KOS自带的Perl版本有冲突。装的时候可能一切顺利,跑的时候才暴露问题,排查成本反而更高。

第二条路是源码直接make install。这是最不可取的做法,因为装完的文件散落在/usr/local/bin、/usr/local/share等路径,完全脱离dnf的管理体系。以后想升级、卸载、批量分发,都变成麻烦事。对正规审计环境来说,网络上下载的脚本文件如果不在RPM台账里,连安全合规都不好交代。

最终结论只有一个:拿到src.rpm,在当前系统上重新构建出适配KOS环境的RPM包。构建产物再导入本地仓库,以后任何一台KOS机器都能dnf install,这是最干净的方案。

2. 适配方案选型:直接装、源码装还是RPM构建

2.1 三种做法对比

我把三条路线放在一起做过对比,整理成一张表,方便你根据自己环境判断。

做法优点缺点适用场景
在线仓库直接安装速度快、一条命令搞定KOS默认源基本没收录logwatch一般发行版有现成包时
下载其他发行版二进制RPM省去编译环节依赖不匹配、路径差异、版本兼容待验证临时验证功能时
源码编译并make install完全可控、可自定义不受dnf管理、升级卸载困难、批量分发难开发调试、个人临时使用
源码src.rpm重建RPM生成正式RPM、纳入仓库管理、可复现需要理解spec构建流程正式生产适配

2.2 为什么最终选择src.rpm重建

我选src.rpm重建,核心逻辑是“复用上游构建配方”。src.rpm里面包含的不只是源码压缩包,还有spec文件、补丁、构建说明。spec文件就是构建说明书,定义了软件装哪些文件、依赖什么包、安装到哪里、有什么前置脚本。基于同一个spec重新构建,能最大程度保留上游的补丁和经验,避免自己从零写安装脚本时漏掉细节。

可能有人会问,为什么不直接用源码包自己写一个spec?说实话,对logwatch这种文件散落多个目录的Perl应用,自己写spec很容易在%files段落漏掉配置文件、脚本目录、文档目录,构建完要么缺文件,要么rpm -V校验不过。基于官方src.rpm改,效率和安全都更有保障。

2.3 规划交付产物

整个适配的目标产物很清晰:一个noarch架构的RPM包,加上配套的本地仓库索引。logwatch是纯Perl脚本应用,不涉及CPU平台相关二进制编译,所以构建出来的包是noarch,x86_64和aarch64架构都能装。这意味着只要在一台构建机上跑通构建,其他架构的KOS服务器可以直接复用产物,不需要每台机器各编译一遍。

交付物清单包括:

  • logwatch-7.3.6-55.*.noarch.rpm(二进制包)
  • logwatch-7.3.6-55.*.src.rpm(源包,留档备查)
  • 修改后的spec文件
  • 本地仓库repodata索引(用于批量分发)

3. 编译前准备:环境搭建与依赖分析

3.1 准备一台干净构建机

编译的第一原则,不要在正在运行业务的生产机上直接构建。构建过程中可能会安装额外的开发工具、生成临时文件,甚至触发安全扫描告警。最好准备一台和线上环境同版本KOS的独立虚拟机或小机器,专门做构建。

进入构建机后,先确认系统信息。

cat /etc/os-release uname -m perl -v

第一项确认KOS版本和构建机一致,保证产物的兼容性。第二项确认架构,虽然目标是noarch包,但构建机的Perl环境会影响构建过程中的路径生成逻辑。第三项确认Perl版本,logwatch依赖的Perl模块需要和当前Perl版本兼容。

3.2 安装rpm构建工具链

KOS默认安装可能没有完整的rpm构建工具链,需要手动装上。

sudo dnf groupinstall -y "Development Tools" sudo dnf install -y rpm-build rpmdevtools createrepo rpmdev-setuptree

rpmdev-setuptree会在当前用户家目录创建标准构建目录结构:~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}。每个目录都有明确职责:SOURCES放源码压缩包和补丁,SPECS放spec文件,BUILD是构建过程的工作目录,RPMS输出二进制包,SRPMS输出源包。

有人可能觉得logwatch是纯脚本应用,不需要装“Development Tools”这种重型工具组。但从我的实操经验看,装全编译工具链更稳。原因有两层:第一,spec文件里可能有附带perl模块的编译操作,需要gcc;第二,后续想在这个构建机上适配其他软件时,工具链现成,不用重复安装。反正构建机不对外提供服务,多装一点无妨。

3.3 梳理Perl模块依赖

logwatch本体是Perl脚本,所以对Perl环境和特定模块有依赖。主模块包括日期解析相关的Date::Manip、Date::Format,还有邮件发送相关的Mail模块。在KOS里需要找到对应的包名。

dnf search perl-Date-Manip dnf search perl-Date-Format

KOS基于企业版Linux生态,包命名规则和上游基本一致。perl-Date-Manip对应Date::Manip模块,perl-Date-Format对应Date::Format。如果dnf源里这些包没有收录,就需要启用仓库补充源,或者用dnf provides 'perl(Date::Manip)'反查哪个包提供了这个模块。

这里多说一句,Perl模块包装名和模块名经常不完全一样。搜不到包的时候,用dnf provides比用dnf search更高效。比如dnf provides '*/Date/Manip.pm',直接按文件路径反查,命中率更高。

4. 完整编译流程:从src.rpm到可安装RPM

4.1 下载并解包src.rpm

构建的起点是拿到官方维护的src.rpm包。可以从上游rpm镜像的source目录下载,也可以从项目托管平台的release页面找。下载完成后先做校验,养成好习惯:

wget https://example.com/logwatch-7.3.6-55.src.rpm sha256sum logwatch-7.3.6-55.src.rpm

校验值和官方公布的一致再继续。实际踩过坑,下载不完整时rpm命令会直接报错rpm: not an rpm package,白白浪费时间排查网络问题。

导入src.rpm的动作很简单:

cp logwatch-7.3.6-55.src.rpm ~/rpmbuild/SRPMS/ rpm -ivh ~/rpmbuild/SRPMS/logwatch-7.3.6-55.src.rpm

执行后,~/rpmbuild/SOURCES/会出现源码包和补丁文件,~/rpmbuild/SPECS/出现logwatch.spec。有时候系统会提示package logwatch-7.3.6-55 is already installed,这是因为构建机上可能残留旧版本,用rpm -Uvh --force强制覆盖即可。

如果好奇src.rpm里面都有什么,可以用rpm2cpio logwatch-7.3.6-55.src.rpm | cpio -t列文件清单,再解包查看。

4.2 读懂并修改spec文件

打开spec文件,重点看几个关键段落。

Name: logwatch Version: 7.3.6 Release: 55%{?dist} BuildArch: noarch BuildRequires: perl(ExtUtils::MakeMaker) perl(Date::Manip) Requires: perl(Date::Manip) perl(Date::Format)

第一处要改的是Release。原值55%{?dist}在企业版Linux上会带发行版标识,KOS上构建时会自动加上KOS相关的dist字段。为了区分自建产物,我在Release后面追加了.kos1,变成55%{?dist}.kos1,这样一眼能看出是什么环境下编译的,后续维护也方便。

第二处关注BuildArch。logwatch是纯脚本应用,保持noarch不动。这样产出的RPM包不绑定CPU架构,KOS的x86_64和aarch64机器都能装。

第三处是依赖声明。spec里的Requires会自动检查Perl模块是否存在,并且支持版本号约束。之前网上那个二进制包缺模块的问题,本质就是Requires没有覆盖完整。我们自己的构建可以保留上游的依赖声明,以当前KOS环境为准补全。

4.3 拉取编译依赖

spec文件准备好后,用dnf自动解析BuildRequires:

cd ~/rpmbuild/SPECS sudo dnf builddep -y logwatch.spec

dnf builddep会把spec里声明的BuildRequires逐个通过仓库解析并安装,省去手动找依赖的功夫。实测下来,KOS在线源里大部分包都能找到,但如果某个perl模块在默认源里没有,builddep会报Unable to find a match,这时候就得手动补装:

sudo dnf install -y perl-Date-Manip perl-Date-Format perl-MailTools

手动补装的原则是缺什么装什么,不要一口气把能猜的包全装一遍。构建报错信息会明确告诉你是哪一行Perl代码加载哪个模块失败,按需补装最精准。

4.4 执行rpmbuild并处置构建异常

一切准备就绪,开始正式构建:

rpmbuild -ba SPECS/logwatch.spec

-ba的意思是Build All,同时构建二进制包和源包。构建过程会依次执行spec里的%prep解包打补丁、%build编译配置、%install安装到临时目录、生成RPM元信息、打包归档。如果一切顺利,~/rpmbuild/RPMS/noarch/下会出现logwatch-7.3.6-55*.noarch.rpm,~/rpmbuild/SRPMS/下会出现新的src.rpm。

构建期最容易遇到的报错有几种:

  • error: Bad exit status from /var/tmp/rpm-tmp.xxxxx (%build)。这种报错信息本身不说明原因,后边跟着的才是重点。需要去/var/tmp/rpm-tmp.xxxxx文件里看实际执行了什么命令、哪一步返回了非零状态。
  • Installed (but unpackaged) file(s) found。构建过程把文件装到了buildroot,但spec的%files段没有声明这些文件。解决办法是去%files段把缺失的文件路径补上。
  • File must begin with "/"。%files里写了相对路径或者空行导致格式不对,检查文件列表每一项都必须是绝对路径。

遇到报错不要急着全量重新构建,用rpmbuild -bi只执行到安装阶段,或者rpmbuild -bc只执行到编译阶段,能大幅缩短调试循环。我在调试过程中用这个技巧,把一个构建问题从5分钟一次缩短到1分钟一次,效率提升很明显。

5. 安装配置与KOS生态接入

5.1 安装RPM并做功能验证

构建产物出来后,先在构建机本机安装验证:

sudo dnf install ~/rpmbuild/RPMS/noarch/logwatch-7.3.6-55*.noarch.rpm which logwatch logwatch --version

确认命令能识别后,再跑一次手动生成日志报告:

logwatch --print --service sshd --range today

这条命令会扫描今天的sshd日志,把结果直接打印到终端。如果输出为空,优先检查系统是否有/var/log/secure或/var/log/auth.log文件。KOS默认使用systemd的journald做日志采集,有些日志文件可能没有传统text文件。后续再细说这个问题。

5.2 core配置项逐一解读

logwatch安装后,全局配置文件位于/etc/logwatch/conf/logwatch.conf。如果没有这个文件,可以从/usr/share/logwatch/default.conf/logwatch.conf复制一份再改。默认配置可以直接跑,但生产环境建议至少调整下面几项。

MailTo = ops@example.com Range = yesterday Detail = Med Service = All Output = mail Format = text LogDir = /var/log

MailTo指定报表收件人。Range定义日志范围,生产环境用yesterday最合适,每天报告前一天的完整日志。Detail控制报告详细程度,Low只给摘要,Med给主要细节,High给全部细节,建议从Med开始调。Service设为All表示扫描所有logwatch能识别的服务,也可以按需指定为Service = sshd, sudo, kernel-message。Output设为mail配合定时任务,就能每天自动发送报告。

有一点值得注意,Format = text或html。如果邮件客户端对HTML支持好,用html格式排版更清晰;如果只是纯文本监控,text更省空间。我实测KOS邮件环境下text格式最通用,不容易被邮件网关拦截。

5.3 接入cron与邮件投递

logwatch装完后系统一般会自动生成/etc/cron.daily/0logwatch定时脚本,这个脚本会读取配置并执行每日报告。需要确保crond服务在运行:

systemctl enable --now crond cat /etc/cron.daily/0logwatch

定时任务本身不复杂,真正的坑在邮件投递上。KOS默认可能没有装MTA(邮件传输代理),logwatch发邮件会静默失败。测试邮件可以手动执行:

logwatch --mailto ops@example.com --service all --range yesterday --output mail --format text

如果没收到邮件,先检查/var/log/maillog。用postfix做本地投递的话,先安装postfix:

sudo dnf install -y postfix sudo systemctl enable --now postfix

postfix默认只做本地投递,把邮件投递到本机用户的mailbox。如果想发到外部邮箱,需要额外配置smtp relay,这部分和logwatch本身无关,但在生产环境里绕不开。我一般会在postfix里配一个对外的relay地址,把日志邮件统一投到运维告警邮箱。

5.4 把RPM纳入本地仓库

单机安装RPM只是完成了第一步,真正有价值的做法是把构建产物放入本地仓库。这样更多KOS服务器无需拷贝包,一条dnf命令就能安装。

sudo mkdir -p /srv/repo/kos/base/x86_64 cp ~/rpmbuild/RPMS/noarch/logwatch-7.3.6-55*.noarch.rpm /srv/repo/kos/base/x86_64/ sudo createrepo /srv/repo/kos/base/x86_64/

然后在客户端机器上写repo文件:

cat > /etc/yum.repos.d/kos-local.repo <<'EOF' [kos-local] name=KOS Local Repo baseurl=http://your-repo-server/srv/repo/kos/base/x86_64/ gpgcheck=0 enabled=1 EOF

如果仓库只在单机使用,baseurl可以写成file:///srv/repo/kos/base/x86_64/。多机共享时用nginx或httpd把仓库目录暴露出去就行。本地仓库配合createrepo,是批量分发自建RPM最标准的方式。

需要留个心:如果仓库面向正式的严肃环境,建议用rpm --addsign给RPM做GPG签名,并把客户端repo的gpgcheck设为1。本地内网环境为了简单可以gpgcheck=0,但这个开关一旦放宽,RPM内容就完全靠仓库本身的安全来保证,风险自负。

6. 实战排错:6类高频问题一次说清

6.1 高频报错速查表

现象可能原因处理建议
dnf builddep找不到依赖默认源缺少perl包装包用dnf provides反查或用补充源安装
rpmbuild报Bad exit status%build阶段某个命令返回非零查看/var/tmp/rpm-tmp.*脚本定位具体命令
Can't locate Date/Manip.pm in @INC缺少perl-Date-Manip模块dnf install perl-Date-Manip
/usr/bin/env: 'perl': No such file系统没有装Perldnf install perl
logwatch --print无输出指定服务的日志文件不存在检查/var/log下对应服务日志
邮件报表收不到MTA未配置或MailTo写错查看/var/log/maillog,配置postfix

6.2 一个典型编译失败案例复盘

我在KOS上第一次跑rpmbuild -ba的时候,报错出现在%build阶段。错误信息很长,核心是Can't locate Date/Manip.pm in @INC。这个错误说明系统Perl环境里没有Date::Manip模块,而spec的BuildRequires声明的依赖没有被正确解析。

排查流程是这样的:先看dnf builddep是否完整执行,发现执行到一半有包找不到被跳过;再dnf provides '*/Date/Manip.pm'确认包名,补齐后重新builddep,问题解决。这个案例很有代表性,很多“编译失败”本质上是依赖没有装全,而不是代码本身有问题。构建报错信息里如果出现Can't locate,十有八九是缺Perl模块,按需安装最有效。

6.3 运行期日志源与邮件投递问题

logwatch正常安装后,另一个容易踩的坑是日志文件不存在。KOS使用journald采集系统日志,默认不一定会生成传统文本日志文件。logwatch默认从/var/log目录读取文本日志,如果对应服务的日志没有落盘,报告就是空的。

解决办法是在logwatch自定义脚本层面做适配。比如为某个服务写一个自定义脚本,用journalctl从journald拉取日志再格式化成logwatch能识别的文本流。具体可以在/etc/logwatch/scripts/services/下新建脚本文件,并在/etc/logwatch/conf/services/下加入对应配置项。这个能力是logwatch比较灵活的体现,遇到日志源差异时不需要改核心代码,只需要适配数据来源。

邮件投递的排查也同样明确。先确认logwatch --print有内容输出,再查邮件。如果mail命令可用,直接mail查看本地mailbox;如果记录在/var/log/maillog里显示status=sent但收件人没收到,那是外部smtp relay或邮件网关的问题,跟logwatch本身无关。

6.4 自定义服务脚本的扩展思路

生产环境里总会遇到logwatch内置脚本覆盖不到的应用日志。我曾经给一个内部应用写过一个自定义日志脚本:在/etc/logwatch/scripts/services/myapp目录下写解析脚本,在/etc/logwatch/conf/services/myapp.conf里声明日志路径和输出级别。加入之后,logwatch的Service = All会自动识别这个新服务,报告里就会出现对应分类。

这个机制的价值在于,logwatch不是一个封闭工具,它对“新日志类型”的扩展成本很低。把自定义脚本和配置做成RPM的一部分,还能随logwatch一起批量部署到所有KOS节点。适配到这一步,基本算是把logwatch从“可以用”变成了“好用”。


整个适配过程做下来,我最大的体会是:KOS环境下的软件适配并没有多神秘,关键是把构建配方(spec)和系统依赖这两件事处理好。不要图省事用make install,也别看到一个二进制包就想直接装,花点时间把src.rpm重新构建成原生RPM,后续的安装、分发、升级才能进入正轨。另外一个额外收获是我把本地仓库也顺手搭起来了,以后在KOS上适配的任何一个自建RPM都会丢进去,组里的其他机器再也不用靠拷包过日子。这套流程虽然是以logwatch为例,但对其他脚本类工具的KOS适配同样适用,你可以当作一套模板保存下来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 2:54:00

Qt安装全指南:版本选择、镜像加速与常见报错排查

“Qt安装”这四个字&#xff0c;看起来平平无奇&#xff0c;实际坑起来能让人怀疑人生。我见过太多人卡在第一步&#xff1a;官网下载几个小时超时、装完打开Qt Creator直接报qt.qpa.plugin: could not find the qt platform plugin "windows"、套件管理器里编译器全…

作者头像 李华
网站建设 2026/10/8 2:54:00

TTL、CMOS、ECL、LVDS、CML五种逻辑电平标准详解与电平转换实战

写这篇文章的起因&#xff0c;是上周帮朋友救砖一台路由器。板子上明明标着TTL串口&#xff0c;我拿了根USB转TTL的小板接上去&#xff0c;GND、TXD、RXD线序全都对&#xff0c;屏幕上却是一片乱码&#xff0c;偶尔蹦出几个正常字符。折腾了半小时才意识到&#xff0c;小板的跳…

作者头像 李华
网站建设 2026/10/8 2:53:59

栈与队列实战指南:从基础实现到全栈项目应用

栈与队列这两个词&#xff0c;在计算机科班课程里永远是排在最前面的那几章。当年学的时候觉得简单得不能再简单&#xff0c;不就是“后进先出”和“先进先出”嘛。可真到写项目、做全栈开发、甚至面试造轮子的时候才发现&#xff0c;这两个基础结构几乎是无处不在的——函数调…

作者头像 李华
网站建设 2026/10/8 2:53:46

DeepSeek农业大模型智算一体机:农机本地化AI决策方案

简介&#xff1a;本资源是一份面向农业信息化从业者、AI解决方案工程师及数字乡村建设规划人员的深度技术方案PPT&#xff0c;聚焦智慧农业与数字乡村融合场景下DeepSeek大模型驱动的智算一体机落地设计。方案系统阐述了四层总体架构&#xff08;决策层/技术层/应用层/设施层&a…

作者头像 李华
网站建设 2026/10/8 2:52:36

用BitDock在Windows上打造macOS风格Dock栏:高效桌面美化方案

我在Windows上折腾桌面美化的年头不算短了。从最早的 RocketDock&#xff0c;到后来的 ObjectDock&#xff0c;再到各种仿 macOS 的启动器&#xff0c;几乎都试过一遍。中间大概有两三年时间&#xff0c;我干脆放弃治疗&#xff0c;直接买了一台 MacBook 当主力机&#xff0c;图…

作者头像 李华
网站建设 2026/10/8 2:52:17

开源版Claude Code:DeepSeek/Qwen/GLM接入与实战

看到这个标题点进来的&#xff0c;咱们都是同类人&#xff1a;白天写接口、晚上修 bug&#xff0c;SQL 都没查完就被拉去开会的牛马。最近 GitHub 热门榜上全是 Claude Code 的身影&#xff0c;短视频里那些博主把需求往终端一贴&#xff0c;Agent 自己读代码、改文件、跑测试一…

作者头像 李华