开源漏洞管理神器Vuls:无代理扫描、容器集成与DevSecOps实践
2026/5/17 2:30:22 网站建设 项目流程

1. 项目概述与核心价值

最近几年,安全圈里一个绕不开的话题就是漏洞管理。无论是甲方安全团队还是乙方安全服务,手里没几个趁手的自动化工具,面对海量的CVE编号和资产清单,基本就是两眼一抹黑。传统的漏洞扫描器,像Nessus、OpenVAS,功能强大但部署复杂、授权昂贵,而且扫描结果往往是“一锤子买卖”,缺乏持续跟踪和风险演进分析的能力。正是在这种背景下,一个来自日本的开源项目——Vuls,逐渐走进了很多安全工程师的视野。

Vuls的全称是“Vulnerability Scanner”,但它和我们印象中的主动扫描器不太一样。它更像一个“漏洞情报聚合器”和“风险状态仪表盘”。它的核心工作模式是“无扫描”(Agentless),通过SSH等方式连接到你的服务器,读取系统上已安装软件包的版本信息,然后与多个漏洞数据库(如NVD、JVN、OVAL)进行离线或在线比对,从而判断你的系统是否存在已知漏洞。简单来说,它不主动向目标系统发送探测包去“找”漏洞,而是通过检查系统自身的“软件清单”来“算”出漏洞。这种设计理念带来了几个显著优势:对目标系统影响极小、扫描速度极快、可以轻松集成到CI/CD流程中,并且非常适合对线上生产环境进行定期、快速的漏洞评估。

我第一次接触Vuls是在一个容器化程度很高的微服务架构项目中。当时我们需要一种轻量级、可编程的方法来监控数百个运行着不同基础镜像的容器是否存在已知的Struts2或Log4j2漏洞。传统的扫描器部署和调度成了大问题,而Vuls基于主机的检查模式,配合其强大的报告和通知功能,完美地解决了这个痛点。从那以后,它就成了我安全工具链里的常备选项。接下来,我将从设计思路、实战部署、高级玩法到避坑指南,为你完整拆解这个强大的漏洞管理神器。

2. 架构设计与核心原理拆解

要玩转Vuls,必须理解其“中心-采集”的分布式架构和“信息收集-漏洞匹配-报告呈现”的核心工作流。这能帮助你在部署和排错时心中有数。

2.1 无代理(Agentless)扫描模式解析

Vuls最核心的设计就是无代理扫描。这意味着你不需要在目标服务器上安装任何常驻进程(Agent)。扫描时,Vuls控制器会通过SSH连接到目标服务器,执行一系列预定义的信息收集命令(如rpm -qa,dpkg -l,pip list,npm list --global --depth=0等),然后将收集到的软件包列表带回本地进行分析。

这种模式的优势非常明显:

  1. 部署简单:只需在目标服务器上配置一个用于扫描的SSH账号(通常只需要只读权限),无需安装和运维额外的Agent软件,降低了运维复杂度。
  2. 资源占用低:扫描过程是瞬时的,执行完命令即断开连接,不会在目标服务器上留下持续消耗CPU和内存的进程,对生产环境友好。
  3. 安全性高:避免了因Agent自身漏洞而引入新的攻击面。同时,SSH连接可以使用密钥认证,且账号权限可以严格控制。
  4. 覆盖全面:只要能通过SSH连接,无论是物理机、虚拟机、容器,甚至是网络设备(如果支持Linux命令子集),理论上都可以纳入扫描范围。

当然,这种模式也有其局限性,主要在于它依赖目标系统自身提供的软件包信息。如果某个软件是通过源码编译安装,且未纳入系统包管理器(如yum、apt)的管理,那么Vuls可能无法识别它,从而造成漏报。这是使用无代理扫描器时必须接受的一个前提。

2.2 漏洞匹配引擎:如何知道系统有漏洞?

