popey/sbom-vm

GitHub: popey/sbom-vm

该工具通过在宿主机上只读挂载虚拟机磁盘镜像的方式,在不启动虚拟机的前提下调用 Syft 生成 SBOM,有效避免了虚拟机内部扫描时的内存溢出问题。

Stars: 19 | Forks: 4

# sbom-vm 从虚拟机磁盘镜像生成软件物料清单 (SBOM),无需启动虚拟机。 在当前状态下,此脚本利用常见的 Linux 实用工具(gdisk、qemu-nbd 等)以只读方式将分区呈现给宿主机,以便在宿主机上运行的 [Syft](https://github.com/anchore/syft) 能够读取文件并生成 SBOM。 ## 功能 * 通过 qemu-nbd 只读挂载虚拟机磁盘镜像 * 支持多种虚拟机磁盘格式 (qcow2, vmdk) * 自动检测并挂载常见的文件系统: * Windows (NTFS) * Linux (ext4, ZFS, BTRFS) * macOS (HFS+, APFS) * BSD (ZFS) * 使用 Syft 进行安全、非破坏性的 SBOM 生成 ## 背景 [Syft](https://github.com/anchore/syft) 是一款通用的 SBOM 生成器,专为从容器、目录和代码库创建 SBOM 而优化。 有些用户会扫描整个文件系统。当存在大量文件时,这可能会非常消耗计算资源,并且可能会生成非常大的 SBOM 文档。在一些反馈的情况中,在虚拟机内部运行 Syft 会导致其耗尽所有可用内存,并被内核的 OOM (Out Of Memory, 内存溢出) 杀手终止,从而导致 SBOM 创建失败。 Will Murphy 在 [Anchore Community Discourse](https://anchore.com/discourse) 上汇总了社区里的一些讨论,主题为“[改进整机扫描](https://anchorecommunity.discourse.group/t/improvements-to-scanning-whole-machine/301?u=popey)”。 ## 项目目标 本项目的目标是对从运行中的虚拟机外部、直接通过磁盘镜像构建 SBOM 进行原型验证。从中获得的经验教训可用于改进或扩展 Syft,或者为 Syft 用于检查容器的库 [stereoscope](https://github.com/anchore/stereoscope) 添加新功能。 一个额外的好处是,在向 Syft 和/或 Stereoscope 贡献的代码完全集成此功能之前,可以满足目前需要扫描虚拟机磁盘镜像的 Syft 用户的需求。 ## 项目范围 以下是我对用于从虚拟机磁盘镜像生成 SBOM 的 MVP (Minimum Viable Product, 最小可行性产品) 的设想。 ### MVP * 检查常见的磁盘镜像格式 (raw, ami, qcow2, vmdk) * 挂载常见的分区类型 (ntfs, hfsplus, apfs, ext4, vfat, zfs) * 使用适当的选项启动 Syft 以生成 SBOM ### 不在范围内 * 加密的磁盘镜像或分区 ## 使用 sbom-vm 注意:到目前为止,这仅在我的 Ubuntu 24.04 工作站上进行了测试。 ## 前置条件 需要以下软件包: * [Syft](https://github.com/anchore/syft) - 用于生成 SBOM * qemu-utils - 用于挂载磁盘镜像 * gzip - 用于解压 zip 格式的 ami * gdisk - 用于处理 GPT 分区 * fdisk - 用于分区分析 * parted - 用于获取详细的分区信息 * util-linux - 用于 mount/umount 命令 * ntfs-3g - 用于支持 Windows NTFS 文件系统 * hfsprogs - 用于支持 MacOS HFS+ 文件系统 * apfs-dkms & apfsprogs - 用于支持 MacOS APFS 文件系统 * zfsutils-linux - 用于支持 ZFS 文件系统 在 Ubuntu 24.04 上,可以通过以下命令安装它们: ``` $ snap install syft $ sudo apt install qemu-utils gdisk fdisk parted util-linux ntfs-3g hfsprogs apfs-dkms apfsprogs zfsutils-linux ``` ## 安装 * 克隆此代码库,或者直接获取其中的单个 python 脚本 ## 运行 * 运行该 python 脚本,并将磁盘镜像作为唯一参数传入 ## 示例输出 ### 使用 ext4 的 Ubuntu 24.04 qcow2 镜像 ``` $ sudo sbom-vm.py test_images/ubuntu_22.04.qcow2 2025-02-01 18:45:59,394 - INFO - Loading NBD kernel module 2025-02-01 18:46:00,405 - INFO - Detecting format of /home/popey/sbom-vm/test_images/ubuntu_22.04.qcow2 2025-02-01 18:46:00,409 - INFO - qemu-img detected format: qcow2 2025-02-01 18:46:00,409 - INFO - Connecting image /home/popey/sbom-vm/test_images/ubuntu_22.04.qcow2 to NBD device 2025-02-01 18:46:01,426 - INFO - Analyzing partitions 2025-02-01 18:46:01,438 - INFO - Found EFI system partition /dev/nbd0p1 2025-02-01 18:46:01,438 - INFO - Found usable partition /dev/nbd0p2 of type ext4 2025-02-01 18:46:01,438 - INFO - Found filesystem partition(s): /dev/nbd0p1 (fat32), /dev/nbd0p2 (ext4) 2025-02-01 18:46:01,438 - INFO - Selected partition /dev/nbd0p2 (priority: 3, size: 547MB) 2025-02-01 18:46:01,442 - INFO - Mounting ext4 filesystem 2025-02-01 18:46:01,450 - INFO - Generating SBOM for mounted filesystem at /mnt/image_analysis 2025-02-01 18:46:01,451 - INFO - Filesystem type: ext4 2025-02-01 18:46:03,679 - INFO - SBOM generated: 20250201_184601_sbom_ubuntu_22.04_nbd0p2_ext4.json 2025-02-01 18:46:03,679 - INFO - Starting cleanup 2025-02-01 18:46:03,684 - INFO - Unmounting /mnt/image_analysis 2025-02-01 18:46:03,714 - INFO - Disconnecting NBD device 2025-02-01 18:46:03,717 - INFO - Removing NBD kernel module 2025-02-01 18:46:03,719 - INFO - Removing temporary directory: /tmp/sbomvm_ch80d0zx ``` ### 使用 ZFS 的 Ubuntu 24.04 qcow2 镜像 ``` $ sudo sbom-vm.py test_images/ubuntu_22.04_zfs.qcow2 2025-02-02 15:27:12,157 - INFO - Loading NBD kernel module 2025-02-02 15:27:13,159 - INFO - Detecting format of /home/alan/Temp/sbom-vm/test_images/ubuntu_22.04_zfs.qcow2 2025-02-02 15:27:13,163 - INFO - qemu-img detected format: qcow2 2025-02-02 15:27:13,163 - INFO - Connecting image /home/alan/Temp/sbom-vm/test_images/ubuntu_22.04_zfs.qcow2 to NBD device 2025-02-02 15:27:14,184 - INFO - Analyzing partitions 2025-02-02 15:27:14,195 - INFO - Found usable partition /dev/nbd0p1 of type zfs_member (via blkid) 2025-02-02 15:27:14,195 - INFO - Found filesystem partition(s): /dev/nbd0p1 (zfs_member) 2025-02-02 15:27:14,195 - INFO - Selected partition /dev/nbd0p1 (priority: 1, size: 1072MB) 2025-02-02 15:27:14,196 - INFO - Mounting zfs_member filesystem 2025-02-02 15:27:14,196 - INFO - Attempting to import ZFS pool from /dev/nbd0p1 2025-02-02 15:27:14,205 - INFO - Found ZFS pool: sbomtmp 2025-02-02 15:27:14,226 - INFO - Generating SBOM for mounted filesystem at /mnt/image_analysis 2025-02-02 15:27:14,226 - INFO - Filesystem type: zfs_member 2025-02-02 15:27:17,462 - INFO - SBOM generated: 20250202_152714_sbom_ubuntu_22.04_zfs_nbd0p1_zfs_member.json 2025-02-02 15:27:17,462 - INFO - Starting cleanup 2025-02-02 15:27:17,465 - INFO - Exporting ZFS pool sbomtmp 2025-02-02 15:27:17,479 - INFO - Disconnecting NBD device 2025-02-02 15:27:17,483 - INFO - Removing NBD kernel module 2025-02-02 15:27:17,485 - INFO - Removing temporary directory: /tmp/sbomvm_41rnscs4 ``` ## 测试镜像 如果你手头没有任何磁盘镜像,可以使用 `generate-test-images.py` 脚本,它会基于 docker 的容器内容创建一些测试用的虚拟机磁盘镜像。该脚本支持创建包含各种文件系统(包括 ext4 和 ZFS)的测试镜像。 ``` $ sudo ./generate-test-images.py 2025-02-02 15:23:13,365 - INFO - Creating output directory at /home/alan/Temp/sbom-vm/test_images 2025-02-02 15:23:13,365 - INFO - Generating zfs test image from ubuntu:22.04 2025-02-02 15:23:13,366 - INFO - Creating 1024MB raw disk image at /home/alan/Temp/sbom-vm/test_images/disk_2jucd3yv.raw 2025-02-02 15:23:13,375 - INFO - Creating partition table for zfs on /home/alan/Temp/sbom-vm/test_images/disk_2jucd3yv.raw 2025-02-02 15:23:14,950 - INFO - Setting up loop device for /home/alan/Temp/sbom-vm/test_images/disk_2jucd3yv.raw 2025-02-02 15:23:16,983 - INFO - Creating zfs filesystem 2025-02-02 15:23:17,042 - INFO - Mounting root partition to /tmp/tmpsfp6mhg0/mnt 2025-02-02 15:23:17,043 - INFO - Populating root filesystem from container ubuntu:22.04 2025-02-02 15:23:17,355 - INFO - Pulling container ubuntu:22.04 2025-02-02 15:23:18,286 - INFO - Creating temporary container 2025-02-02 15:23:18,364 - INFO - Exporting container filesystem 2025-02-02 15:23:19,000 - INFO - Extracting rootfs 2025-02-02 15:23:19,344 - INFO - Cleaning up temporary container 2025-02-02 15:23:19,370 - INFO - Cleaning up ZFS pool sbomtmp 2025-02-02 15:23:19,479 - INFO - Detaching loop device /dev/loop154 2025-02-02 15:23:20,485 - INFO - Converting /home/alan/Temp/sbom-vm/test_images/disk_2jucd3yv.raw to qcow2 format 2025-02-02 15:23:20,564 - INFO - Successfully generated zfs test image: /home/alan/Temp/sbom-vm/test_images/ubuntu_22.04_zfs.qcow2 ``` 通过一个简单的循环来为每个生成的镜像生成 SBOM 是最简单的方法: ``` for f in $(ls -1 $PWD/test_images/*.qcow2); do echo $f ; sudo $PWD/sbom-vm.py $f; done ``` ## 贡献 欢迎贡献代码!请随时提交 Pull Request。对于重大更改,请先开启一个 issue 讨论您希望更改的内容。
标签:SBOM, Syft, 生成式AI安全, 硬件无关, 虚拟机, 请求拦截, 跨平台文件系统, 逆向工具, 镜像解析