OpenVAS Docker 部署问题与处理记录
1. 范围与脱敏说明
本文记录一次使用 Greenbone Community Edition(OpenVAS)官方 Docker Compose 配置进行部署、首次初始化、镜像离线迁移和局域网访问配置时遇到的问题及处理方式。
- 主机名统一写为
<openvas-host>、<new-openvas-host>。 - 用户名统一写为
<user>。 - IP、网段、密码和内部目录信息均使用占位符。
- 以下命令假定 Compose 文件目录为
"$GVM_DIR";每次重新 SSH 登录后先设置:
export GVM_DIR="$HOME/greenbone-community-edition"
不要在没有备份的情况下执行
docker compose down -v。该命令会删除数据库、feed 等全部 Docker volumes。
2. 最终验收结果
部署最终达到以下状态:
- 所有核心容器正常运行,数据容器状态为
healthy。 - NVT(漏洞检测插件)已导入
gvmd数据库;本次快照为 186002 个。 - CERT 和 SCAP(CVE/CPE)数据均已导入完成。
- Web 界面可以使用
admin登录,HTTPS 443 可按需向局域网开放。
完整完成标志:
Finished loading VTs. The VT cache has been updated ...
sync_cert: Updating CERT info succeeded.
update_scap_end: Updating SCAP info succeeded
Updating VTs in database ... done (... VTs).
可一次性核验:
docker compose -f "$GVM_DIR/compose.yaml" logs --since 24h ospd-openvas gvmd \
| grep -E 'Finished loading VTs|Updating VTs in database .*done|update_scap_end: Updating SCAP info succeeded|sync_cert: Updating CERT info succeeded'
3. 问题与处理记录
3.1 scap-data 镜像拉取中断
现象
scap-data:latest 体积较大,拉取时出现网络超时或传输中断,例如:
read tcp ...: i/o timeout
unexpected EOF
判断
该问题发生在镜像层下载阶段,不等同于镜像损坏或 OpenVAS 配置错误。其他镜像已经完成并不能说明 scap-data 可用;应以 Docker 显示下载成功、并在 docker images 中可见为准。
处理
对单个镜像重试拉取,避免反复下载已完成的其他镜像:
until docker pull registry.community.greenbone.net/community/scap-data:latest; do
echo 'scap-data 拉取失败,5 秒后重试...'
sleep 5
done
完成后再运行:
docker compose -f "$GVM_DIR/compose.yaml" pull
3.2 首次 up -d 时 scap-data 显示 unhealthy
现象
首次启动出现:
dependency failed to start: container ...-scap-data-1 is unhealthy
从而使依赖 scap-data 的 gvmd 暂不创建或暂不启动。
排查依据
查看容器日志可见:
docker compose -f "$GVM_DIR/compose.yaml" logs --tail=200 scap-data
若日志最后包含:
Copying SCAP data...
files copied.
说明数据复制已完成。进一步检查健康状态:
docker inspect --format \
'状态={{.State.Status}};健康={{.State.Health.Status}};退出码={{.State.ExitCode}}' \
greenbone-community-edition-scap-data-1
处理
等待容器变为 healthy,然后重新运行完整启动即可:
docker compose -f "$GVM_DIR/compose.yaml" up -d
不要因此执行 down -v;该场景只是在大数据复制完成前健康检查尚未通过。
3.3 新 SSH 会话中 DOWNLOAD_DIR 丢失
现象
重新 SSH 登录后执行 Compose 命令报错:
open /compose.yaml: no such file or directory
原因
之前使用 export DOWNLOAD_DIR=... 设置的 shell 环境变量只在原 SSH 会话中有效;新会话变量为空,导致 Compose 路径退化为 /compose.yaml。
处理
每次登录后重新设置变量,或始终使用绝对路径:
export GVM_DIR="$HOME/greenbone-community-edition"
docker compose -f "$GVM_DIR/compose.yaml" ps
# 等价写法
docker compose -f /home/<user>/greenbone-community-edition/compose.yaml ps
3.4 第二台主机仅完成 NVT 文件加载,gvmd 未创建
现象
第二台主机先出现:
Finished loading VTs. The VT cache has been updated ...
但执行以下命令没有任何容器记录:
docker compose -f "$GVM_DIR/compose.yaml" ps gvmd
这说明 ospd-openvas 已加载插件文件,但 gvmd 尚未创建,因此插件、CERT、SCAP 尚未写入 PostgreSQL 数据库。
处理
确认 feed 数据容器已健康后,再执行完整编排启动:
docker compose -f "$GVM_DIR/compose.yaml" up -d
docker compose -f "$GVM_DIR/compose.yaml" ps gvmd
无需重新拉镜像,也无需删除卷。
3.5 首次 feed 导入耗时很长,且日志不连续
现象
NVT 导入完成后,gvmd 继续依次导入 CERT、CVE、CPE;在 CPE 关联阶段,可能长时间只有如下日志:
Updating CVSS scores and CVE counts for CPEs
期间还可能出现:
write_to_client_unix: failed to write to client: Broken pipe
update_epss_scores: EPSS scores file ... not found
判断
Broken pipe通常是管理界面、CLI 或日志客户端断开,不代表gvmd导入任务失败。- EPSS 文件不存在是可选评分增强数据缺失的信息提示,不影响 NVT、CVE、CPE 的基础扫描能力。
- 只要
gvmd保持Up (healthy),并最终出现update_scap_end: Updating SCAP info succeeded,即可判定 SCAP 导入成功。
检查命令
docker compose -f "$GVM_DIR/compose.yaml" ps gvmd
docker stats --no-stream \
"$(docker compose -f "$GVM_DIR/compose.yaml" ps -q gvmd)"
首次导入期间不要因日志间隔而重启容器;重启会延长初始化时间。
3.6 数据/初始化容器 Exited 是否异常
现象
以下服务显示 Exited:
gpg-data
pg-gvm-migrator
gvm-config
configure-openvas
判断与处理
这是正常状态。这些都是一次性任务,分别用于复制 GPG 数据、迁移数据库、生成 Nginx/TLS 配置以及生成 OpenVAS 配置。只要其 Compose 结果为成功完成,之后退出是预期行为;不应强行使其保持运行。
3.7 离线迁移镜像时 scp 连接到错误端口
现象
使用下列错误格式传输,仍会尝试连接默认 SSH 端口 22:
scp file.tar <user>@<new-openvas-host>:8022:/home/<user>/
并出现:
ssh: connect to host ... port 22: Connection refused
原因与处理
scp 的 SSH 端口必须使用大写 -P 指定:
scp -P <ssh-port> greenbone-images.tar greenbone-images.tar.sha256 compose.yaml \
<user>@<new-openvas-host>:/home/<user>/
4. 镜像离线迁移标准流程
在源主机导出当前 Compose 所需的全部镜像:
cd "$GVM_DIR"
docker compose -f compose.yaml config --images | sort -u > greenbone-images.txt
docker image save -o greenbone-images.tar $(cat greenbone-images.txt)
sha256sum greenbone-images.tar > greenbone-images.tar.sha256
将 greenbone-images.tar、greenbone-images.tar.sha256 和同一份 compose.yaml 复制到新主机。新主机导入并启动:
sha256sum -c greenbone-images.tar.sha256
docker load -i greenbone-images.tar
mkdir -p "$GVM_DIR"
mv compose.yaml "$GVM_DIR/"
docker compose -f "$GVM_DIR/compose.yaml" up -d
注意:
- 新主机不要先执行
docker compose pull,否则会重新联网检查/下载镜像。 - 迁移镜像不迁移运行数据。新主机会创建独立 volumes,并重新将 feed 数据复制和导入到自己的数据库。
- 源、目标主机应使用相同 CPU 架构(通常为
amd64)。
5. 管理员密码与局域网 HTTPS 访问
5.1 修改默认管理员密码
首次完成后立即更改 admin 密码:
docker compose -f "$GVM_DIR/compose.yaml" \
exec -u gvmd gvmd gvmd --user=admin --new-password='<strong-password>'
密码含 $ 时应使用单引号;避免将真实密码写入命令历史或文档。
5.2 仅向局域网开放 HTTPS 443
官方默认端口映射仅监听 127.0.0.1。如需让局域网浏览器访问,编辑 compose.yaml。
在 gvm-config.environment 中加入(替换为实际局域网 IP 或内部 DNS 名称):
NGINX_HOST: "<lan-ip-or-dns>"
NGINX_ACCESS_CONTROL_ALLOW_ORIGIN_HEADER: "https://<lan-ip-or-dns>"
将 Nginx 端口映射改为:
ports:
- "443:443"
- "127.0.0.1:9392:9392"
重新生成配置:
docker compose -f "$GVM_DIR/compose.yaml" config -q
docker compose -f "$GVM_DIR/compose.yaml" \
up -d --force-recreate gvm-config nginx
验收应显示:
0.0.0.0:443->443/tcp
若使用 UFW,只允许实际局域网网段访问 443:
sudo ufw allow from <lan-cidr> to any port 443 proto tcp
不要将 9392 暴露到局域网或互联网;日常浏览器管理使用 HTTPS 443 即可。首次访问自签名证书时会有浏览器告警,后续可替换为内部 CA 或受信任证书。
6. 日常运维检查清单
# 容器与健康状态
docker compose -f "$GVM_DIR/compose.yaml" ps
# 查看服务日志
docker compose -f "$GVM_DIR/compose.yaml" logs --tail=100 gvmd ospd-openvas nginx
# 验证 Docker 守护进程开机启动
sudo systemctl enable --now docker
sudo systemctl is-enabled docker
核心常驻服务包括 redis-server、pg-gvm、gvmd、gsad、nginx、openvasd 和 ospd-openvas。初始化容器退出并不影响已完成的部署;数据持久化在 Docker named volumes 中。