收集到软件包列表后,Vuls如何判断是否存在漏洞?这是其技术核心。Vuls本身并不维护漏洞库,而是作为一个“连接器”和“分析器”。

  1. 数据源:Vuls会从多个权威漏洞数据库同步数据,主要包括:

    • NVD (National Vulnerability Database):美国官方的漏洞数据库,包含CVE的详细描述、CVSS评分、受影响的CPE(通用平台枚举)信息。
    • JVN (Japan Vulnerability Notes):日本的漏洞信息数据库,对于在日企或使用日本开发软件的场景尤为重要,信息有时比NVD更及时。
    • OVAL (Open Vulnerability and Assessment Language):一种用于描述系统检查状态的XML语言。Vuls支持Red Hat, Ubuntu, Debian等发行版的OVAL定义文件,能进行非常精确的版本匹配。
    • GOST (Go Security Tracker):Vuls作者维护的一个安全数据源,包含一些NVD未收录的漏洞信息。
  2. 匹配过程:Vuls将收集到的软件包名称和版本,转换成标准的CPE格式,然后与漏洞数据库中CVE条目所影响的CPE列表进行匹配。例如,它发现服务器上安装了openssl-1.0.1e-34.el7,而CVE-2014-0166(心脏出血漏洞)影响的CPE中包含cpe:/a:openssl:openssl:1.0.1,且版本在1.0.1到1.0.1f之间,那么就会判定该服务器存在此漏洞。

  3. 优先级计算:匹配到漏洞后,Vuls会综合CVSS v2/v3基础分数、漏洞发布时间、可利用性(Exploitability)等信息,计算出一个自己的优先级分数(Vuls Score),并在报告中直观地以红色(高危)、黄色(中危)等颜色标出,帮助运维人员快速聚焦最紧急的风险。

注意:Vuls的漏洞匹配高度依赖其本地漏洞数据库的完整性和时效性。如果长时间不更新数据库,就无法发现新披露的漏洞。因此,定期(例如每天)更新漏洞数据库是使用Vuls必须建立的运维流程

2.3 报告与通知系统设计

发现漏洞不是终点,如何高效地通知到人并推动修复才是关键。Vuls提供了极其丰富的报告和通知渠道,这是它区别于很多简陋开源工具的地方。

  • 多种报告格式

    • 控制台文本:最直接,适合快速查看。
    • JSON:结构化数据,便于集成到其他自动化系统或自研平台。
    • HTML:功能强大的可视化报告,可以按服务器、按漏洞严重级别筛选、排序,并直接链接到CVE详情页,体验非常好。
    • PDF:方便归档和邮件发送。
    • CycloneDX / SPDX:输出软件物料清单(SBOM),满足日益增长的软件供应链安全需求。
  • 灵活的通知机制

    • Slack / Microsoft Teams:将扫描结果直接发送到团队协作频道。
    • Email:发送HTML或文本格式的邮件报告。
    • ChatWork / Rocket.Chat:支持更多聊天工具。
    • AWS SNS / Google Chat:云原生环境集成。
    • Syslog:将安全事件发送到SIEM(安全信息与事件管理)系统。
    • HTTP POST:将JSON格式的扫描结果回调到指定的Webhook URL,实现最大程度的自定义集成。

这种设计使得Vuls不仅能作为工程师手头的命令行工具,更能轻松融入企业现有的DevSecOps流程,实现漏洞从发现、通知到修复验证的闭环管理。

3. 从零开始部署与配置实战

理论讲得再多,不如动手搭一遍。下面我将以最典型的场景——在CentOS 7控制机上扫描另一台Ubuntu 20.04目标机——为例,带你走通完整的部署和首次扫描流程。

3.1 环境准备与依赖安装

首先,我们需要一台机器作为Vuls的“控制机”。它负责运行Vuls主程序、存储漏洞数据库、生成报告。这台机器最好有稳定的网络(用于拉取漏洞库)和一定的磁盘空间(漏洞数据库约占用10GB+)。

控制机(CentOS 7)准备工作:

  1. 安装基础依赖:Vuls是用Go语言编写的,但它的数据抓取和部分功能依赖一些工具。

    sudo yum install -y sqlite git gcc make
  2. 安装Go语言环境:Vuls需要Go来编译。建议安装较新版本的Go(如1.19+)。

    wget https://golang.org/dl/go1.19.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc echo 'export GOPATH=$HOME/go' >> ~/.bashrc source ~/.bashrc go version # 验证安装
  3. 安装Vuls本体:使用Go的go install命令安装是最简单的方式。

    go install github.com/future-architect/vuls@latest

    安装完成后,二进制文件位于$GOPATH/bin/vuls。确保该路径已在你的PATH环境变量中。

  4. 初始化配置目录:Vuls需要一个目录来存放配置、数据库和缓存。

    mkdir -p ~/vuls-work cd ~/vuls-work vuls init

    执行init后,会在当前目录生成config.toml样例文件。

