Clair 漏洞扫描服务部署与使用详解

在 Ubuntu 22.04 上从零到一部署 Clair 4 漏洞扫描服务(下载二进制、配置 YAML、连接 PostgreSQL、systemd 托管),实测服务启动与数据库迁移日志,并给出 clairctl 与配置参数速查。

漏洞扫描漏洞扫描Clair2026/10/08

Clair 漏洞扫描服务部署与使用详解

目标:在一台 Ubuntu 22.04 服务器上从零到一部署 Clair 4(Quay 团队开源的漏洞扫描服务),涵盖二进制下载安装、config.yaml 配置、PostgreSQL 初始化、systemd 托管与 clairctl 客户端使用,全程给出真实命令输出。本文基于 Clair v4.9.0(claircore v1.5.48)实测。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • 组件版本:Clair v4.9.0(claircore v1.5.48,clairctl --help 实测)
  • 服务端口:HTTP API localhost:8080,introspection localhost:8089(默认)
  • 数据存储:PostgreSQL 14,数据库 clair,用户 clair,口令示例 q1w2e3r4
  • 安装目录:/opt/data/clair
  • 管理模式:combo(一个进程同时运行 indexer/matcher/notifier 三个子系统)
  • 管理用户:root

二、前置条件

  • Ubuntu 22.04,可访问 GitHub 下载页(若公网受限,可走下方代理拉取方式)。
  • PostgreSQL 14(作为 Clair 持久化后端,必需)。
  • 磁盘:Clair 二进制约 34 MB,漏洞数据库随 updater 增长需预留 10 GB 以上。

三、下载与安装

3.1 获取版本与下载二进制

Clair 4 的发布包在 GitHub Releases(仓库 quay/clair)。查询最新版本与下载地址:

curl -s https://api.github.com/repos/quay/clair/releases/latest | python3 -c \
  "import sys,json; d=json.load(sys.stdin); print(d['tag_name']); [print(a['browser_download_url']) for a in d['assets']]" | head -8

预期回显(节选):

v4.9.0
https://github.com/quay/clair/releases/download/v4.9.0/clair-v4.9.0.tar.gz
https://github.com/quay/clair/releases/download/v4.9.0/clairctl-linux-amd64
…

💡 说明:clair-v4.9.0.tar.gz 为源码包(含 cmd/、config.yaml.sample、Documentation/);服务端与客户端的可执行文件可取自发行渠道提供的预编译产物。若 github.com 直连受限,可改用 https://gh-proxy.com/<直达链接> 类代理拉取。

解压源码包并保留其中的官方配置样例:

mkdir -p /opt/data/clair && cd /opt/data/clair
tar xzf clair-v4.9.0.tar.gz
ls clair-v4.9.0/config.yaml.sample

⚠️ 前置要求:Clair 官方发行渠道(含预编译可执行文件的部署产物)内已含 clair/clairctl;若自行从源码编译需 Go 工具链与可用的模块代理。生产更推荐直接获取官方发行二进制。

3.2 确认可执行文件

Clair 服务端与客户端命令检查(真实输出):

clair --help

预期回显:

Usage of clair:
  -conf string
        The file system path to Clair's config file.
  -mode string
        The operation mode for this server, will default to combo.
clairctl --help

预期回显(节选):

NAME:
   clairctl - interact with a clair API
VERSION:
   v4.9.0 (claircore v1.5.48)
COMMANDS:
   manifest         print a clair manifest for the named tar file
   report           request vulnerability reports
   export-updaters  run updaters and export results
   import-updaters  import updates
   delete           deletes index reports for given manifest digests
   check-config     print a fully-resolved clair config
   admin            run administrator task
GLOBAL OPTIONS:
   --config value, -c value  clair configuration file (default: "config.yaml")
   --help, -h                show help
   --version, -v             print the version

💡 说明:启动时默认会打印两行 invalid compression type: 'none', using no compression as default 提示,属默认配置的日志,不影响运行。

四、安装 PostgreSQL 并初始化

Clair 需要 PostgreSQL 做元数据与漏洞数据的持久化。初始化集群并创建数据库与用户:

apt-get update
apt-get install -y postgresql postgresql-contrib

pg_createcluster 14 main
pg_ctlcluster 14 main start

创建 Clair 专用账号与库:

su - postgres -c "psql -c \"CREATE USER clair WITH LOGIN PASSWORD 'q1w2e3r4';\""
su - postgres -c "createdb -O clair clair"

验证:

su - postgres -c "psql -l" | grep clair

预期回显:

 clair   | clair  | UTF8 | C.UTF-8 | C.UTF-8 |

五、配置文件 config.yaml

以下为实测可用的最小化配置(conbo 模式,含 indexer/matcher/notifier 三子系统,均连同一 clair 库)。参考官方 config.yaml.sample 精简,字段含义见第六节。

---
http_listen_addr: localhost:8080
introspection_addr: localhost:8089
log_level: info
indexer:
  connstring: host=localhost port=5432 user=clair password=q1w2e3r4 dbname=clair sslmode=disable
  scanlock_retry: 10
  layer_scan_concurrency: 5
  migrations: true
matcher:
  indexer_addr: "localhost:8080"
  connstring: host=localhost port=5432 user=clair password=q1w2e3r4 dbname=clair sslmode=disable
  max_conn_pool: 100
  migrations: true
