简介:CIS-CAT 漏扫工具包面向系统管理员、安全运维及合规检查人员,围绕 CIS 基准对 Windows、Linux、Unix 等操作系统开展自动化配置核查与漏洞识别,适合日常安全巡检、等保合规自查及小规模测试环境使用。压缩包共 152 个文件,约 52.94MB,以 exe 与 jar 构成扫描主程序及 Java 组件,dll、pyd 提供运行依赖,辅以 txt、pdf、xml 等说明与规则文件,另有 bat、ps1、sh 启动脚本,目录结构便于直接部署。该工具支持按需选择或自定义扫描规则,扫描后输出含问题严重程度与修复建议的报告,并可持续更新规则库;lite 版本体量较轻,适合快速验证基础安全隐患。已有 1484 人学习,读者可据此理解 CIS 基准落地方式、掌握配置核查流程,并借助报告定位不合规项、梳理整改思路。
1. 从一台“自查全过”的服务器说起:CIS-CAT 到底扫的什么
上个月帮一个团队做操作系统安全扫描,对方运维拍着胸脯说“基线我们都对过了,没问题”。我拿 CIS-CAT 跑了一遍,Level 1 的评分项里直接冒出七十多条 fail:SSH 还开着密码登录、/etc/shadow权限是 644、core dump 没关、审计服务装了但规则是空的。这些都不是漏洞,扫描器也报不出来,但每一条都是攻击面。CIS-CAT 就是干这个的:它把 CIS Benchmark 那份几百页的配置基线文档,变成可执行的检查脚本,逐条比对你机器上的实际配置,输出 pass / fail / not applicable 和整改建议原文。它属于主机配置合规评估工具(配置基线核查),不是 CVE 漏洞扫描器,这一点先分清,否则拿去和漏扫比覆盖范围只会失望。适合谁:需要给几十上百台机器做一致性基线核查、要出合规证据、要做发布前门禁的运维和安全工程师。
2. 装起来才能谈结论:JDK、benchmark 与 profile 的三件套
CIS-CAT 的坑有一半出在“东西没对齐”上——版本对不上、profile 选错、权限不够,扫描照样能跑完,报告照样是绿的,但结论是假的。所以先把运行环境的三个组成部分拆开看:Java 运行时、benchmark 文件、profile 名称。这三个对了,后面命令怎么写都是次要的。
2.1 运行前置:JDK 与目录结构
CIS-CAT Pro Assessor 本质是一个 Java 应用,外层用Assessor-CLI.sh(Linux)或Assessor-CLI.bat(Windows)包着 jar 启动。所以第一件事不是急着敲扫描命令,而是确认 java 在 PATH 里、版本满足随包说明的要求。我见过最典型的翻车是机器上装着两套 JDK,java -version显示的是 8,但脚本内部调的是另一套 17,启动直接抛UnsupportedClassVersionError。
解压后先别改任何东西,把目录结构看一遍,心里有个数:
# 解压到一个固定路径,别放 /tmp,后面要长期复用 unzip CIS-CAT-Pro-Assessor.zip -d /opt/cis-cat # 进入 Assessor 子目录,CLI 脚本和 benchmarks 都在这一层 cd /opt/cis-cat/Assessor # 给启动脚本执行权限 chmod +x Assessor-CLI.sh # 确认 java 可用,并记下版本 java -version # 先看帮助,不同小版本的参数名会有出入,以这个输出为准 ./Assessor-CLI.sh -h这段命令没做任何扫描,只是把“能不能跑”这件事确认掉。-h的输出建议完整看一遍,因为 CIS-CAT 在各版本之间调整过参数命名,网上抄来的命令直接贴很可能报unrecognized option。目录里几个关键位置记一下:benchmarks/放 XCCDF 格式的基准文件,reports/是默认报告落盘位置,config/下可能有认证描述文件的样例模板。配置文件不要直接改样例,复制一份出来改,升级的时候不会互相覆盖。
提示:不要用 root 直接跑扫描进程,除非你的检查项确实需要读
/etc/shadow这类文件。评估账号给最小权限加定向 sudo,比给一个 root shell 安全得多,报告也更干净。
2.2 Benchmark 与 Profile:别拿错尺子
Benchmark 是“尺子”,Profile 是“尺子上的刻度档位”,两者混了是新手最常见的误解。Benchmark 文件是一个 XCCDF XML,里面写死了针对某个系统某个版本的几百条检查项,文件名通常长这样:CIS_<系统名>_Benchmark_v<版本>-xccdf.xml。Profile 则是这个文件内部的分组,比如Level 1 (Server)、Level 2 (Workstation)这种,决定这次跑哪些项、按什么标准算分。
版本对齐是硬要求。同一个发行版,大版本不同(比如 20.04 和 22.04),检查项、文件路径、默认参数全都变了。拿 20.04 的 benchmark 去扫 22.04 的机器,结果往往是大量not applicable,剩下能跑的项里还有一批因为路径不存在而报error,最后算出来的分数毫无意义。系统小版本升级后,也建议重新拉一次对应版本的 benchmark,这事儿没有后悔药。
| 组件 | 作用 | 拿错之后的典型症状 |
|---|---|---|
| Benchmark 文件 | 定义检查项全集与判定逻辑 | 大面积 not applicable、路径类检查全 error |
| Profile | 决定启用哪些检查项、是否计分 | 分数虚高、原本该查的项根本没进报告 |
| 报告格式 | HTML / CSV 等输出形态 | 想拿数据做趋势却没有 CSV,只能人工抄 |
Profile 的选择要看机器的角色。服务器和工作站的基线本来就不一样,工作站要开桌面相关服务,服务器不需要。给一台生产数据库服务器套上 Workstation 的 profile,你会得到一堆“某项服务未启用”的 fail,然后被 DBA 追着问为什么要动他的机器。所以扫描之前先问清楚这台机器是干什么的,profile 选 Server 侧。
2.3 GUI 与 CLI 的取舍
CIS-CAT 提供图形界面的 Assessor,也提供纯命令行。第一次接触、想快速看看报告长什么样,用 GUI 点几下确实直观;但只要涉及批量、定时、进流水线,就必须走 CLI。GUI 在无头服务器上要么装 X11 转发,要么远程桌面,配一遍环境的时间够你把 CLI 参数背下来了。
我通常的分工是:GUI 只用来给不熟这套工具的人做一次演示,让他理解“一条 fail 对应报告里的哪一段”;真正的日常工作全部用 CLI,报告统一落到一个带日期的目录里。GUI 和 CLI 共用同一个benchmarks/目录,所以在 GUI 里导入过的基准文件,CLI 直接就能引用,不用重复下载。
还有一个容易被忽略的点:CLI 输出到终端的进度信息很啰嗦,几百条检查项逐条打印。第一次跑建议就让它刷,能看到卡在哪一项;稳定之后再加静默参数或者重定向到日志文件,否则定时任务的日志很快就把磁盘塞满。
3. 命令行实战:一条 Assessor-CLI 命令的七个参数怎么填
参数本身不难,难的是每个值从哪来。这一段按“先查名字、再跑单机、最后铺批量”的顺序走,每一步都给能直接抄的命令,跑完你能拿到一份可读的 HTML 报告和一份能进表格的 CSV。
3.1 先定位 benchmark 与 profile 的真实名称
不要凭记忆写文件名。CIS-CAT 自带的-l参数会把当前benchmarks/目录下的所有基准和它们内部的 profile 名字列出来,这是最可靠的信息源:
# 列出所有可用 benchmark 及其 profile ./Assessor-CLI.sh -l # 如果输出太长,按关键字过滤,比如只看某发行版 ./Assessor-CLI.sh -l | grep -i -A3 "linux"输出里会同时给出文件名和 profile 的完整字符串。注意 profile 名字里通常带空格和括号,传到命令里必须整体加引号,否则 shell 会把它拆成好几个参数,CIS-CAT 收到之后报“profile not found”,你还以为是文件坏了。我一般会先把名字复制到一个临时文本里,确认引号包住的是完整字符串,再往命令里贴。
如果-l里根本没有你需要的 benchmark,说明文件没放进去。把下载到的 XCCDF XML 直接丢进benchmarks/目录,不需要注册,也不需要重启,再列一次就出来了。文件名别改,CIS-CAT 有时会从文件名里解析版本信息。
3.2 单机扫描:一条命令生成 HTML 和 CSV
单机本地扫描是日常用得最多的形态。下面这条命令同时出两种格式的报告,并且关闭时间戳后缀:
# 单机本地扫描,同时生成 html 与 csv 两份报告 ./Assessor-CLI.sh \ -b benchmarks/CIS_YourDistro_Benchmark_vX.Y.Z-xccdf.xml \ -p "Level 1 (Server)" \ -r html csv \ -rd /var/reports/cis/$(hostname)-$(date +%Y%m%d) \ -nts逐项说明,因为每个参数填错都会让结果变味:
-b后面跟 benchmark 文件的相对或绝对路径。用相对路径时,当前目录必须是Assessor/,否则找不到文件。我习惯直接写绝对路径,脚本挪位置也不会失效。-p是 profile 名称,完整字符串加双引号。想一次跑多个 profile,可以重复传这个参数,但报告会合在一起,后期拆分比较麻烦,一般不这么干。-r指定报告格式,可以跟多个值。html给人看,csv给程序和表格看,这两个是标配。部分版本还支持其他结构化格式,具体看-h,别照抄网上老版本的写法。-rd是报告输出目录。这里用主机名加日期拼了一个路径,好处是同一台机器多次扫描不会互相覆盖,坏处是目录会越攒越多,需要配清理策略。-nts关闭文件名的时间戳后缀。加了它,报告文件名是固定的,方便脚本按固定路径去读;不加的话每次文件名都不一样,适合人工翻看、怕覆盖的场景。
不加-rd的话,报告默认落在reports/下,同名文件可能被覆盖,做趋势对比时这是灾难。我的习惯是输出目录里必须带主机名和日期,哪怕后面要写脚本去扫这个目录。
扫描过程中如果某条检查项卡住很久,多半是在做文件权限遍历或者服务状态查询。整体耗时从几分钟到二十几分钟都正常,取决于机器性能、检查项数量和是否涉及大目录遍历。别在超时设得很短的定时任务里跑全量扫描。
3.3 远程扫描与批量编排
机器一多,逐台登录就不现实了。CIS-CAT Pro 支持远程目标评估,通过 SSH 连 Linux、通过 WinRM 连 Windows,把检查逻辑推过去跑。远程扫描需要一份认证描述文件,里面写目标地址、账号、密码或密钥路径。不同版本这个参数的叫法不完全一致,一般是用-a指向认证文件,具体以-h输出为准。
先把认证文件复制一份出来改,别动原始模板:
# 复制认证描述文件模板,按目标填写地址与凭据 cp config/sample-authentication.txt config/targets-prod.txt # 编辑,填目标地址、端口、账号、密钥路径或密码 vi config/targets-prod.txt填写时有两个现实约束。第一,目标机的 SSH 必须允许该账号登录,密钥要提前分发好,密码登录在很多加固过的环境里已经被关掉了。第二,部分检查项需要读只有 root 能看的文件,所以这个账号需要配免密 sudo 或者定向的 sudo 规则,否则这些项统一报error,而不是 fail——报告里 error 和 fail 是两回事,后面解读报告时会讲。
批量扫描我一般用外层循环包住单机命令,每台一个独立目录:
#!/usr/bin/env bash # 按目标清单逐台扫描,每台输出独立目录 set -u BENCH="benchmarks/CIS_YourDistro_Benchmark_vX.Y.Z-xccdf.xml" PROFILE="Level 1 (Server)" OUTBASE="/var/reports/cis" DAY=$(date +%Y%m%d) while read -r host; do [ -z "$host" ] && continue # 跳过注释行 case "$host" in \#*) continue ;; esac echo "[*] scanning $host" ./Assessor-CLI.sh \ -b "$BENCH" \ -p "$PROFILE" \ -a config/targets-prod.txt \ -r html csv \ -rd "$OUTBASE/$host-$DAY" \ -nts done < targets.txt这里targets.txt是一行一个主机名的清单,注释行用#开头。循环里没有做并发,因为远程扫描本身对目标机有负载,几十台一起压过去容易把目标机的 SSH 连接数打满,反而制造故障。真要提速,把清单切成几份,用xargs -P控制并发数在 3 到 5 之间,别更高。
失败的处理也要留一手:某台机器连不上,脚本继续往下跑,但要在日志里记下主机名,否则第二天你只知道“有一台没报告”,不知道是哪台。简单做法是把每次调用的退出码写进一个汇总文件,跑完之后统一看。
4. 报告拆解:把 200 条 fail 压缩成 20 条待办
第一次打开 CIS-CAT 的 HTML 报告,大部分人的反应是“怎么这么多”。两三百条检查项,一半 fail,直接照着干会做不完。报告的价值不在于 fail 的数量,而在于它给了每条项的判定依据、实际取值和整改原文,让讨论从“我觉得这样更安全”变成“标准要求是这样,当前值是那样”。
4.1 报告里到底有哪些字段
HTML 报告的结构通常是:顶部一个汇总区,给出总分、各状态计数、按 Level 分组的结果;下面按检查项逐条展开。每条包含几个关键信息:状态、是否计分、CIS Controls 映射、检查描述、当前实际值、整改建议。
状态字段是解读的核心,含义和处理方式差别很大:
| 状态 | 含义 | 处理动作 |
|---|---|---|
| pass | 实际配置符合基线要求 | 记录,纳入复扫确认 |
| fail | 实际配置与要求不符 | 进入待办,按优先级排期 |
| error | 检查未能完成,通常是权限或路径问题 | 先修扫描环境,不能当通过 |
| not applicable | 该项在当前系统上不适用 | 抽查几条确认是真不适用 |
| not checked | 未执行,可能被 profile 排除 | 确认是有意排除还是漏配 |
最危险的是把error当成 pass。某次一台机器上报了三十多条 error,运维扫了一眼说“没红色告警”,实际上是因为扫描账号没有 sudo,所有需要读受保护文件的检查项全部没法执行。这种情况下分数反而好看,但基线根本没验证过。
4.2 按什么顺序修
我的排序原则是三条:先修计分项里 Level 1 的,再修影响面大的,最后处理需要停机变更的。计分项和不计分项在报告里通常有标识,不计分项(Not Scored)本身不可自动判定,只能作为人工核查的参考,把它们混进 KPI 里会误导决策。
影响面怎么判断?看这条项被映射到了哪些 CIS Controls。一条同时关联多个控制域的检查项,改动收益通常更高。比如 SSH 相关的加固项,往往同时关联访问控制、边界防护、审计几块,优先做。
还有一个实用技巧:把同一类 fail 合并成一次变更。所有跟 SSH 配置相关的 fail 一次性改完、重启一次服务,比逐条改、反复重启稳妥得多。CIS-CAT 报告的整改建议里通常直接给出了配置片段和文件路径,照着改之前先在测试机上验证,尤其是涉及sshd_config和内核参数的部分,改错了会把自己锁在外面。
4.3 用 CSV 做跨版本对比
HTML 适合给人看,CSV 适合做趋势。每次扫描出的 CSV 里,每行是一条检查项,带状态、实际值、期望值这些列。想回答“加固之后到底好了多少”,最直接的办法是拿两次的 CSV 做 diff:
import csv, sys def load(path): # 以检查项编号为键,读取状态 d = {} with open(path, newline='', encoding='utf-8') as f: for row in csv.DictReader(f): key = row.get('Rule ID') or row.get('ID') or row.get('rule_id') if key: d[key] = row.get('Status', '').strip().lower() return d before, after = load(sys.argv[1]), load(sys.argv[2]) fixed = [k for k in before if before[k] == 'fail' and after.get(k) == 'pass'] broke = [k for k in before if before[k] == 'pass' and after.get(k) == 'fail'] print(f"修复 {len(fixed)} 项,回退 {len(broke)} 项") for k in fixed[:20]: print(" 已修复:", k) for k in broke: print(" 回退:", k)列的字段名在不同版本里可能是Rule ID、ID或带下划线的写法,所以上面用or做了兼容。这段脚本的作用是把“加固有没有引入新问题”这件事变成可查的:broke列表比总分更重要,一次加固之后总分涨了但改坏了三条,那三条往往就是后面故障的根源。
注意:两张 CSV 必须来自同一个 benchmark 和同一个 profile,否则规则集合都不一样,diff 出来的差异是假的。做对比之前先核对文件名里的版本号。
5. 避坑清单:五类让扫描结果失真的现场问题
这套工具本身逻辑不复杂,出问题基本都出在周围。下面五条是我在不同环境里反复遇到的,每条按“现象、原因、解决”写,遇到对得上的直接照做。
5.1 结果层面的失真
现象一:报告里大半是not applicable,只剩零星几条 pass。原因几乎总是 benchmark 版本与目标系统版本不匹配,检查项的路径和判定条件对不上,工具只能跳过。解决方式是把目标系统的准确版本号确认清楚,重新取对应版本的 benchmark 文件放进去,再跑一次-l确认它是新加的那个文件,然后重扫。别偷懒用“最接近的版本”,差一个大版本结论就不可信。
现象二:总分很高,但业务方反馈机器配置很松。原因通常是 profile 选错,或者只跑了 Level 1 里的一小部分。Level 1 是基础要求,Level 2 才涉及更严格的内核参数和访问控制。给对外暴露的机器只跑 Level 1,评分好看不代表足够。解决方式是按资产分级定 profile:面向外网、处理敏感数据的机器跑更严格的档位,内网测试机跑基础档,报告里标注清楚各自用的哪档,别混在一起算总账。
现象三:远程扫描一批机器,返回的 fail 项在人工登录后复查看是符合要求的。原因多半是远程执行环境和本地交互式登录的环境不同,比如某条项检查的是登录后的 shell 限制,远程非交互会话下取到的值不一样。解决方式是抽样复核,从 fail 列表里挑出跨机器的共同项,挑两三台人工核对;如果确认是环境差异,在报告里单独标注,不要直接下发整改,否则改出来的配置可能把正常运维流程卡死。
5.2 运行环境与权限层面的问题
现象四:报告里error数量异常多,且集中在需要读受保护文件的检查项上。原因就是权限不足。扫描账号没有 sudo,工具读不到/etc/shadow、审计规则、部分服务配置,这些项全部记为 error。解决方式是给扫描账号配定向免密 sudo,只放开需要读的路径和命令,不要图省事直接给 ALL。配完之后先单独跑一台验证 error 数量是否下降,再铺开批量。
现象五:批量扫描中途大面积超时或者连接被拒。原因是并发太高,或者目标机 SSH 的最大会话数有限制。解决方式是把并发压到 3 以内,远程扫描本身耗时主要在连接建立和文件遍历上,并发收益没有想象中大;同时在脚本里给每个主机之间加几秒间隔,避免连接风暴。另外确认目标机的连接数限制,加固过的环境经常把MaxStartups调得很低,这一点在扫描前问一句能省掉半天排查。
6. 进阶:把一次性扫描变成基线门禁
扫描一次出一份报告,本质上还是“事后检查”。真正省事的是把它塞进发布流程:新机器上线前、配置变更后自动跑一遍,不达标就卡住,不让它进生产。这件事用 CIS-CAT 的 CLI 加退出码判断就能做到,不需要额外平台。
关键是把报告里的分数或 fail 数量抽出来做阈值判断。HTML 不好解析,所以门禁必须基于 CSV:
#!/usr/bin/env bash # 门禁脚本:跑一次扫描,fail 数超过阈值就返回非零 set -u BENCH="benchmarks/CIS_YourDistro_Benchmark_vX.Y.Z-xccdf.xml" PROFILE="Level 1 (Server)" OUT="/var/reports/gate/$(hostname)-$(date +%Y%m%d%H%M)" THRESHOLD=15 mkdir -p "$OUT" ./Assessor-CLI.sh -b "$BENCH" -p "$PROFILE" -r csv -rd "$OUT" -nts || exit 2 # CSV 里统计 fail 行数,字段名按你的版本调整 FAILS=$(awk -F',' 'NR>1 && tolower($0) ~ /,fail,/ {c++} END{print c+0}' "$OUT"/*.csv) echo "fail 项数量: $FAILS (阈值 $THRESHOLD)" if [ "$FAILS" -gt "$THRESHOLD" ]; then echo "基线不达标,阻断发布"; exit 1 fi echo "基线通过"; exit 0THRESHOLD不要一上来就设成 0。存量机器总有历史遗留项,阈值设成 0 的结果是所有人都去绕过门禁。我一般先用一周的扫描数据算出当前 fail 数的中位数,把阈值定在中位数略低的位置,每周往下压一点,让团队有节奏地收敛,而不是一次性卡死。
几个参数和判断点的取舍值得说清楚。报告目录用分钟级时间戳,门禁场景下同一台机器一天可能跑好几次,日期粒度不够会互相覆盖。退出码分三级:0 通过、1 不达标、2 扫描本身失败。第三种最容易被忽略,扫描失败和不达标必须区分开,否则工具坏了没人发现,门禁形同虚设。
| 场景 | 建议 profile | 建议阈值策略 | 报告留存 |
|---|---|---|---|
| 上线前门禁 | Level 1 (Server) | 中位数下压,逐周收紧 | 保留最近 30 天 |
| 月度巡检 | Level 1 + Level 2 | 按资产分级设不同阈值 | 保留 12 个月 |
| 变更后复扫 | 与变更前一致 | 与前一次结果 diff | 与变更单关联归档 |
还有一件小事值得单独提:扫描本身会消耗目标机资源,门禁如果挂在发布流水线里,要注意别和业务高峰撞上,也别在一次发布里对同一台机器重复扫三遍。我见过流水线里三个阶段各调了一次扫描,单次二十分钟,直接把发布窗口撑爆。
从那以后我每次接基线核查的活,都强制先跑一遍-l确认 benchmark 和 profile 的真实名称,再拿一台机器做全量试扫,把 error 数量和权限问题清干净了才铺批量。这个习惯救过我两次:一次是版本对不上导致报告全绿,一次是扫描账号没权限导致 error 被当成通过。希望帮到你。
本文还有配套的精品资源,点击获取