目标机(Ubuntu 20.04)准备工作:

目标机只需要做一件事:提供一个可以通过SSH密钥对登录的、具有只读权限的账号。

  1. 在目标机上创建一个专门用于扫描的用户,例如vuls-scanner

    sudo useradd -m -s /bin/bash vuls-scanner
  2. 为该用户配置必要的sudo权限,使其能够在不输入密码的情况下执行特定的信息收集命令。这是关键一步。编辑/etc/sudoers.d/vuls文件(使用visudo -f更安全):

    # 允许vuls-scanner用户以root权限运行特定命令,无需密码 vuls-scanner ALL=(ALL) NOPASSWD: /usr/bin/apt-get update, /usr/bin/stat, /usr/bin/find, /bin/cat, /usr/bin/ls, /usr/bin/curl

    实操心得:这里的sudo权限需要精细控制。只授予扫描必需的最小命令集合。上述命令是一个基础集合,Vuls实际会根据扫描模式调用更多命令。一个更省事但安全性稍低的做法是允许所有apt-getdpkg相关命令,例如NOPASSWD: /usr/bin/apt*, /usr/bin/dpkg*。在生产环境中,建议参考Vuls官方文档针对不同OS的推荐sudoers配置。

  3. 在控制机上生成SSH密钥对(如果还没有),并将公钥id_rsa.pub的内容添加到目标机vuls-scanner用户的~/.ssh/authorized_keys文件中。

3.2 配置文件深度解读

config.toml是Vuls的大脑。我们打开它进行详细配置。

[default] # 扫描结果的输出目录 resultsDir = "./results" # 是否在扫描中包含已结束的进程信息(用于检测内存中的漏洞) scanMode = ["fast", "offline"] # fast: 快速扫描, offline: 使用离线模式(需先`vuls fetch`) # 定义第一个服务器 [servers.ubuntu2004] # 这是一个服务器标签,可自定义 host = "192.168.1.100" # 目标服务器IP port = "22" # SSH端口 user = "vuls-scanner" # SSH用户名 keyPath = "/home/youruser/.ssh/id_rsa" # SSH私钥路径 # 目标服务器的类型,决定使用哪种包管理器进行检测 type = "ubuntu" # 可选: ubuntu, debian, centos, redhat, amazon, oracle, suse, alpine... # 发行版版本,帮助精确匹配OVAL release = "20.04" # 可选:如果目标服务器有内部代理,可在此设置用于漏洞库更新的代理 # httpProxy = "http://your-proxy:8080" # 漏洞数据库设置 [cveDict] type = "sqlite3" # 使用SQLite3存储漏洞数据,轻量 url = "https://github.com/vulsio/go-cve-dictionary.git" # 数据源 [ovalDict] type = "sqlite3" url = "https://github.com/vulsio/goval-dictionary.git" [gost] type = "sqlite3" url = "https://github.com/vulsio/gost.git" # 报告设置 [email] smtpAddr = "smtp.gmail.com" smtpPort = "587" user = "your-email@gmail.com" password = "your-app-password" # 注意:使用应用专用密码,非邮箱登录密码 from = "your-email@gmail.com" to = ["team1@example.com", "team2@example.com"]

关键配置项解析:

  • scanModefast是默认模式,扫描已安装的软件包。offline模式需要先执行vuls fetch从目标机收集原始数据到控制机,然后再在控制机上进行分析,适合网络隔离或安全要求极高的环境。fastoffline可以同时使用。
  • typerelease必须准确填写,这直接影响到Vuls选择哪个发行版的OVAL数据进行匹配。填错会导致漏洞检测不全或误报。
  • cveDict,ovalDict,gost:这些是漏洞数据源。首次运行前需要分别初始化这些数据库,这是一个耗时较长的过程(需要下载数GB数据)。

