Limozacloud/glance

GitHub: Limozacloud/glance

一款轻量级 Linux SBOM 扫描器,通过扫描包管理器和非受管二进制文件生成 CycloneDX 格式的软件物料清单并归因到 PURL/CPE 身份。

Stars: 0 | Forks: 0

# glance [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/7cbf265c93050254.svg)](https://github.com/Limozacloud/glance/actions/workflows/ci.yml) [![License](https://img.shields.io/github/license/Limozacloud/glance)](LICENSE) 一个用于 Linux 服务器的**轻量级 SBOM 扫描器**。它基于两类证据生成紧凑的 [CycloneDX](https://cyclonedx.org/) 1.6 SBOM: 1. **包目录扫描器**(`rpm`、`dpkg`、`apk`)会枚举每个已安装的 包及其完整版本,并附带规范的 `pkg:rpm`/`pkg:deb`/`pkg:apk` PURL。 2. **二进制文件扫描器**通过低成本的 *locate 门控* 查找文件,直接 从字节中读取版本信息,并将文件归属到一个上游 身份 —— 例如,一个内置的 `libcrypto.so.1.1` 会变成带有 `pkg:generic/openssl@1.1.1w` PURL **以及**带有版本的 CPE 的 `openssl 1.1.1w`。 ## 安装 ``` pip install glance # ships PyYAML; pure-stdlib core otherwise ``` 要求 Python 3.10+。扫描逻辑仅使用标准库;PyYAML 仅用于读取 YAML 配置文件。 ## 使用方法 ### CLI ``` # 扫描整个系统,生成 CycloneDX SBOM glance --output sbom.json --report report.json # 仅使用 binary cataloger,强制 filesystem walk,缩小范围 glance --catalogers binary --engine walk --include /opt --include /usr/lib64 # 直接输入到漏洞扫描器 glance -o sbom.json && grype sbom:sbom.json ``` ``` --config FILE YAML or JSON config file --engine ENGINE auto | plocate | mlocate | walk (default: auto) --include PATH root path to scan (repeatable) --catalogers LIST comma list: binary,rpm,dpkg,apk (default: all applicable) --format FORMAT cyclonedx | native (default: cyclonedx) --output, -o FILE write the SBOM (default: stdout) --report FILE write the audit report JSON ``` ### 库 ``` from glance import scan, Config result = scan(Config(include_paths=["/opt", "/usr/lib64"])) for c in result.components: print(c.name, c.version, c.purl, "managed" if c.managed else "UNMANAGED") # audit trail — 运行了什么,跳过了什么,以及原因 print(result.report.engine_used, result.report.skipped) ``` 在代码中构建 `Config` 无需 YAML —— 这在将 glance 嵌入到 更大的 agent 时非常方便。 ## 工作原理 ``` config -> discovery -> scanner (binary) ┐ ├─> correlate -> models -> CycloneDX + report package catalogers (rpm/...) ┘ ``` 1. **优先进行 Glob 门控。** 在读取任何内容之前,由路径/文件名 glob(所有分类器门控的并集, 例如 `**/libcrypto.so*`, `**/openssl`, `**/python*`)决定哪些文件 是值得关注的。 2. **发现引擎级联。** `plocate` -> `mlocate` -> 文件系统遍历。 locate 仅用作返回 *超集* 的快速索引;门控是 决定匹配结果的唯一权威,因此引擎的选择只影响速度, 绝不会影响结果。陈旧度检查(`max_db_age_hours`)会从 级联中剔除过于陈旧的 DB。`mandatory_paths`(例如 `/usr/lib64`, `/opt`)**始终** 被直接遍历,无论引擎、DB 新鲜度或任何自定义的 `updatedb.conf` 剔除规则如何。 3. **内容扫描。** 仅读取通过门控的候选文件,通过 `mmap` 读取(无全文件 拷贝),并与预编译的 **字节** 正则表达式匹配(版本字符串位于 `\x00` 分隔符之间)。 4. **关联。** 对于每个发现的二进制文件,glance 会询问包 DB *谁拥有 这个确切的路径?* 有归属 -> *受管*,为了优先处理包组件而被抑制(记录在 报告中)。无归属 -> *非受管*,作为 归属于其安装路径应用的 `pkg:generic` 组件输出。 5. **审计报告。** 每个被跳过的路径/文件系统/扫描器都会记录 原因。“绿色”扫描绝不会无声地意味着“绿色,除了那 2 TB 没人 看的地方。” ## 配置 完整的带注释参考文档位于 [`glance/data/default_config.yaml`](glance/data/default_config.yaml)。所有键 都是可选的;相同的默认值存在于代码中。提供的键会覆盖默认值, 未提供的键保留默认值,而未知的键会导致硬错误。 | 键 | 默认值 | 含义 | |-----|---------|---------| | `include_paths` | `["/"]` | 要扫描的根目录(遍历回退 / 结果边界) | | `exclude_paths` | `[]` | 要跳过的额外路径前缀 | | `exclude_fs_types` | nfs, cifs, tmpfs, overlay, … | 绝不扫描的文件系统类型 | | `mandatory_paths` | `/usr/lib`, `/usr/lib64`, `/opt`, … | 始终遍历,不可被剔除 | | `file_globs` | `null` (从分类器派生) | glob 门控 | | `engine` | `auto` | `auto`/`plocate`/`mlocate`/`walk` | | `max_db_age_hours` | `24` | 早于此时间的 locate DB 不可用 | | `on_stale_db` | `fallback` | `fallback` (级联) 或 `warn` (无论如何都使用) | | `catalogers` | `null` (所有适用的) | `binary,rpm,dpkg,apk` 的子集 | | `correlate_ownership` | `true` | 受管/非受管关联 | | `max_file_size` | `209715200` | 超过此字节数时跳过内容扫描 | | `elf_precheck` | `false` | 基于 ELF 魔数进行门控(开启时会跳过脚本工具) | | `compute_sha256` | `false` | 对匹配的文件进行哈希计算 | ## 添加分类器 分类器就是**数据**:一个门控加上字节正则表达式匹配器和身份 模板。在 `glance/catalogers/binary/classifiers.py` 中添加一个: ``` from .matchers import Classifier, contents Classifier( cls="nginx-binary", file_globs=["**/nginx"], # version strings sit between NULs in the binary matcher=contents(rb"(?m)nginx version: [^/]+/(?P[0-9]+\.[0-9]+\.[0-9]+)"), package="nginx", purl_template="pkg:generic/nginx@{version}", cpe_templates=["cpe:2.3:a:f5:nginx:{version}:*:*:*:*:*:*:*"], ) ``` `{version}` 会被捕获到的版本替换到 PURL 和 CPE 中。 可以使用更丰富的匹配器:`any_of`、`all_of`、`none_of`、`branching` (为每个子匹配选择一个身份,例如 AWS-LC 与 OpenSSL)、`filename_template` (从文件名中提取版本)、`shared_library`(从引用的 `.so` 中提取版本), 以及 `supporting`(邻近的 `VERSION` 文件)。 ## 开发 ``` pip install -e ".[dev]" pytest ruff check . && ruff format --check . mypy glance ``` ## 许可证 MIT
标签:CycloneDX, Python, SBOM, WebSocket, 依赖分析, 占用监测, 实时处理, 无后门, 无线安全, 硬件无关, 资产管理, 逆向工具