服务器可以正常访问,不代表它没有风险。过期的 Web 组件、暴露的管理端口、弱 TLS 配置、缺失的安全补丁和错误的软件版本,都可能在业务看似正常时留下攻击入口。人工逐台检查很容易遗漏,而 OpenVAS/Greenbone 能够把资产发现、漏洞测试、风险评分、报告和复查集中到一套界面中。
本文以 Ubuntu 24.04、Greenbone Community Containers、Docker Compose 和 Caddy 为基准,完整演示如何在 VPS 上搭建通常被称为 OpenVAS 的漏洞扫描平台,包括资源规划、官方 Compose 部署、Feed 同步、管理员密码、HTTPS、授权目标扫描、结果复核、备份、升级和故障排查。
需要先说明:Greenbone 官方把社区容器定位为体验最新功能和熟悉产品的方式,并明确表示这份容器指南不面向正式生产部署。因此,本文适合个人实验室、内部验证、小规模授权扫描和产品评估;对有 SLA、合规审计、高可用或厂商支持要求的企业环境,应评估 Greenbone Enterprise Appliance,或依据官方源代码构建与运维指南设计正式架构。
很多搜索结果仍把整套系统叫作 OpenVAS,但现在更准确的关系是:
- OpenVAS Scanner:执行漏洞测试的扫描器;
- gvmd:管理目标、任务、用户、结果和 PostgreSQL 数据;
- GSA/gsad:浏览器界面及其 API 服务;
- Greenbone Community Feed:提供漏洞测试、CVE/CPE、扫描配置、端口列表和报告格式;
- Greenbone Community Edition:上述开源组件组成的完整漏洞管理框架。
因此,“安装 OpenVAS”不是只启动一个扫描进程。官方容器栈包含 PostgreSQL、Redis、gvmd、GSA、gsad、Nginx、ospd-openvas、OpenVAS Scanner、Notus 和多组 Feed 数据容器。遇到问题时,要判断故障发生在 Web、管理器、扫描器、数据库还是 Feed,而不是笼统地重装 OpenVAS。
| 方案 | 主要能力 | 适合回答的问题 | 局限 |
|---|---|---|---|
| OpenVAS / Greenbone | 主动漏洞扫描与报告 | 目标暴露了什么服务、可能存在哪些漏洞 | 扫描有资源与业务影响,需要授权 |
| Wazuh | Agent、日志、FIM、配置与终端检测 | 主机正在发生什么安全事件 | 不是通用网络漏洞扫描器 |
| Nmap | 主机发现、端口与服务识别 | 哪些端口开放、服务是什么 | 不提供完整漏洞管理闭环 |
OpenVAS 是“主动去检查目标”,Wazuh 是“持续收集终端安全状态”。两者可以互补:先用 OpenVAS 找出外部暴露面,再用Wazuh SIEM/XDR 教程持续监测登录、文件变化、漏洞清单和安全事件。
漏洞扫描会主动连接大量端口、发送探测请求,并可能触发 IDS、WAF、账号锁定、限流或服务异常。开始前必须满足以下条件:
- 目标属于你,或你持有明确的书面授权;
- 授权说明目标 IP、域名、端口范围、时间窗口和允许的测试强度;
- 云厂商、托管商和应用平台政策允许这类扫描;
- 已通知运维与安全人员,避免把测试当成真实攻击;
- 关键系统有近期备份、监控和可执行的回滚方案。
不要扫描随机公网 IP、邻居租户、未授权客户系统,也不要把漏洞扫描当成“无害的端口探测”。本文只讨论防御性、已授权的安全评估。
Greenbone 官方社区容器文档给出的最低配置是 2 核 CPU、4GB 内存、20GB 可用磁盘,推荐配置为 4 核 CPU、8GB 内存、60GB 可用磁盘。初次 Feed 加载、并行扫描和报告查询会同时消耗 CPU、内存与随机 I/O,生产式评估建议从推荐值起步。
| 使用规模 | 建议起步配置 | 说明 |
|---|---|---|
| 功能验证、单个测试目标 | 2 vCPU、4GB RAM、40GB NVMe | 低并发,初次 Feed 可能较慢 |
| 小团队、周期扫描数十台主机 | 4 vCPU、8GB RAM、80GB NVMe | 更接近官方推荐值 |
| 多网段或大量 Web 服务 | 8 vCPU、16GB RAM 起 | 先压测,并限制并发任务 |
扫描器的位置会影响结果。部署在公网 VPS 上,看到的是目标的公网暴露面;部署在内网或通过 WireGuard 进入目标网段,才能发现仅内部开放的数据库、面板和管理服务。若要同时评估公网和内网,使用不同扫描节点与任务,避免混淆网络边界。
不要把扫描器与关键业务放在同一台低配 VPS 上。扫描期间 CPU、网络连接数和磁盘会明显上升,可能影响网站、数据库或邮件服务。
准备域名,例如 openvas.example.com,将 A 记录指向 VPS。若没有可用 IPv6,不要保留错误的 AAAA 记录。
安装基础工具和 Caddy:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y ca-certificates curl caddy
docker --version
docker compose version
Docker 应通过官方 Ubuntu 仓库安装。把普通用户加入 docker 组相当于授予接近 root 的控制能力,只应对可信管理员执行;更严格的环境可以始终通过 sudo docker 管理。
检查主机资源和时间:
nproc
free -h
df -h
timedatectl status
磁盘不足会导致 PostgreSQL 或 Feed 加载异常。开始前还应确认云安全组只开放 SSH、HTTP 和 HTTPS,不要为扫描器随意开放数据库或内部 API 端口。
Greenbone Community Containers 采用滚动发布模式,官方要求始终使用最新的 compose.yaml。这意味着教程不能可靠地声称“所有容器统一为某个 OpenVAS 版本”。更稳妥的做法是保存下载时间、Compose 哈希和镜像摘要。
sudo install -d -m 750 -o "$USER" -g "$USER" /opt/greenbone-community-edition
cd /opt/greenbone-community-edition
curl -fL https://greenbone.github.io/docs/latest/_static/compose.yaml \
-o compose.yaml
date -Is | tee compose-downloaded-at.txt
sha256sum compose.yaml | tee compose.yaml.sha256
docker compose -f compose.yaml config --quiet
config --quiet 没有输出且退出码为 0,说明 Compose 语法可以解析。不要从旧博客复制多年未更新的 docker-compose.yml,也不要使用来历不明的单容器镜像。
官方 Compose 默认把 Nginx 的 HTTPS 映射到宿主机 127.0.0.1:443。由于 Caddy 需要占用公网 443,复制一份生产配置,把 Greenbone 内部 HTTPS 改到回环地址 9443:
cd /opt/greenbone-community-edition
cp compose.yaml compose.production.yaml
sed -i 's/127.0.0.1:443:443/127.0.0.1:9443:443/' \
compose.production.yaml
docker compose -f compose.production.yaml config > compose.rendered.yaml
grep -nE '127\.0\.0\.1.*(9443|9392)' compose.rendered.yaml
必须看到 9443 和 9392 只绑定 127.0.0.1。如果原文件结构以后改变,sed 可能没有命中;因此每次下载新 Compose 后都要检查渲染结果,不能只看命令是否报错。
拉取镜像并启动:
cd /opt/greenbone-community-edition
docker compose -f compose.production.yaml pull
docker compose -f compose.production.yaml up -d
docker compose -f compose.production.yaml ps
docker compose -f compose.production.yaml images --digests \
| tee images-with-digests.txt
镜像摘要文件能记录当时实际运行的构建。滚动更新后,如果必须回溯问题,可以对照旧摘要,而不是只凭 stable 或 latest 标签猜测。
官方栈包含会复制 Feed 数据后保持运行或正常结束的辅助容器,不能仅凭某个数据容器退出就认定部署失败。重点检查 pg-gvm、gvmd、ospd-openvas、gsad、nginx 和 redis-server:
docker compose -f compose.production.yaml ps
docker compose -f compose.production.yaml logs --tail=100 pg-gvm
docker compose -f compose.production.yaml logs --tail=100 gvmd
docker compose -f compose.production.yaml logs --tail=100 ospd-openvas
docker compose -f compose.production.yaml logs --tail=100 nginx
curl -kI https://127.0.0.1:9443/
这里的 curl -k 只用于检查本机自签名上游,不能作为公网跳过 TLS 验证的理由。
OpenVAS 能否正常扫描,关键不只是容器运行,而是漏洞测试和安全数据是否已经下载并加载。Greenbone 官方说明 Feed 同步分为两部分:
- 通过数据容器镜像下载变化;
- 由扫描器和
gvmd把数据加载到内存与数据库。
初次加载可能持续几分钟到数小时。没有加载完成就开始扫描,会产生不完整或错误的结果。观察日志:
cd /opt/greenbone-community-edition
docker compose -f compose.production.yaml logs -f ospd-openvas gvmd
重点等待类似以下完成信息:
Finished loading VTs. The VT cache has been updated from version X to Y.
Updating VTs in database ... done (X VTs).
update_scap_end: Updating SCAP info succeeded
sync_cert: Updating CERT info succeeded.
还应在 Web 后台检查 Feed 状态,并确认 Full and fast 扫描配置、端口列表和报告格式已经出现。不要用固定 VT 数量判断完成,因为 Feed 会持续变化。
以后更新 Feed 时,官方容器流程是拉取数据镜像并重新运行数据容器:
docker compose -f compose.production.yaml pull \
notus-data vulnerability-tests scap-data dfn-cert-data \
cert-bund-data report-formats data-objects
docker compose -f compose.production.yaml up -d \
notus-data vulnerability-tests scap-data dfn-cert-data \
cert-bund-data report-formats data-objects
后台服务会继续自动加载新数据。Feed 更新不应与高负载扫描、数据库备份同时运行。
官方容器默认创建 admin / admin,这是公开文档中的不安全初始凭据。启动后立即修改:
cd /opt/greenbone-community-edition
docker compose -f compose.production.yaml exec -u gvmd gvmd \
gvmd --user=admin --new-password='替换为随机强密码'
真实密码不要原样写进脚本、Git、截图或工单。更安全的做法是在交互式终端临时读取密码并执行,随后清理 shell 历史中可能留下的敏感命令。
确认新密码可以登录,并验证旧的 admin 密码已经失效。多人管理时为每位管理员创建独立账号,不要共享 admin;扫描报告可能包含主机版本、端口、弱点和内部地址,应按敏感安全数据管理。
Greenbone 自带 Nginx 在 127.0.0.1:9443 提供自签名 HTTPS,Caddy 对外申请可信证书并反向代理。编辑 /etc/caddy/Caddyfile:
openvas.example.com {
encode zstd gzip
reverse_proxy https://127.0.0.1:9443 {
transport http {
tls_insecure_skip_verify
}
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
Referrer-Policy "no-referrer"
}
}
tls_insecure_skip_verify 只作用于同一 VPS 上 Caddy 到 Greenbone 自签名证书的回环连接;浏览器到 Caddy 仍使用可验证的 HTTPS。更严格的做法是把 Greenbone 内部 CA 加入 Caddy 的信任配置。
验证并重载:
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
curl -I https://openvas.example.com/
若平台只供自己使用,优先通过 WireGuard、Tailscale 或固定管理 IP 限制入口。若必须公网开放,至少使用强密码、独立账号和额外访问控制。完整的主机加固步骤可参考VPS 安全加固指南。
Greenbone 的数据库、Redis、gvmd socket、扫描器和内部 API 不需要映射公网。防火墙只开放管理所需端口:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status numbered
如果管理人员有固定 IP,可以把 443 收紧到来源白名单。修改 UFW 前保留一个已登录 SSH 会话,并确认云厂商控制台或救援模式可用,避免把自己锁在服务器外。出现端口已监听但无法访问时,按端口、防火墙和安全组排查指南逐层检查。
检查最终监听地址:
sudo ss -lntup | grep -E ':80|:443|:9392|:9443'
9443 和 9392 应只显示 127.0.0.1,公网 443 应由 Caddy 监听。
首次扫描建议使用一台非关键测试 VPS,不要直接选择生产数据库或整个大网段。
在 Greenbone Web 界面中:
- 进入 Configuration > Targets;
- 创建目标并填写已授权的 IP 或域名;
- 先选择较小的端口列表,明确要检查的服务范围;
- Alive Test 根据目标是否响应 ICMP、TCP ACK 或 ARP 选择;
- 保存目标后进入 Scans > Tasks;
- 使用
Full and fast创建任务,先保持较低并发; - 启动任务并观察扫描器、目标和业务监控。
如果目标禁用了 Ping,默认 Alive Test 可能把在线主机判断为不可达。可以选择更符合网络策略的 TCP 探测或“认为主机存活”,但这样会增加扫描时间和连接量。
不要一开始就扫描 /16、全端口和所有目标。先用一台主机验证报告、误报、性能影响与通知流程,再逐渐扩大范围。
无凭据扫描从网络外部观察服务,适合发现公开端口、TLS、Web 服务和远程可识别的软件版本。它看不到许多仅能通过系统包数据库、补丁状态和本地配置确认的问题。
凭据扫描能提供更深的主机信息,但也引入更高风险:
- 使用专用扫描账号,而不是日常管理员账号;
- 仅授予完成检查所需的权限;
- SSH 私钥设置口令并安全保管;
- 不把生产 root 密码直接保存在共享扫描器中;
- 记录凭据创建、轮换、吊销和扫描访问日志;
- 扫描器被攻破时,凭据不应能横向控制全部服务器。
对 Linux 目标,可以创建受限 SSH 账号并按 Greenbone 检查需求配置必要的提权。先在测试机验证,确认不会触发 PAM 锁定、Fail2Ban 或堡垒机异常。
Greenbone 会按严重度展示结果,但 CVSS 分数不是唯一修复顺序。每条高危结果至少复核:
- 目标和端口是否属于当前资产;
- 软件版本识别是否准确;
- 漏洞是否需要认证、特定配置或用户交互;
- 当前网络边界是否允许攻击路径;
- 发行版是否已经回移安全补丁,但包版本看起来较旧;
- 修复是否会影响兼容性和业务窗口。
推荐把结果分为:已确认、误报、接受风险、计划修复和已修复待复测。不要把导出的 PDF 报告直接转发到公开聊天群,也不要因为扫描器给出“High”就未经验证地在生产环境卸载组件。
修复后创建复测任务,确认原结果消失且业务仍正常。扫描只能提供某个时间点的视图,不能替代持续补丁管理、日志监测和配置基线。
扫描器与目标都可能成为瓶颈。安排定时任务时:
- 避开备份、发布、账务结算和流量高峰;
- 把不同网段和业务分批扫描;
- 先控制并发主机数,再扩展端口与测试范围;
- 同时观察扫描 VPS 和目标 VPS 的 CPU、内存、连接数与延迟;
- 为异常中止、目标不可用和扫描超时配置通知;
- 不要让多个重复任务同时扫描同一目标。
首次完整扫描耗时取决于端口范围、网络延迟、目标响应、VT 数量和并发配置,不能承诺固定的“几分钟完成”。
容器可以重建,但扫描目标、任务、用户、报告与配置存放在 PostgreSQL 和持久化卷中。只备份 compose.yaml 无法恢复这些数据;只依赖同一块 VPS 磁盘上的 Docker 卷也不是备份。
先记录当前状态:
cd /opt/greenbone-community-edition
docker compose -f compose.production.yaml config --volumes \
| tee persistent-volumes.txt
docker compose -f compose.production.yaml images --digests \
| tee images-with-digests.txt
对于小规模社区容器,可以在维护窗口执行一致性更高的冷备份。下面的流程停止容器但不删除卷,然后逐个归档 Compose 声明的命名卷:
GVM_DIR=/opt/greenbone-community-edition
GVM_BACKUP_DIR="/srv/backups/greenbone/$(date +%F_%H%M%S)"
sudo install -d -m 700 -o "$USER" -g "$USER" "$GVM_BACKUP_DIR"
cd "$GVM_DIR"
docker compose -f compose.production.yaml down
docker compose -f compose.production.yaml config --volumes \
| while read -r volume; do
full_volume="greenbone-community-edition_${volume}"
docker run --rm \
--mount "type=volume,src=${full_volume},dst=/source,readonly" \
--mount "type=bind,src=${GVM_BACKUP_DIR},dst=/backup" \
alpine:3.22 \
sh -c "tar -C /source -czf /backup/${volume}.tar.gz ."
done
cp compose.yaml compose.production.yaml compose.yaml.sha256 \
compose-downloaded-at.txt images-with-digests.txt "$GVM_BACKUP_DIR"/
sha256sum "$GVM_BACKUP_DIR"/* > "$GVM_BACKUP_DIR/SHA256SUMS"
docker compose -f compose.production.yaml up -d
备份完成后把目录加密复制到另一台主机或对象存储。恢复只能在隔离环境或确认为空的新栈中进行:先使用同一份 Compose 创建卷,再把每个归档解压回同名卷,最后启动并验证管理员登录、Feed、目标、任务和历史报告。不要把归档直接覆盖到正在运行的 PostgreSQL 卷。
恢复演练比“备份命令退出 0”更重要。通用的异地副本、保留周期和校验策略可以参考VPS 自动备份方案。
Greenbone 官方容器是滚动发布。官方更新流程是获取最新 Compose、拉取镜像并重新启动有变化的服务,但生产式评估不应直接覆盖现有配置:
- 在维护窗口前完成离机备份和恢复抽查;
- 下载新的
compose.yaml到临时文件; - 比较新旧 Compose,重新应用
9443回环端口修改; - 运行
docker compose config --quiet; - 拉取镜像并记录新摘要;
- 启动后等待 Feed 数据重新加载;
- 验证登录、目标、任务、报告和测试扫描;
- 观察 PostgreSQL、gvmd 和扫描器日志。
不要执行 docker compose down -v。-v 会删除命名卷,官方也把它列为“从头开始、删除全部数据”的操作。
curl -kI https://127.0.0.1:9443/
docker compose -f /opt/greenbone-community-edition/compose.production.yaml ps
docker compose -f /opt/greenbone-community-edition/compose.production.yaml logs --tail=100 nginx gsad gvmd
sudo journalctl -u caddy -n 100 --no-pager
本机 9443 失败说明问题在 Greenbone Nginx、GSA、gsad 或端口映射;本机成功但域名失败,再检查 Caddy、DNS、证书和云安全组。
官方建议先重启扫描器,让它重新发现 VT:
cd /opt/greenbone-community-edition
docker compose -f compose.production.yaml restart ospd-openvas
docker compose -f compose.production.yaml logs -f ospd-openvas gvmd
等待日志明确显示 VT 缓存与数据库更新完成,不要连续重启打断加载。
官方提供了强制重建 gvmd Feed 数据的命令:
docker compose -f /opt/greenbone-community-edition/compose.production.yaml \
exec -u gvmd gvmd gvmd --rebuild-gvmd-data=all
扫描配置依赖 VT 已先加载完成。Feed 仍在同步时反复重建不会解决根因。
先确认 ospd-openvas 是否运行,再重启并查看日志:
docker compose -f /opt/greenbone-community-edition/compose.production.yaml \
restart ospd-openvas
docker compose -f /opt/greenbone-community-edition/compose.production.yaml \
logs --tail=200 ospd-openvas gvmd
gvmd 可能无法连接 PostgreSQL 或 Unix socket。官方故障排查建议重启 gvmd,随后检查数据库日志:
docker compose -f /opt/greenbone-community-edition/compose.production.yaml restart gvmd
docker compose -f /opt/greenbone-community-edition/compose.production.yaml \
logs --tail=200 gvmd pg-gvm
检查目标地址、DNS、Alive Test、目标防火墙和扫描器出口 IP。目标可能禁用 ICMP,但允许 TCP;也可能只允许内网访问,而扫描器位于公网。不要通过关闭目标全部防火墙来“验证”。
df -h
docker system df
docker volume ls | grep greenbone-community-edition
先区分 PostgreSQL、Feed 数据、日志和镜像占用。不要直接删除不认识的 Docker 卷;先备份并确认卷用途,再调整报告保留、扫描频率或扩容磁盘。
- 只扫描自有或书面授权的目标
- 已记录 Compose 下载时间、哈希和镜像摘要
- Greenbone
9443/9392只监听127.0.0.1 - 默认
admin / admin已失效 - 公网入口使用可信 HTTPS,并限制管理来源
- 初次 Feed 已完成下载和数据库加载
- 已用非关键目标验证扫描与复测流程
- 凭据扫描使用独立最小权限账号
- 扫描结果按敏感数据保护
- 备份位于异机,并完成隔离恢复演练
- 更新前比较新旧 Compose,没有使用
down -v - 监控扫描器及目标的资源和业务状态
OpenVAS Scanner 是执行漏洞测试的组件;Greenbone Community Edition 是包含扫描器、管理器、Web 界面、数据库和 Feed 的完整框架。日常所说的“OpenVAS 安装”通常指部署整套 Greenbone 社区版。
不建议。官方社区容器最低要求是 4GB 内存,推荐 8GB。初次 Feed 加载、扫描与数据库查询并发时,2GB 很容易发生 OOM、加载失败或页面无响应。
Feed 镜像下载完成后,ospd-openvas 和 gvmd 还要把 VT、SCAP、CERT、端口列表和扫描配置加载到内存与数据库。官方说明初次过程可能持续数小时,应以完成日志和后台 Feed 状态判断。
技术上可以连接可达目标,但只能扫描你拥有或明确获得授权的系统,还要遵守云厂商与托管商政策。未经授权扫描随机公网目标可能造成投诉、封禁或法律风险。
不能。OpenVAS 进行周期性的主动漏洞扫描;Wazuh 持续收集 Agent、日志、文件完整性和安全事件。前者发现暴露面与潜在漏洞,后者监测主机日常状态和攻击行为。
远程识别可能依赖 Banner 或行为特征,Linux 发行版也可能把安全补丁回移到看似较旧的版本。应结合系统包信息、发行版安全公告、漏洞前提和网络路径人工复核。
社区容器采用滚动发布,更新前应保存 Compose 与镜像摘要、完成备份、比较新旧配置,并在维护窗口验证 Feed、登录、任务和报告。不能只执行 pull 后假设所有数据都兼容。
普通 down 不会删除命名卷;down -v 会删除卷和其中数据。无论是否使用 -v,Docker 卷都不能替代异机备份和恢复演练。
在 VPS 上搭建 OpenVAS/Greenbone,真正困难的不是启动容器,而是管理滚动版本、等待 Feed 完整加载、控制扫描授权与负载、正确复核报告,并保证数据库和卷能够恢复。
稳妥的上线顺序是:保存官方 Compose 快照,收敛 Web 端口,修改默认密码,等待 Feed 完成,只对一台授权测试机运行低并发扫描,建立复核与修复闭环,再逐步扩大资产范围。社区容器适合学习和评估;如果环境要求正式生产支持、高可用和合规保证,应采用与风险等级匹配的架构和产品。
官方参考:
