vdanen/syfter

GitHub: vdanen/syfter

syfter 是一个基于Syft的SBOM生成与管理工具,旨在提升软件供应链的可见性和安全性。

Stars: 1 | Forks: 0

# Syfter [![OpenSSF 最佳实践](https://www.bestpractices.dev/projects/11827/badge)](https://www.bestpractices.dev/projects/11827) [![OpenSSF 记分卡](https://api.scorecard.dev/projects/github.com/vdanen/syfter/badge)](https://scorecard.dev/viewer/?uri=github.com/vdanen/syfter) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/vdanen/syfter?sort=semver) ![PyPI release](https://img.shields.io/pypi/s/syfter) ![Downloads](https://static.pepy.tech/badge/syfter) 使用 [Syft](https://github.com/anchore/syft) 的 SBOM 生成与管理工具。 **版本: 0.9.1.0** ## 概述 - **扫描**包含 RPM 包、容器镜像及其他制品的目录 - **丰富** SBOM 的产品特定元数据(带有发行版限定符的 CPE 和 PURL) - **存储** SBOM 至可查询的数据库(SQLite 或 PostgreSQL) - **查询**跨产品或系统的所有软件包和文件 - **导出**为面向客户的格式(SPDX, CycloneDX) ### 企业级能力 除了所有标准 syfter 功能外,此版本增加了面向生产的服务器功能: | 功能 | 描述 | |---------|-------------| | **API 密钥认证** | 基于团队的密钥,支持管理员管理(`X-API-Key` 请求头) | | **速率限制** | 基于令牌桶算法,按密钥限制(每分钟查询和上传次数) | | **响应缓存** | 进程内缓存,数据修改时自动失效 | | **RPM 依赖关系跟踪** | 大规模查询 Requires/Provides 关系 | | **跨产品追踪** | `syfter trace` 跨仓库、基础镜像和分层容器追踪软件包 | | **证明元数据** | Cosign SLSA 和 SPDX 证明索引 | | **组件关系** | 产品到产品的组合映射 | | **查询性能** | 针对数千万软件包优化的 PostgreSQL 查询模式 | ### 两种运行模式 Syfter 支持两种不同的模式: ### 两种部署选项 Syfter 可以在两种部署配置下运行: | 模式 | 存储 | 适用场景 | |------|---------|----------| | **本地模式** | SQLite (`~/.syfter/syfter.db`) | 开发、单用户、小规模 | | **服务器模式** | PostgreSQL + MinIO (S3) | 生产环境、多用户、大规模 | - **本地模式**是默认模式 - 无需额外设置,安装即可运行 - **服务器模式**需要通过 `podman-compose` 运行 API 服务器 ## 前置条件 - **Python 3.9+** - **Syft** - 从 [GitHub releases](https://github.com/anchore/syft/releases)、Homebrew 安装,或运行以下命令: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin - **Skopeo** - 可通过 dnf 或 Homebrew 安装,参见 [GitHub 安装说明](https://github.com/containers/skopeo/blob/main/install.md) ## 安装说明 ### 使用 uv(推荐) ``` # 安装为独立 CLI 工具(隔离环境) uv tool install syfter # 或安装包含服务器组件 uv tool install "syfter[server]" # 升级到最新版本 uv tool upgrade syfter ``` ### 使用 pip ``` # 从 PyPI 安装 pip install syfter # 安装包含服务器组件 pip install "syfter[server]" ``` ### 从源代码安装 ``` git clone https://github.com/vdanen/syfter.git cd syfter # 使用 uv uv tool install . # 或使用 pip pip install -e . # 安装所有组件(服务器 + 开发工具) pip install -e ".[all]" ``` 详细的构建和分发选项请参见 [docs/BUILDING.md](docs/BUILDING.md)。 ## 部署选项 ### 选项 1:本地模式(默认) 本地模式使用 SQLite,无需额外设置。安装即可开始使用: ``` # 扫描存储至 ~/.syfter/syfter.db syfter scan /path/to/rpms -p myproduct -v 1.0 syfter products syfter query -n "openssl%" ``` 本地模式适用于: - 开发和测试 - 单用户工作站 - 中小规模的扫描量(约 50 个产品以内) ### 选项 2:服务器模式(分布式) 服务器模式使用 PostgreSQL 作为数据库,使用 MinIO(兼容 S3)存储 SBOM。可扩展至支持数千个产品和多个并发用户。 #### 服务器模式的前置条件 - **Podman** 和 **podman-compose**(或 Docker/docker-compose) # Fedora/RHEL sudo dnf install podman podman-compose # macOS brew install podman podman-compose #### 启动服务器 ``` cd podman # 创建包含密码的环境文件 cp env.example .env # 编辑 .env 以设置安全密码: # POSTGRES_PASSWORD=your_secure_password # MINIO_ROOT_PASSWORD=your_secure_password # 启动所有服务(PostgreSQL、MinIO、API) podman-compose up -d # 检查状态 podman-compose ps # 查看日志 podman-compose logs -f syfter-api ``` 服务将可通过以下地址访问: - **API 服务器**: http://localhost:8000 - **MinIO 控制台**: http://localhost:9001(使用 MINIO_ROOT_USER/PASSWORD 登录) - **PostgreSQL**: localhost:5432 #### 配置 CLI 以使用服务器模式 设置 `SYFTER_SERVER` 环境变量指向您的 API 服务器: ``` # 添加到你的 ~/.bashrc 或 ~/.zshrc export SYFTER_SERVER=http://localhost:8000 # 或在每次命令中指定 syfter --server http://localhost:8000 products # 认证服务器(设置团队 API 密钥) export SYFTER_API_KEY=your-team-key ``` #### API 认证 当 `SYFTER_AUTH_ENABLED=true`(默认值)时,除 `/health` 外,所有 API 请求都需要 `X-API-Key` 请求头。 ``` # 使用种子管理员密钥启动服务器 SYFTER_AUTH_ENABLED=true \ SYFTER_ADMIN_API_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))") \ SYFTER_DB_TYPE=postgresql \ SYFTER_PG_HOST=localhost \ SYFTER_PG_PASSWORD=changeme \ python -m uvicorn server.main:app --host 0.0.0.0 --port 8000 # 创建团队密钥 curl -X POST http://localhost:8000/api/v1/admin/keys/ \ -H "X-API-Key: $SYFTER_ADMIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"team_name": "security"}' export SYFTER_API_KEY= export SYFTER_SERVER=http://localhost:8000 syfter products ``` 如需在本地开发时禁用 API 密钥认证,可设置 `SYFTER_AUTH_ENABLED=false`。 #### 服务器模式命令 设置 `SYFTER_SERVER` 后,所有命令将自动使用服务器: ``` # 现在这些将连接到 API 服务器 syfter scan registry.redhat.io/ubi9:latest -p ubi -v 9.0 syfter products syfter query -n "kernel%" syfter export -p ubi -v 9.0 -f spdx-json -o ubi9.spdx.json ``` #### 强制使用本地模式 如果已设置 `SYFTER_SERVER` 但仍想使用本地 SQLite: ``` syfter --local products ``` #### 服务器架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ syfter CLI (client) │ │ SYFTER_SERVER=http://localhost:8000 │ └───────────────────────────────┬─────────────────────────────────┘ │ HTTP API ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Syfter API Server │ │ (FastAPI, syfter-api) │ └───────────────────────────────┬─────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────────┐ ┌─────────────────────┐ │ PostgreSQL │ │ MinIO (S3) │ │ (syfter-postgres) │ │ (syfter-minio) │ │ │ │ │ │ • Products │ │ • Original SBOMs │ │ • Packages │ │ • Modified SBOMs │ │ • Files │ │ (gzip compressed) │ │ • Systems │ │ │ └─────────────────────┘ └─────────────────────┘ ``` #### 服务器管理 ``` cd podman # 停止所有服务 podman-compose down # 停止并移除卷(删除所有数据) podman-compose down -v # 代码更改后重新构建 podman-compose build --no-cache api podman-compose up -d api # 查看 API 日志 podman-compose logs -f syfter-api # 直接访问 PostgreSQL podman-compose exec syfter-postgres psql -U syfter -d syfter ``` #### ARM 架构 Mac 用户 在 Apple Silicon Mac 上,可能需要指定平台: ``` # 选项 1:在 .env 中设置 echo "DOCKER_DEFAULT_PLATFORM=linux/arm64" >> .env # 选项 2:设置环境变量 export DOCKER_DEFAULT_PLATFORM=linux/arm64 podman-compose up -d ``` ## 快速开始 ### 1. 扫描包含 RPM 包的目录 ``` # 扫描 RHEL 10.0 软件包 syfter scan /path/to/rhel10/rpms -p rhel -v 10.0 # 带描述扫描 syfter scan /path/to/rpms -p rhel -v 10.0 --description "Red Hat Enterprise Linux 10.0" ``` ### 2. 扫描容器镜像 ``` syfter scan registry.redhat.io/rhel9:latest -p rhel -v 9.0 syfter scan docker:ubi9/ubi:latest -p ubi -v 9.0 ``` #### 仓库认证 许多容器仓库(如 `registry.redhat.io`)需要认证。Syfter 使用您的本地容器凭据,因此扫描前请先登录: ``` # Red Hat Registry(需要 Red Hat 账户) podman login registry.redhat.io # Quay.io(用于私有仓库) podman login quay.io # 通用注册表 podman login myregistry.example.com ``` 凭据存储在 `~/.config/containers/auth.json`(或 `$XDG_RUNTIME_DIR/containers/auth.json`)中,并由 `podman` 和 `skopeo` 自动使用。 **访问红帽仓库:** 1. 在 [access.redhat.com](https://access.redhat.com) 创建免费账户 2. 或使用来自 [红帽仓库服务账户](https://access.redhat.com/terms-based-registry/) 页面的服务账户令牌 ``` # 使用服务账户(非交互式) podman login registry.redhat.io \ --username "12345678|myserviceaccount" \ --password-stdin < token.txt ``` **验证认证:** ``` # 检查是否可以访问注册表 skopeo inspect --override-arch amd64 --override-os linux \ docker://registry.redhat.io/ubi9/ubi:latest | jq '.Name' ``` #### Linux 签名外观库配置 在 RHEL/Fedora 系统上,skopeo 被配置为通过 `/etc/containers/registries.d/registry.redhat.io.yaml` 从红帽的签名存储库获取镜像签名: ``` docker: registry.redhat.io: lookaside: https://registry.redhat.io/containers/sigstore ``` 这会导致 skopeo 在拉取镜像时获取签名。当复制到 OCI 目录格式(syfter 内部使用)时,由于 OCI 目录无法存储签名,skopeo 会失败: ``` FATA[0002] Can not copy signatures to oci:/tmp/...: Pushing signatures for OCI images is not supported ``` Syfter 通过在复制镜像时使用 `--remove-signatures` 自动处理此问题。这只影响写入临时 OCI 目录的内容——不会禁用签名验证。如果您的 `policy.json` 需要签名验证,拉取时仍会进行验证;签名只是不会复制到本地目标。 **注意:** macOS 系统通常没有此仓库配置(通过 brew 安装的 skopeo 不包含它),因此此问题仅出现在 Linux 上。 #### 容器层追踪 扫描容器镜像时,Syfter 会**自动**确定每个软件包来自哪个基础镜像。这有助于在多阶段容器构建中识别漏洞修复位置。 ``` # 扫描容器镜像 - 基础镜像扫描自动进行 syfter scan registry.redhat.io/rhel9/go-toolset:latest -p go-toolset -v 9.0 # 查询软件包 - 显示每个软件包的源镜像 syfter query -n "go%" -p go-toolset -v 9.0 ``` 输出显示每个软件包来自哪个镜像: ``` Name Version Product Source Image ──────────────────────────────────────────────────────────────────────────── bash 5.1.8-9.el9 go-toolset-9.0 ubi9/ubi git 2.47.3-1.el9_6 go-toolset-9.0 ubi9/s2i-base golang 1.25.3-1.el9_7 go-toolset-9.0 rhel9/go-toolset ``` **工作原理:** 1. 使用**层摘要比较**准确识别基础镜像链(例如 `ubi9/ubi` → `ubi9/s2i-core` → `ubi9/s2i-base` → `rhel9/go-toolset`) 2. 从标签中提取精确的镜像引用(例如 `registry.redhat.io/ubi9/ubi:9.7-1767674301`) 3. 扫描每个基础镜像以构建软件包列表 4. 比较软件包列表以确定哪个镜像引入了每个软件包 5. 在数据库中为每个软件包记录 `source_image` `syfter layers` 命令显示完整的层链,包含: - `layer_id`:容器层摘要(截断) - `layer_index`:在层栈中的位置(0 = 基础层) - `source_image`:引入此层的镜像 - `image_reference`:完整的镜像引用(仓库/名称:版本-发布号) ### 3. 查询软件包 ``` # 查找所有产品中的内核软件包 syfter query -n "kernel%" # 在特定产品中查找软件包 syfter query -n "openssl%" -p rhel -v 10.0 # 查找文件 syfter query -f "%/bin/bash" ``` ### 4. 导出 SBOM ``` # 导出为 SPDX JSON syfter export -p rhel -v 10.0 -f spdx-json -o rhel-10.spdx.json # 导出为 CycloneDX syfter export -p rhel -v 10.0 -f cyclonedx-json -o rhel-10.cdx.json # 导出为所有格式 syfter export -p rhel -v 10.0 -f all -o ./sboms/ ``` ## 系统模式(基础设施扫描) 除了扫描产品,Syfter 还可以扫描基础设施中的主机,以跟踪各系统安装的软件包。 ### 扫描本地主机 ``` # 扫描本地主机并上传到服务器 syfter system-scan # 添加标签进行分组 syfter system-scan --tag production # 使用描述性标签扫描 syfter system-scan --tag "web-servers" ``` ### 通过 SSH 扫描远程主机 ``` # 扫描远程主机 syfter system-scan webserver01.example.com # 使用 SSH 选项 syfter system-scan 192.168.1.100 -u admin -i ~/.ssh/server_key # 带标签扫描 syfter system-scan dbserver.local --tag databases ``` **注意:** 远程扫描需要在远程主机上安装 `syft`。 ### 列出系统 ``` # 列出所有已扫描系统 syfter systems # 按标签筛选 syfter systems --tag production ``` ### 跨系统查询软件包 ``` # 查找安装了 openssh 的系统 syfter system-query -n "openssh%" # 在特定系统中搜索 syfter system-query -n "kernel%" --tag production # 跨系统查找文件 syfter system-query -f "%/bin/bash" ``` ### 列出系统的软件包/文件 ``` # 列出系统上的所有软件包 syfter system-list -H webserver01 -t packages # 列出所有文件 syfter system-list -H webserver01 -t files ``` ## CLI 参考 ### `syfter scan` 扫描目标并存储带有产品元数据的 SBOM。 ``` Usage: syfter scan [OPTIONS] TARGET Options: -p, --product TEXT Product name (required) -v, --version TEXT Product version (required) --vendor TEXT Vendor name (default: "Red Hat") --cpe-vendor TEXT CPE vendor string (default: "redhat") --purl-namespace TEXT PURL namespace (default: "redhat") --description TEXT Product description -o, --output PATH Write modified SBOM to file --original-output PATH Write original SBOM to file --no-store Don't store in database ``` ### `syfter search`(别名:`query`) 跨所有产品搜索软件包和文件。 ``` Usage: syfter search [OPTIONS] Options: -n, --name TEXT Package name pattern (% = wildcard) -f, --file TEXT File path pattern -d, --digest TEXT File digest (exact match) -p, --product TEXT Filter by product name -v, --version TEXT Filter by product version --limit INTEGER Maximum results (default: 50) --json Output as JSON --cross-product Trace package across the full product stack (server mode) ``` `query` 命令名已弃用但仍被接受。 ### `syfter trace` 跨产品技术栈(RHEL 仓库、UBI 基础镜像、分层容器)追踪软件包。需要服务器模式。 ``` Usage: syfter trace [OPTIONS] PACKAGE_NAME Options: --pkg-version TEXT Package version filter --limit INTEGER Maximum results per category (default: 200) --json Output as JSON ``` ### `syfter deps` 查询 RPM 依赖关系(需要已索引依赖关系的服务器模式)。 ``` Usage: syfter deps [OPTIONS] [DEPENDENCY_NAME] Options: --package TEXT Filter by package name --type [requires|provides] Dependency type (default: requires) -p, --product TEXT Filter by product name -v, --version TEXT Filter by product version --limit INTEGER Maximum results (default: 50) --json Output as JSON ``` ### `syfter relationships` 列出产品间的组件关系(服务器模式)。 ``` Usage: syfter relationships [OPTIONS] Options: --limit INTEGER Maximum results (default: 50) --json Output as JSON ``` ### `syfter export` 将产品的 SBOM 导出为各种格式。 ``` Usage: syfter export [OPTIONS] Options: -p, --product TEXT Product name (required) -v, --version TEXT Product version (required) -f, --format TEXT Output format: syft-json, spdx-json, spdx-tv, cyclonedx-json, cyclonedx-xml, all -o, --output PATH Output file or directory ``` ### `syfter products` 列出数据库中的所有产品。 ### `syfter scans` 列出所有扫描,可按产品筛选。 ### `syfter stats` 显示数据库统计信息。 ### `syfter check` 验证 syft 是否已安装并显示其版本。 ### `syfter list` 列出产品版本的文件或软件包。 ``` Usage: syfter list [OPTIONS] Options: -p, --product TEXT Product name (required) -v, --version TEXT Product version (required) -t, --type [files|packages] What to list (default: files) --full Include architecture in package output --layers Include source layer (container scans only) ``` 使用 `--layers` 时,软件包输出格式为 `源镜像::软件包版本`: ``` syfter list -p go-toolset -v 1.25 -t packages --layers | grep zlib ubi9/ubi::zlib-1.2.11-40.el9 ubi9/s2i-base::zlib-devel-1.2.11-40.el9 # 从特定基础镜像查找所有软件包 syfter list -p go-toolset -v 1.25 -t packages --layers | grep "^ubi9/ubi::" # 统计每层软件包数量 syfter list -p go-toolset -v 1.25 -t packages --layers | cut -d: -f1 | sort | uniq -c ``` ### `syfter layers` 显示产品的容器层链(仅容器扫描)。 ``` Usage: syfter layers [OPTIONS] Options: -p, --product TEXT Product name (required) -v, --version TEXT Product version (required) --json Output as JSON ``` 显示容器镜像的逐层分解,包括: - 层索引和截断的摘要 - 源镜像名称(例如 `ubi9/ubi`, `rhel9/go-toolset`) - 每层的版本和完整镜像引用 ### `syfter system-scan` 扫描主机并存储用于基础设施跟踪的 SBOM。 ``` Usage: syfter system-scan [OPTIONS] [TARGET] Arguments: TARGET Hostname or IP (default: localhost) Options: -t, --tag TEXT Tag for grouping/CMDB linking -u, --user TEXT SSH user for remote hosts -p, --port INTEGER SSH port (default: 22) -i, --identity PATH SSH identity file -o, --output PATH Write SBOM to file --no-store Don't store (just output) -q, --quiet Suppress progress output --skip-files Skip file indexing --include-debug Include debuginfo packages ``` ### `syfter systems` 列出数据库中的所有系统。 ``` Usage: syfter systems [OPTIONS] Options: --tag TEXT Filter by system tag ``` ### `syfter system-query` 跨系统查询软件包和文件。 ``` Usage: syfter system-query [OPTIONS] Options: -n, --name TEXT Package name pattern (% = wildcard) -f, --file TEXT File path pattern -d, --digest TEXT File digest (exact match) -H, --hostname TEXT Filter by hostname -t, --tag TEXT Filter by system tag --limit INTEGER Maximum results (default: 50) --json Output as JSON ``` ### `syfter system-list` 列出特定系统的文件或软件包。 ``` Usage: syfter system-list [OPTIONS] Options: -H, --hostname TEXT System hostname (required) -t, --type [files|packages] What to list (default: files) --full Include architecture in package output ``` ## Shell 脚本包装器 为方便起见,`scripts/` 目录中提供了 shell 脚本: ``` # 简单扫描包装器 ./scripts/scan-product.sh /path/to/rpms rhel 10.0 # 查询包装器 ./scripts/query.sh package "kernel%" ./scripts/query.sh file "%/bin/bash" # 导出包装器 ./scripts/export-sbom.sh rhel 10.0 spdx-json rhel-10.spdx.json # 从配置文件批量扫描 ./scripts/batch-scan.sh products.conf ``` ### 批量扫描配置 为批量扫描创建配置文件: ``` # products.conf /path/to/rhel10 rhel 10.0 "RHEL 10.0" /path/to/rhel9 rhel 9.4 "RHEL 9.4" /path/to/ocp openshift 4.14 "OpenShift Container Platform 4.14" registry.redhat.io/ubi9:latest ubi 9.0 "Universal Base Image 9" ``` 然后运行: ``` ./scripts/batch-scan.sh products.conf ``` ## 工作原理 ### SBOM 丰富 当您扫描目标时,Syfter 会: 1. 运行 Syft 生成 `syft-json` 格式的 SBOM 2. 修改每个软件包的元数据以包含: - **CPE**:更新供应商信息(例如 `cpe:2.3:a:redhat:kernel:...`) - **PURL**:添加发行版限定符(例如 `pkg:rpm/redhat/kernel@5.14?distro=rhel-10.0`) - **元数据**:用于追溯的产品信息 ### 存储 Syfter 将数据存储在两个位置: **本地模式**(SQLite): - 数据库:`~/.syfter/syfter.db` - SBOM 作为压缩 BLOB 存储在数据库中 **服务器模式**(PostgreSQL + MinIO): - 数据库:PostgreSQL 用于存储索引后的元数据(软件包、文件、产品) - 对象存储:MinIO/S3 用于存储压缩的 SBOM 文件 两种模式都存储: - **完整 SBOM 保留**:原始和修改后的 syft-json 均原样存储 - **索引的软件包**:用于快速查询的软件包元数据 - **索引的文件**:用于查找的文件路径和摘要 - **容器层**:用于容器扫描的层到镜像的映射 这种双重方法允许: - 跨所有产品的快速查询(数据库) - 用于导出的原始 SBOM 检索(对象存储) ### 导出格式 Syfter 使用 Syft 的原生转换功能生成: | 格式 | 扩展名 | 描述 | |--------|-----------|-------------| | `syft-json` | `.syft.json` | Syft 原生格式(内部存储) | | `spdx-json` | `.spdx.json` | SPDX 2.3 JSON | | `spdx-tv` | `.spdx` | SPDX 标签-值 | | `cyclonedx-json` | `.cdx.json` | CycloneDX 1.4 JSON | | `cyclonedx-xml` | `.cdx.xml` | CycloneDX 1.4 XML | ## 环境变量 ### 客户端变量 | 变量 | 描述 | 默认值 | |----------|-------------|---------| | `SYFTER_DB` | SQLite 数据库路径(本地模式) | `~/.syfter/syfter.db` | | `SYFTER_SERVER` | API 服务器 URL(服务器模式) | 无(使用本地模式) | ### 服务器变量(用于 API 容器) | 变量 | 描述 | 默认值 | |----------|-------------|---------| | `SYFTER_DB_TYPE` | 数据库类型(`sqlite` 或 `postgresql`) | `sqlite` | | `SYFTER_PG_HOST` | PostgreSQL 主机 | `localhost` | | `SYFTER_PG_PORT` | PostgreSQL 端口 | `5432` | | `SYFTER_PG_DATABASE` | PostgreSQL 数据库名 | `syfter` | | `SYFTER_PG_USER` | PostgreSQL 用户名 | `syfter` | | `SYFTER_PG_PASSWORD` | PostgreSQL 密码 | (必需) | | `SYFTER_STORAGE_TYPE` | 存储类型(`local` 或 `s3`) | `local` | | `SYFTER_S3_ENDPOINT` | S3/MinIO 端点 URL | (s3 模式必需) | | `SYFTER_S3_BUCKET` | S3 存储桶名称 | `syfter-sboms` | | `SYFTER_S3_ACCESS_KEY` | S3 访问密钥 | (s3 模式必需) | | `SYFTER_S3_SECRET_KEY` | S3 秘密密钥 | (s3 模式必需) | | `SYFTER_API_KEY` | 客户端 API 密钥(服务器模式) | 无 | | `SYFTER_AUTH_ENABLED` | 启用 API 密钥认证 | `true` | | `SYFTER_ADMIN_API_KEY` | 用于初始管理员访问的种子密钥 | 无 | | `SYFTER_AUTH_CACHE_TTL` | 认证验证缓存 TTL(秒) | `60` | | `SYFTER_RATE_LIMIT_ENABLED` | 启用每密钥速率限制 | `true` | | `SYFTER_RATE_LIMIT_QUERY` | 每密钥每分钟查询请求数 | `60` | | `SYFTER_RATE_LIMIT_QUERY_BURST` | 查询突发允许量 | `20` | | `SYFTER_RATE_LIMIT_UPLOAD` | 每密钥每分钟上传请求数 | `10` | | `SYFTER_RATE_LIMIT_UPLOAD_BURST` | 上传突发允许量 | `5` | | `SYFTER_CACHE_STATS_TTL` | 统计信息缓存 TTL(秒) | `300` | | `SYFTER_CACHE_PRODUCTS_TTL` | 产品缓存 TTL(秒) | `300` | ## 数据库索引(大规模部署) 对于拥有超过 100 万个软件包的部署,以下 PostgreSQL 索引对于查询性能至关重要: ``` -- LIKE prefix queries + ORDER BY (the COLLATE "C" is essential) CREATE INDEX idx_package_name_c ON packages (name COLLATE "C"); -- LIKE via text_pattern_ops (used by the index scan filter) CREATE INDEX idx_package_name_pattern ON packages (name text_pattern_ops); -- Foreign key lookups for product-scoped counts CREATE INDEX idx_packages_product_id ON packages (product_id); CREATE INDEX idx_scan_product ON scans (product_id); -- Dependency queries (package-scoped + type filter) CREATE INDEX idx_dep_package_type ON dependencies (package_id, dependency_type); ``` ## 示例 ### 工作流:生成客户 SBOM ``` # 1. 扫描所有产品 syfter scan /mnt/rhel10-rpms -p rhel -v 10.0 syfter scan /mnt/rhel9-rpms -p rhel -v 9.4 syfter scan registry.redhat.io/ubi9:latest -p ubi -v 9.0 # 2. 检查存储内容 syfter products syfter stats # 3. 跨所有产品查询 syfter query -n "openssl%" # 4. 导出面向客户的 SBOMs mkdir -p customer-sboms syfter export -p rhel -v 10.0 -f all -o customer-sboms/ syfter export -p rhel -v 9.4 -f spdx-json -o customer-sboms/rhel-9.4.spdx.json ``` ### 工作流:查找软件包位置 ``` # 查找包含特定软件包的产品 syfter query -n "curl" --json | jq '.[] | {product: "\(.product_name)-\(.product_version)", version: .version}' # 按路径模式查找文件 syfter query -f "%libssl%" # 按摘要查找文件 syfter query -d "sha256:abc123..." ``` ## 架构 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ syfter CLI │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │ │ Scanner │───>│ Manipulator │───>│ Storage │ │ │ │ (syft, ssh+syft) │ │ (CPE/PURL) │ │ (SQLite/PostgreSQL+S3) │ │ │ └───────────────────┘ └─────────────┘ └───────────┬─────────────┘ │ │ │ │ │ │ │ v │ │ ┌───────┴───────┐ ┌──────────┐ │ │ │ Scan Targets │ │ Exporter │ │ │ ├───────────────┤ │ (SPDX/ │ │ │ │ • Products │ │ CDX) │ │ │ │ - RPM dirs │ └──────────┘ │ │ │ - Containers│ │ │ │ - Archives │ │ │ │ • Systems │ │ │ │ - Localhost │ │ │ │ - SSH hosts │ │ │ └───────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ## 构建与分发 关于以下内容的说明,请参见 [docs/BUILDING.md](docs/BUILDING.md): - 构建用于分发的 Python wheel 包 - 创建容器镜像 - 构建 RPM 包 - 离线安装包 ## 部署 关于生产部署指南,请参见 [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md),包括: - 服务器架构 - PostgreSQL 设置 - MinIO/S3 配置 - systemd 服务文件 - 安全考虑 对于 OpenShift/Kubernetes 部署,API 容器镜像基于 `podman/Containerfile` 构建。典型的生产技术栈包括 Syfter API(通常带有用于浏览器 OIDC 的 oauth2-proxy sidecar)、PostgreSQL 和兼容 S3 的对象存储(MinIO 或通过 IRSA 使用 AWS S3)。 ## 理解容器层 关于以下内容的详细信息,请参见 [docs/MULTI-STAGE-BUILDS.md](docs/MULTI-STAGE-BUILDS.md): - Syfter 如何处理多阶段 Docker/Podman 构建 - 为什么构建阶段的层不会出现在最终镜像中 - 理解编译二进制文件中的 Go 模块检测 - 非包管理文件的文件搜索限制 ## 开发 ``` # 安装开发依赖项 pip install -e ".[all]" # 运行测试 ./scripts/run-tests.sh local # Local SQLite tests ./scripts/run-tests.sh coverage # With coverage report ./scripts/run-tests.sh server # Server tests (requires running server) # 格式化代码 black syfter/ ruff check syfter/ ``` ## 致谢 [syfter](https://github.com/vdanen/syfter) 由 Vincent Danen 开发,红帽产品安全团队贡献。 ## 许可证 Apache License 2.0 ## AI 编码声明 完全透明地说,此代码几乎完全由 AI 编写。虽然 我能用 Python 编程,但我确实没有时间去做,因此 利用了 AI 来完成它。如果有问题(很可能有!),欢迎 提交 PR 修复。此项目背后的意图是 快速创建一个能解决围绕 SBOM 生产和使用 某些挑战的工具。它非常复杂,这就是为什么它 利用了 [Syft](https://github.com/anchore/syft)(何必重新发明轮子呢?)。 如果使用 AI 生成的代码让您感到不安或冒犯,可能还有其他工具可用。如果不是,这个工具可能正在解决 您面临的、对我来说也同样需要解决的挑战。
标签:API安全, Cosign, CycloneDX, DevSecOps, GPT, JSON输出, PostgreSQL, RPM扫描, SBOM生成工具, SLSA, SPDX, SQLite, Syft集成, 上游代理, 企业级部署, 供应链风险管理, 依赖关系跟踪, 元数据丰富, 安全合规, 安全最佳实践, 容器扫描, 导出格式, 开源安全工具, 数据库存储, 查询优化, 测试用例, 漏洞管理, 缓存机制, 网络代理, 请求拦截, 跌倒检测, 跨产品追溯, 跨产品追踪, 软件供应链安全, 软件物料清单, 远程方法调用, 逆向工具, 逆向工程平台