3.3 首次扫描全流程实录

配置好后,我们开始第一次扫描。

  1. 初始化漏洞数据库(耗时最长):在控制机的vuls-work目录下执行。这一步会从GitHub克隆数据源并初始化SQLite数据库。

    # 初始化CVE数据库(NVD, JVN) vuls fetch cve --years 2020 2021 2022 2023 2024 # 指定抓取最近几年的数据,否则会抓全部,数据量巨大 # 初始化OVAL数据库(例如Ubuntu) vuls fetch oval ubuntu 20.04 # 初始化GOST数据库 vuls fetch gost

    注意事项vuls fetch cve如果不加--years参数,会尝试抓取所有年份的CVE数据,耗时可长达数小时,且需要大量磁盘空间。强烈建议在首次搭建时指定最近3-5年的年份,后续再通过定时任务增量更新。

  2. 测试服务器连接与配置:使用configtest命令验证配置是否正确,能否成功连接到目标服务器并执行信息收集。

    vuls configtest

    如果看到[INFO] Test passed for all servers,恭喜你,配置成功。

  3. 执行漏洞扫描

    vuls scan -report-json -report-html

    这个命令会对config.toml中定义的所有服务器进行扫描,并生成JSON和HTML格式的报告。

  4. 查看扫描结果

    • 扫描完成后,结果会保存在./results/当前日期/目录下。
    • 直接使用vuls report命令可以在终端以彩色文本形式查看摘要。
    • 生成的report.html文件可以用浏览器打开,界面非常直观,可以点击每个漏洞查看详情、受影响的服务器,并且直接链接到NVD官网或安全公告。
  5. 发送通知(可选):配置好邮件或Slack后,可以使用vuls report -to-emailvuls report -to-slack来发送报告。

4. 高级应用场景与集成方案

掌握了基础扫描,Vuls还能玩出更多花样,适应更复杂的现代IT架构。

4.1 容器与云原生环境扫描

容器扫描是Vuls的强项。你不需要在每个容器里安装Agent,只需要扫描宿主机,或者扫描容器镜像。

  • 扫描运行中的容器:Vuls支持通过Docker API或SSH到宿主机来扫描容器。需要在config.toml的服务器配置块中增加容器相关设置。

    [servers.docker-host] host = "docker-host-ip" user = "..." # ... 其他SSH配置 containers = ["running-container-name-1", "running-container-name-2"] # 指定容器名 # 或者扫描所有运行中的容器 # containers = ["running"]

    扫描时,Vuls会进入每个容器内部执行包列表收集命令。

  • 扫描容器镜像:Vuls提供了一个子命令vuls img,专门用于扫描本地或远程仓库中的Docker镜像。这对于在CI/CD流水线中构建镜像后立即进行安全检查非常有用。

    # 扫描本地镜像 vuls img scan your-application:latest # 扫描远程仓库镜像(需先登录registry) vuls img scan registry.example.com/your-group/your-app:tag

    镜像扫描的原理是将镜像以只读方式挂载,然后检查其文件系统中的包管理数据库。

4.2 与CI/CD流水线集成

将安全左移,在代码构建和镜像构建阶段就引入漏洞检查,是DevSecOps的核心实践。Vuls可以轻松集成到Jenkins、GitLab CI、GitHub Actions等流水线中。

GitLab CI 集成示例:

stages: - build - security-scan vulnerability-scan: stage: security-scan image: docker:latest services: - docker:dind variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" before_script: - apk add --no-cache go git sqlite - go install github.com/future-architect/vuls@latest - mkdir -p ~/vuls-work && cd ~/vuls-work - vuls init # 简化:只更新最近一年的CVE数据,以加快流水线速度 - vuls fetch cve --years $(date +%Y) --quiet - vuls fetch oval alpine 3.16 --quiet # 假设基础镜像是Alpine 3.16 script: # 1. 构建Docker镜像 - docker build -t my-app:$CI_COMMIT_SHA . # 2. 使用Vuls扫描该镜像 - vuls img scan my-app:$CI_COMMIT_SHA -format=json -output=./scan-result.json # 3. 使用jq等工具解析结果,如果发现CRITICAL或HIGH漏洞,则使任务失败 - if [ $(cat ./scan-result.json | jq '.scannedCves | map(select(.severity == "HIGH" or .severity == "CRITICAL")) | length') -gt 0 ]; then exit 1; fi artifacts: paths: - ./scan-result.json when: always # 即使任务失败,也保留扫描结果报告 allow_failure: false # 发现高危漏洞,则流水线失败

