如何对 Linux 上的文件系统进行指纹识别(欧几里得距离)?

如何对 Linux 上的文件系统进行指纹识别(欧几里得距离)?

我有大量系统(100 个),由一小群人管理,这些系统会随着时间的推移而发生变化。每个系统都使用基础映像进行安装(基础映像有自己的版本,根据安装时间的不同而不同),然后根据客户的需求,随着时间的推移以各种方式对其进行定制(分叉)。

我有每个版本的安装映像的副本。各个版本之间超过 90% 的安装映像是相同的。定制部分通常不到 3%。

我需要找出安装了哪些版本以及自安装以来进行了哪些定制。

由于带宽限制,我无法进行网络diffrsync --dry-run通过网络进行*。

但是,我设想能够在每个安装映像上运行一个脚本,并将其作为数据库发送到每个系统,以便与其自己的文件系统进行比较并报告 - 就像“指纹”一样,如果你愿意的话。

“指纹”(文件系统树 + 每个文件和文件夹的校验和)将被限制于可修改的文件集(而不是、、、/proc管道、套接字等)。/sys/tmp

“指纹”不能是文件系统的 MD5,因为一次改变就会导致不同的指纹,而且我们不能确定哪些文件可能已经被定制。

我正在寻找一个可以报告两件事的实用程序:

  1. 根据文件系统“指纹”(树形结构的元数据 + 文件和文件夹校验和)数据库,建议哪个版本与当前文件系统最匹配,以及
  2. 列出自该版本以来已更改(定制)的文件/文件夹,包括新文件和已删除的文件。

此外,如果我可以从现有数据库中创建新的数据库,以便我可以从定制中获取信息来制作新版本(例如版本 2.0.3-withmodX),那就太好了。

我考虑过:

  • 备份实用程序 - 他们假设每个客户端的版本都有 1:1 的线性进展
  • 图像管理系统——倾向于假设图像从服务器->客户端,仅具有已知的定制(例如新文件,特定配置文件夹),而我们想要的信息是客户端(参考数据库)->服务器。

我或许可以用git某种方式来生成文件系统的“.git”数据库,然后发送多个.git 数据库进行比较,然后:

  1. 最少行数git status=版本。
  2. git status针对版本的输出 = 定制。

是否存在这样的文件系统“指纹”实用程序,或者是否存在一些可以使其更容易构建的实用程序?

*虽然我想知道是否rsync可以输出一个元信息数据库,可以用来轻松构建这样的工具。

答案1

你想要描述数百个磁盘映像的起源,识别任意的模糊变化,而且带宽有限?这很棘手。

之前在 Server Fault 上,磁盘映像的比较启动 cmp 和 rsync.我会补充virt-diff以及 VCS(可能是 git)。你不会喜欢它们中的任何一个。

由于您想要了解文件差异,因此您不考虑磁盘映像上的校验和(sha256sum, )。一旦您确定了所需的确切映像,它仍然是映像的有用标识符。md5sum

UUID 和文件系统上的任何标签都可以通过 看到lsblk --fs。可用于识别来源,但不能识别任何更改。不过,我敢打赌,安装系统时,它们都没有改变。

cmp磁盘映像上的比较是文件系统的字节比较。您不会看到文件级别的差异。/tmp 中的细微变化(如改动)都会使每个映像都不同。

rsync在已安装的文件系统上将显示已更改的文件。它还会执行大量的 I/O,典型的 Linux 根文件系统将有数十万个 inode。您没有足够的 IOPS 来查找数百个其他文件系统的增量,而不是在使用中的系统。

virt-diff会发现磁盘映像中的文件存在差异。您可以引用未使用的磁盘映像或快照,例如辅助服务器上的完整备份。此备份受带宽限制,而不是 IOPS 限制。但是,您说您受带宽限制。

类似的 VCSgit并非设计用于保存任意系统文件(包括权限和特殊文件)。etckeeper 有办法做到这一点当祖先未知时,VCS 的用处也不大,它们的数据结构遵循用户的分支方式。

您可以通过以下方式对 git repos 中的任意对象进行重复数据删除报告查看包文件。这里的问题在于工具和规模。verify-pack是一个低级管道命令,不易于用于此目的。在每个文件级别执行此操作将分析数百万个 blob,不可扩展。即使查看 blob 的打包方式也会变得很慢。


我建议忘记自动脚本并让一个人来做。

从基础镜像和自定义镜像中识别出有用的镜像。使用值得作为基础镜像保留的用例。

设置并记录这些的唯一 UUID 和标签。对图像进行校验和归档以供将来使用。


没有直接关系,但将来尝试分离系统包状态和用户数据。

考虑一个只读根,其配置和数据是不同的文件系统或覆盖。可能是 NFS 上的 /home 或 tmpfs 上的 /tmp。基本映像很容易识别,因为它没有被触及。对映像的更改可以是一个定义的过程:挂载 r/w、进行更改、快照。

相关内容