notifier:
  indexer_addr: http://localhost:8080
  matcher_addr: http://localhost:8080
  connstring: host=localhost port=5432 user=clair password=q1w2e3r4 dbname=clair sslmode=disable
  migrations: true
  delivery_interval: 1m
  poll_interval: 5m
metrics:
  name: prometheus

⚠️ 注意:Clair 4.9 已移除旧版 matcher.updater_sets 字段。若直接沿用旧配置会启动失败,真实回显为: failed loading config: error decoding config "/opt/data/clair/config.yaml": unknown field "updater_sets"。删除该字段即可(见第八节 Q1)。

六、systemd 托管与启动验证

6.1 以 combo 模式启动并看日志

前端直接启动(前台模式,便于采集启动日志;生产用 systemd 托管见 6.2):

cd /opt/data/clair && clair -conf /opt/data/clair/config.yaml -mode combo

真实启动日志(节选,覆盖配置加载、INTROSPECTION、按扫描器注册、数据库迁移、匹配器初始化):

{"level":"info","component":"main","version":"v4.9.0 (claircore v1.5.48)","message":"starting"}
{"level":"info","component":"main","lint":"no delivery mechanisms specified (at $.notifier)","time":"2026-10-08T13:35:19Z"}
{"level":"info","component":"main","message":"ready"}
{"level":"info","component":"initialize/Services","message":"begin service initialization"}
{"level":"info","component":"introspection/New","endpoint":"/metrics","server":"localhost:8089","message":"configuring prometheus"}
{"level":"info","component":"libindex/New","message":"registered configured scanners"}
{"level":"info","component":"libvuln/New","message":"libvuln initialized"}
{"level":"info","component":"notifier/postgres/Init","message":"performing notifier migrations"}
{"level":"info","component":"libvuln/updates/Manager.Start","message":"starting initial updates"}
{"level":"info","component":"httptransport/New","path":"/openapi/v1","message":"openapi discovery configured"}

💡 说明:performing notifier migrations 与 migrations: true 相关,会在 PostgreSQL 中自动建表并派生数据库结构;metrics.name: prometheus 使 /metrics 可暴露到 Prometheus。

6.2 配置 systemd 单元

编写 /etc/systemd/system/clair.service:

[Unit]
Description=Clair Vulnerability Scanner
After=network.target postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/data/clair
ExecStart=/usr/local/bin/clair -conf /opt/data/clair/config.yaml -mode combo
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

启用并启动(每行只操作一个单元):

systemctl daemon-reload
systemctl enable clair
systemctl start clair
systemctl status clair

监听端口确认:

ss -lntp | grep -E "8080|8089"

预期回显:

LISTEN 0   4096   127.0.0.1:8080   0.0.0.0:*   users:(("clair",pid=…,fd=…))
LISTEN 0   4096   127.0.0.1:8089   0.0.0.0:*   users:(("clair",pid=…,fd=…))

七、CLI 速查(clairctl)

clairctl 的 --config/-c 指向服务端 config.yaml;服务端需先启动。

# 打印服务端已解析后的完整配置
clairctl -c /opt/data/clair/config.yaml check-config

# 对某个 tar 归档打印其 manifest(索引请求入口)
clairctl -c /opt/data/clair/config.yaml manifest <software>.tar

# 请求漏洞报告
clairctl -c /opt/data/clair/config.yaml report <software>.tar

# 手动运行数据源 updater 并导出结果
clairctl -c /opt/data/clair/config.yaml export-updaters /opt/data/clair/updates.json

# 导入更新
clairctl -c /opt/data/clair/config.yaml import-updaters /opt/data/clair/updates.json

⚠️ 前置要求:manifest/report 需要向服务端登记一待扫描制品(其内容需可被 indexer 拉取),export-updaters 需要网络拉取各数据源;均要求服务端正在运行且注册表/制品地址可达。

八、常见问题(FAQ)

Q1:启动报 unknown field "updater_sets"。 → 见第五节 ⚠️:4.9 已移除该字段,删除后重新启动。属配置迁移的典型报错。

Q2:启动报 must provide a -mode value or set "CLAIR_MODE" in the environment。 → 需显式给 -mode combo(或 indexer/matcher/notifier),或导出环境变量 CLAIR_MODE=combo。真实触发该错误的两种写法见上文。

Q3:clairctl check-config 报 missing needed arguments。 → 该子命令需传入可解析的完整参数/制品信息;确认 -c 指向正确 config 且服务端在线(参考 clairctl 子命令与帮助)。

Q4:扫描结果一直为空或卡在 updater。 → 首次 starting initial updates 需要拉取各数据源(alpine/debian/ubuntu/osv 等)漏洞库,网络不佳时耗时长属正常;export-updaters 可排查拉取情况。

九、卸载方式

# 停止并禁用服务(每行只操作一个单元)
systemctl stop clair
systemctl disable clair
systemctl stop postgresql
systemctl disable postgresql
# 删除二进制与配置
rm -rf /opt/data/clair /usr/local/bin/clair /usr/local/bin/clairctl /etc/systemd/system/clair.service
systemctl daemon-reload
# 彻底清理 PostgreSQL 数据
apt-get autoremove -y postgresql postgresql-contrib
rm -rf /var/lib/postgresql/14/main

十、参考链接

Clair 漏洞扫描服务部署与使用详解 - Quzuo