这个例子展示了在构建镜像后立即进行安全质检,并将高危漏洞作为质量门禁。

4.3 大规模部署与自动化运维

当你有成百上千台服务器需要管理时,手动维护config.toml是不现实的。Vuls支持通过外部动态生成配置文件。

  • 使用服务器发现工具:你可以写一个脚本,从你的CMDB(配置管理数据库)、云厂商的API(如AWS EC2 DescribeInstances)、或服务发现工具(如Consul、etcd)中拉取服务器列表,然后动态生成config.toml或直接使用vuls scan-target参数。

    # 示例:从AWS CLI获取所有EC2实例的私有IP,并生成扫描命令 aws ec2 describe-instances --query 'Reservations[].Instances[].PrivateIpAddress' --output text | tr '\t' '\n' | while read ip; do vuls scan -target $ip --results-dir ./results/$(date +%Y%m%d) & done wait

    注意:大规模并发扫描时,要控制并发度,避免对控制机或网络造成过大压力。Vuls本身没有内置并发控制,需要依靠外部脚本(如xargs -P)来实现。

  • 定时扫描与报告:使用cronsystemd timer设置定时任务,定期执行扫描和报告发送。

    # 每天凌晨2点执行扫描,并发送HTML报告邮件 0 2 * * * cd /home/user/vuls-work && /usr/local/bin/vuls scan -report-html && /usr/local/bin/vuls report -to-email -format-html > /dev/null 2>&1

    更推荐的做法是将扫描和报告生成分开,并加入数据库更新步骤:

    # 每周一凌晨1点更新漏洞数据库 0 1 * * 1 cd /home/user/vuls-work && /usr/local/bin/vuls fetch cve --years $(date +%Y) --quiet # 每天凌晨3点执行扫描 0 3 * * * cd /home/user/vuls-work && /usr/local/bin/vuls scan -results-dir ./results/$(date +\%Y\%m\%d) -quiet # 每天凌晨4点发送前一天的扫描报告摘要到Slack 0 4 * * * cd /home/user/vuls-work && /usr/local/bin/vuls report -to-slack -results-dir ./results/$(date -d "yesterday" +\%Y\%m\%d)

5. 常见问题、性能调优与避坑指南

在实际使用中,你肯定会遇到各种问题。下面是我和团队在多年使用中积累的一些典型问题解决方法和优化技巧。

5.1 扫描失败与连接问题排查

问题1:configtest通过,但scan失败,报错Failed to ssh to host

  • 可能原因1:SSH超时。网络延迟或目标服务器负载高,导致SSH连接建立慢。

    • 解决:在config.toml[default]或具体服务器配置中增加timeout参数。
      [servers.my-server] host = "..." # ... timeout = "120s" # 将超时时间从默认的30秒延长
  • 可能原因2:目标服务器SSH配置限制了并发连接数。Vuls在扫描时会并行执行多个命令。

    • 解决:在config.toml中限制并发度。
      [default] scanMode = ["fast"] # 限制最大并发SSH连接数 maxConcurrentSSHSessions = 2

问题2:扫描过程中报错sudo: sorry, you must have a tty to run sudo

  • 原因:目标服务器的sudoers配置要求TTY。而Vuls通过SSH执行命令时默认没有分配TTY。
    • 解决:修改目标服务器上的sudoers配置,为扫描用户添加NOPASSWD权限的同时,允许无TTY。在/etc/sudoers.d/vuls中增加:
      Defaults:vuls-scanner !requiretty
      或者,在Vuls的SSH连接参数中强制分配伪TTY(不推荐,可能引起其他问题)。

5.2 漏洞数据库更新与维护

