在 CentOS/Fedora 上查找(未)使用的软件包?

在 CentOS/Fedora 上查找(未)使用的软件包?

简而言之:从所有已安装的(rpm)包中,我想找出未使用的包(例如自过去 6 个月以来)。

长话短说:我拥有多台拥有良好服务记录的机器。每次我从一个版本升级到另一个版本时,我都会惊讶于升级过程的顺利程度。

然而多年来,许多软件包都是通过 yum 安装的,其中很多我知道已经不再使用了。我想摆脱这些软件包,因为它们对资源使用和系统的整体安全性有负面影响。

我正在寻找查找未使用的包的最佳方法。

一种方法是手动筛选已安装的软件包?这种方法很有效,我也学到了很多东西,但它非常耗时。

因此,我正在寻找一种自动化的方法来识别未使用的包,以便我可以手动清理它们。

我猜想一种解决方法是监控服务器上所有使用的文件,将它们链接到包并查看剩余的文件。有没有什么方法可以实现此目的?

还有其他更有创意的方法来实现这一目标吗?

答案1

考虑到 RPM 和共享库对多个软件包的共同性质,我将采用构建我实际使用的软件包列表并将其与已安装软件包列表进行比较的方法。删除未使用的软件包有好处,例如释放磁盘空间、减少有助于特权升级的软件包、减少校验和数据库(即 OSSEC、aide、tripwire)的大小。

假设

  • atime 已启用。如果您使用 noatime 的挂载选项,则文件的访问时间将不会更新,并且无法用于确定访问了哪些文件。在文件系统上设置 noatime 以避免写入惩罚是很常见的。

免责声明:这种方法存在一些风险,您需要考虑。例如,如果您的服务器已经运行了几年,那么可能会有守护进程运行,这些守护进程使用自服务器/守护进程启动以来您未访问过的旧文件。还有很多其他风险需要考虑,但您问了,所以我可能会从一种方法开始。这仍然需要人工来确定哪些可以安全删除。 您不应该使用此方法自动删除软件包。 这仅供教育使用。

建立所有已安装 RPM 的列表。

rpm -qa | sort -n > /dev/shm/all.txt

建立最近访问的文件列表并保存计数。 新的一年即将到来,所以您可能想回顾一下去年。

YEAR=`date -d "one year ago" '+%Y'`
# YEAR=2014
OFS="$IFS";IFS=$'\n';stat --printf="%y %n\n" $(ls -tr $(find /bin /boot /etc /lib /lib64 /sbin /usr /var -type f ! -name "*~" ! -name "*.gz" ! -name "*.tar")) | grep ^${YEAR} | awk {'print $NF'} > /dev/shm/recent.txt;IFS="$OFS";
FILECOUNT=`egrep -c ^.+ /dev/shm/recent.txt`

将我们的 RPM 数据库复制到 ram 磁盘,这样我们就不会滥用服务器。确保您至少有 100 MB 左右的可用空间。例如 df -Ph /dev/shm

mkdir --mode=0700 /dev/shm/rpmdb
rsync -a /var/lib/rpm/. /dev/shm/rpmdb/.

找到与我们的 recent.txt 列表关联的 RPM。这需要一段时间。我敢打赌有人可以找到更高效、更快速、更聪明的方法来完成这一步。我会在屏幕会话中执行此操作。

renice 19 -p $$ > /dev/null 2>&1
printf "${FILECOUNT} files to iterate through."
> /dev/shm/recent_packages.txt
for file in `cat /dev/shm/recent.txt`
do
rpm --dbpath /dev/shm/rpmdb -q --whatprovides ${file} >> /dev/shm/recent_packages.txt 2>/dev/null
# optional status indicator.
printf "."
done

从我们的列表中删除不属于 RPM 包的文件。

grep -v "not owned by" /dev/shm/recent_packages.txt | sort -n | uniq > /dev/shm/recent_sorted.txt

比较输出。同样,这本身并不是完全有用的。您需要确定为什么这些包中的文件未被访问。

diff -u /dev/shm/recent_sorted.txt /dev/shm/all.txt | grep '^+'

您可以使用以下命令列出 RPM 的内容rpm -ql 软件包。这是我的一台虚拟机上的输出。如您所见,这对我来说并不完全有用。

+++ /dev/shm/all.txt    2014-12-31 20:50:06.521227281 +0000
+basesystem-10.0-4.el6.noarch
+dhcp-common-4.1.1-43.P1.el6.centos.x86_64
+filesystem-2.4.30-3.el6.x86_64
+rootfiles-8.1-6.1.el6.noarch

我需要保留文件系统和基本系统,尽管这些文件已经有一段时间没有被访问过了。 注意:有时我启用了 noatime

我删除了 dhcp-common 及其相关的 dhclient 包,因为在我的特定用例中我永远不需要 DHCP。我意识到这种方法并不完全有效,但它应该能为您提供有关服务器每个独特角色的起点。新年快乐!

答案2

我不知道这个问题是否有正确的答案......

值得注意的是,许多通用 Linux 部署中经常会安装多余的软件包。

大多数工程师不会手动选择要安装的单个软件包,而是根据应用程序的逻辑组进行选择(Web 服务器、邮件服务器、NFS 服务器)或系统角色(服务器、工作站、最小)

在上述选择过程中,还会安装依赖项。因此,确定哪些包“未使用”的概念就变得十分棘手。

安全性不仅仅取决于安装了什么……它更多的是取决于实际上系统上运行的;即守护进程、网络服务、暴露的端口、进程等。

在资源利用率方面,安装未使用的软件只会浪费磁盘空间。进程在执行之前不会消耗 CPU 或 RAM 资源。因此,后果很低。如果我是雇主/经理,我会建议你关注其他事情。不是这个。

如果您想改进系统构建,正确的方法是从一组基本软件包开始,然后添加提供必需系统功能所需的一切。记录附加软件包列表,并将其添加到启动下面的例子)。不要错误地从正在运行的系统中删除软件。

来自我其中一个 kickstart 软件包列表的片段,其中包含软件包组和几个额外的软件包...

%packages

@ base
@ core
@ cifs-file-server
@ compat-libraries
@ console-internet
@ development
@ mail-server
@ nfs-file-server
@ network-server
@ network-tools
@ system-management
@ system-admin-tools
@ web-server

yum-fastestmirror
rpm-devel
e2fsprogs
grub
kernel-devel
net-snmp-utils
screen

相关内容