Limozacloud/glance
GitHub: Limozacloud/glance
一款轻量级 Linux SBOM 扫描器,通过扫描包管理器和非受管二进制文件生成 CycloneDX 格式的软件物料清单并归因到 PURL/CPE 身份。
Stars: 0 | Forks: 0
# glance
[](https://github.com/Limozacloud/glance/actions/workflows/ci.yml)
[](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, 依赖分析, 占用监测, 实时处理, 无后门, 无线安全, 硬件无关, 资产管理, 逆向工具