问题:vuls fetch速度极慢,甚至失败。

  • 原因:NVD等数据源位于国外,网络不稳定。
    • 解决
      1. 使用代理:在config.toml[default]部分或[cveDict]部分配置httpProxy
      2. 使用国内镜像或离线包:社区有一些项目提供了NVD数据的国内镜像或打包好的数据库快照,可以手动下载并替换。但需要注意数据的一致性和及时性。
      3. 增量更新:使用vuls fetch cve --years 2024只更新今年的数据。可以设置一个每日的cron job只增量更新最近几天的数据,再设置一个每周的job更新全年数据。

问题:磁盘空间占用越来越大。

  • 原因:SQLite数据库和缓存文件会随着时间增长。
    • 解决:定期清理旧的扫描结果和缓存。Vuls本身没有自动清理功能,需要写脚本。例如,保留最近30天的扫描结果:
      find ~/vuls-work/results -type d -mtime +30 -exec rm -rf {} \;
      对于CVE数据库,旧年份的数据可以删除。可以直接删除对应的SQLite文件(如cve.sqlite3),然后重新fetch所需年份的数据。但更安全的方法是使用vuls fetch cve --years指定年份,Vuls会进行增量更新,不会重复下载全部数据。

5.3 性能优化与最佳实践

  1. 扫描模式选择

    • fast模式:99%的场景使用此模式,它只检查已安装的软件包。
    • offline模式:在目标机无法出网或安全审计要求极其严格时使用。需要先vuls fetch(从目标机拉数据到控制机),再vuls scan --offline。速度比fast模式慢。
    • fast+offline:同时使用两种模式,offline模式能检测到一些fast模式检测不到的细节(如内核漏洞的精确状态),但扫描时间会加倍。非必要不开启
  2. 目标服务器分组扫描:如果服务器数量多,可以按业务、环境(生产/测试)或操作系统类型分组,创建多个config.toml文件,分批扫描。这样可以缩短单次扫描的周期,也便于分派漏洞修复任务。

  3. 只关注需要关注的漏洞:Vuls支持通过-ignore-unfixed参数忽略未提供官方修复补丁的漏洞(很多Linux发行版对某些CVE的修复会滞后)。也可以编写自定义的忽略规则文件,永久忽略某些在特定环境下被评估为误报或风险可接受的漏洞。

  4. 与CMDB/ITSM集成:将Vuls的JSON报告输出,通过脚本解析后,与你公司的CMDB资产关联,并自动在ITSM(如Jira, ServiceNow)中创建漏洞修复工单,指派给相应的服务器负责人。这是实现漏洞管理闭环的关键一步。

  5. 关注“可利用性”:CVSS分数高不代表一定能被利用。Vuls的报告里会包含“Exploitability”信息。在资源有限的情况下,优先修复那些已有公开利用代码(Exploit)或概念验证(PoC)的漏洞,能更有效地降低真实风险。

5.4 报告解读与误报处理

报告中的“CVE-XXXX-XXXX (Not Fixed Yet)”:这表示Vuls检测到了这个CVE,但目标系统对应的软件仓库中尚未提供安全更新。你需要持续关注发行版的安全公告。

报告中的“CVE-XXXX-XXXX (Ignore)”:这表示该漏洞已被添加到忽略列表中。你需要审查忽略列表,确认这些忽略是否合理。

如何判断是否为误报?

  1. 检查受影响版本范围:点击报告中的CVE编号链接,跳转到NVD官网,仔细阅读“Affected Versions”和“Vendor Advisory”。确认你系统上的软件版本是否真的在受影响范围内。
  2. 检查缓解措施:有些漏洞可能已经通过配置修改(如关闭某个功能模块)得到了缓解,而包版本并未改变。Vuls的包版本检测无法识别这种缓解,需要人工确认。
  3. 检查OVAL定义:对于Red Hat, Ubuntu等系统,Vuls使用OVAL进行精确匹配,误报率较低。对于通过源码或非标准包管理器安装的软件,误报率可能较高,需要人工核实。

处理误报:如果确认是误报,可以在Vuls工作目录下创建ignoreCves.json文件,将CVE ID加入全局忽略列表,避免每次扫描都告警。但务必记录忽略原因,并定期复审。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询