Clair 漏洞扫描服务部署与使用详解
在 Ubuntu 22.04 上从零到一部署 Clair 4 漏洞扫描服务(下载二进制、配置 YAML、连接 PostgreSQL、systemd 托管),实测服务启动与数据库迁移日志,并给出 clairctl 与配置参数速查。
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,introspectionlocalhost: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 官方文档:https://quay.github.io/clair/
- GitHub 仓库:https://github.com/quay/clair
- Claus 发布页:https://github.com/quay/clair/releases
- Clair v4 架构与配置:https://quay.github.io/clair/v4/config.html