如何使用 vps-audit 审计 Linux VPS—以及如何正确读取结果
快速 VPS 审计是一个起点,而不是最终判决
您的网站加载并且 SSH 响应,但这不会显示待处理的更新、宽松的 SSH 设置或意外的监听器。首次审计会浮现这些问题。
vps-audit 是一个针对 Debian 和 Ubuntu 的 Bash 清单,它将本地配置、维护、监听器和资源信号转换为彩色编码的报告。就像车辆仪表板一样,它指出需要检查的区域,而不诊断每个原因。
本指南安全地运行固定的 vps-audit v0.2.0,使用本机工具检查重要结果,并将其转化为优先事项。该示例使用一个运行 Ubuntu 24.04 LTS 的 AlexHost Ubuntu VPS。其他提供商的镜像可能有所不同,非托管的客户操作系统仍然是操作员的责任。

vps-audit 检查的内容——及其无法证明的内容
vps-audit 检查本地指标,但不会详尽检查任何区域。此表显示每个结果能——和不能——告诉您什么。
| 域 | 脚本提出的问题 | 结果无法证明的内容 |
|---|---|---|
| 🔐 远程访问 | 解析的 SSH 设置、Fail2ban/CrowdSec 状态、jail-port 对齐和失败身份验证计数是否与其规则匹配? | 每个身份验证路径都得到加固或尝试代表违规。 |
| 🌐 网络暴露 | 脚本可以检测到什么主机防火墙前端和本地监听端口? | 通过每个防火墙和 NAT 层从互联网可以访问哪些服务。 |
| 🔄 维护 | 是否有待处理的重启,缓存的包数据是否显示升级,以及是否安装了 unattended-upgrades? | 是否安装了每个安全更新或自动更新是否成功运行。 |
| 🛡️ 权限和策略 | 它是否找到专用的 sudo 日志文件、一个密码长度值和异常 SUID 文件? | 权限控制是否完整或 SUID 文件是否恶意。 |
| 📊 操作快照 | 运行多少个服务,磁盘、内存、CPU、负载、OS、内核和正常运行时间现在看起来如何? | 长期容量、可用性或性能趋势。 |
SUID 允许程序以文件所有者的有效权限运行。合法系统程序使用它,因此请调查意外的 SUID 文件,而不是删除它。Fail2ban 和 CrowdSec 可以阻止恶意流量,但仅安装或活跃状态不能证明它们保护预期的服务。
脚本对资源使用、服务、失败登录和监听器应用通用阈值。这些不是工作负载感知的风险评分;不同的 VPS 角色可能因不同原因达到相同的颜色。
该工具不检查恶意软件、已知漏洞、应用程序、容器、提供商防火墙、合规性或趋势。虽然其 README 提到”活跃互联网连接”,但 v0.2.0 仅获取公共 IP 并清点本地监听器。因为它需要特权可见性,请首先控制哪个文件接收 sudo 访问。
在给下载的脚本授予 sudo 权限之前
此 Debian/Ubuntu 工作流需要 SSH 访问、sudo 和下面使用的标准工具。在一个临时目录中工作。如果缺少某个工具,请停止而不是通过安装它来改变基线。
该示例使用 vps-audit v0.2.0,发布于 2026 年 8 月 10 日,在 2026 年 9 月 8 日检查时仍为最新版本。
其标签指向提交 57c323d46b48026740f0b35b9bad6cd6127c757b。固定版本可避免来自可变 main 的后续更改。
创建一个专用目录并通过 HTTPS 下载该精确标记的脚本:
mkdir -p "$HOME/vps-audit-test"
cd "$HOME/vps-audit-test"
curl -fL --proto '=https' --tlsv1.2
-o vps-audit.sh
https://raw.githubusercontent.com/nuver-labs/vps-audit/v0.2.0/vps-audit.sh

这会在新目录中保存 vps-audit.sh。-f 选项在 HTTP 错误时失败,而 -L 跟随重定向。
接下来,记录本地 SHA-256 指纹并显示与此演练相关的设置:
sha256sum vps-audit.sh
grep -nE '^(VPS_AUDIT_VERSION|RESOURCE_(WARN|FAIL)|SERVICES_(WARN|FAIL)|LOGINS_(WARN|FAIL)|OPEN_PORTS_(WARN|FAIL)|PASSWORD_MINLEN|DEFAULT_REPORT_DIR|ENABLE_CHOWN)=|api.ipify.org' vps-audit.sh

输出对文件进行指纹识别,并显示其报告路径、阈值和对 api.ipify.org 的请求。完整标记源代码还读取本地状态、模拟 apt-get -s upgrade 并递归搜索 SUID 文件。它不是只读的:它写入报告、可能创建其目录并联系外部服务。如果您能读懂 shell 代码,在授予提升的权限之前请审查源代码。
资源阈值为 WARN 50% 和 FAIL 80%。运行的服务使用 20/40,失败的登录 10/50,监听器名义上 10/20,密码长度 12。限制部分解释了为什么监听器状态不遵循这些变量。
⚠️ 警告:固定、哈希、目标检查和语法检查改进了可重现性,但不能建立信任。提交未签名,发布版本不提供校验和或签名资产。
将哈希与审计说明一起保存。在运行之前,将其与文件进行比较。匹配表示副本包含相同的字节。差异可能来自另一个发布版本、更改的下载或本地编辑。记录标签和哈希将每个报告链接到生成它的脚本。
最后,解析文件而不运行其正常命令,然后仅在解析成功时添加执行权限:
bash -n vps-audit.sh
&& chmod +x vps-audit.sh
&& printf 'Syntax check: PASS; execute permission addedn'

这仅确认 Bash 可以解析该文件并且已添加执行权限。固定脚本现已准备好进行一次不变的运行。
运行 vps-audit 并定位报告
该脚本打印系统详情和彩色状态,然后写入纯文本报告。其递归 SUID 搜索使运行时间可变,因此需要测量。
运行固定文件一次并保留 shell 进程的退出状态:
printf 'Audit started: '
date -u '+%Y-%m-%d %H:%M:%S UTC'
TIMEFORMAT=$'Elapsed real: %3R secondsnUser CPU: %3U secondsnSystem CPU: %3S seconds'
time sudo ./vps-audit.sh
AUDIT_STATUS=$?
printf 'Audit exit status: %sn' "$AUDIT_STATUS"
在测试的 VPS 上,审计在 2026 年 9 月 14 日 UTC 13:12:10 开始,在 58.412 秒内完成。它返回 0 并保存了 ./vps-audit-report-20260914_131210.txt。


Elapsed real 是挂钟时间;user 和 system 值测量 CPU 时间。退出状态 0 表示进程完成,不表示每项检查都通过。v0.2.0 即使有 FAIL 结果也返回 0。
选择新报告,检查其元数据,并提取计数和示例,而不完整显示敏感文件。
REPORT=$(ls -1t ./vps-audit-report-*.txt 2>/dev/null | head -n 1)
if [ -z "$REPORT" ]; then
printf 'No vps-audit report found in the current directory.n' >&2
exit 1
fi
printf 'Report selected: %sn' "$REPORT"
sudo stat --format='Owner: %U:%G | Mode: %A (%a) | Size: %s bytes | Modified: %y' "$REPORT"
for status in PASS WARN FAIL; do
count=$(sudo grep -c "^\[$status\]" "$REPORT" || true)
printf '%s: %sn' "$status" "$count"
done
sudo grep -E '^[(PASS|WARN|FAIL)] (Running Services|Disk Usage|Password Policy)' "$REPORT"

报告的 13:13:08 UTC 修改时间与运行时间相符。它包含 17 个结果:6 个 PASS、3 个 WARN 和 8 个 FAIL。这些是分类,不是安全评分。
状态总数在比较同一版本的多次运行时很有用,但始终要检查变化背后的行。较低的 FAIL 计数可能来自不同的输入或解析器行为,而不是改进。不变的总数也可能隐藏了一个已解决的问题和一个新问题。
2,665 字节的报告属于 root:root,模式为 644(-rw-r--r--),这是使用 sudo 和默认 ENABLE_CHOWN=false 的预期结果。如果目录权限允许到达该文件,组用户和其他用户可以读取该模式。仅 root 所有权不会使其私密。
❗ 重要:报告包含主机名、公共 IP、系统详情和发现。保持其私密性,在分享前删除标识符、提示和敏感服务信息。
如果将来的运行缺少某个状态,请记录该缺失,而不是重新配置 VPS 来制造一个颜色。
如何阅读 PASS、WARN 和 FAIL 而不过度反应
仪表板标签报告每个测试如何与 v0.2.0 的规则匹配:
| 标签 | 正确的阅读 | 它不能证明的 |
|---|---|---|
| PASS | 观察到的值与此规则的期望相匹配。 | 该服务或 VPS 是安全的。 |
| WARN | 该值超过了审查阈值或产生了上下文信号。 | 存在漏洞。 |
| FAIL | 该规则发现与其内置期望的更强不匹配。 | 发生了入侵或立即更改是正确的。 |
将观察与建议分开。在”22 个服务运行”中,计数是观察;”减少攻击面”是基于通用阈值的建议。确认计数、识别服务,然后决定该建议是否适合服务器。
对每个结果提出三个问题:该值准确吗?它是有意的吗?实际影响是什么?本机命令检查该值;工作负载上下文决定其余部分。

SSH 端口 WARN 是基于策略的:v0.2.0 标记端口 22。移动 SSH 可能会减少自动化噪声,但不能替代强身份验证或访问控制。端口 22 上的已知服务可能不如未知通配符侦听器重要。
对于 FAIL,在提出修复之前检查规则。根登录测试仅接受 PermitRootLogin no,因此不同的 prohibit-password 设置仍然失败。在采取行动之前直接检查 OpenSSH。
PASS 也需要上下文。对于 unattended-upgrades,脚本仅确认该包存在——而不是其配置或运行历史。
使用本机命令验证高影响力发现
使用只读本机命令检查 SSH 访问、主机过滤和本地侦听器。首先,询问 OpenSSH 在默认值和包含的配置合并后实际解析的内容:
sudo sshd -T
| grep -E '^(port|listenaddress|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication) '

Ubuntu 在其主配置的开始附近加载 /etc/ssh/sshd_config.d/*.conf。sshd -T 解析合并的设置,使其比 grep 单个文件更强有力的证据。
OpenSSH 在通配符 IPv4 和 IPv6 地址上解析了端口 22。它还返回了 permitrootlogin yes、passwordauthentication yes、pubkeyauthentication yes 和 kbdinteractiveauthentication no。解析的配置确认了脚本的 root 登录和密码身份验证发现,尽管帐户状态、PAM 和 Match 规则仍可能影响特定登录。
其次,询问 UFW 本身报告的状态和托管策略:
sudo ufw status verbose

Ubuntu 文档将 UFW 记录为其默认防火墙前端。这里它处于活跃状态,具有低级日志记录和传入和路由流量的默认拒绝策略。规则允许入站端口 22、80、443 和 37985 通过 IPv4 和 IPv6。这确认了 UFW 的状态,而不是每条规则是否合适。
第三,清点本地 TCP 和 UDP 侦听器、绑定地址和拥有进程:
sudo ss -lntup

这些选项选择数字 TCP 和 UDP 侦听器并请求进程详细信息。端口 53、62789、8404 和 11111 仅限环回;端口 22、80、2096、5678 和 37985 使用通配符地址。没有显示进程详细信息,因此其所有者和用途仍然未知。
process listener
→ bind address / interface
→ host firewall
→ provider-edge firewall or NAT
→ external network path
端口 22、80 和 37985 具有通配符侦听器和 UFW 允许规则。UFW 允许 443 而没有侦听器,而 2096 和 5678 具有侦听器但没有显示的允许规则。
防火墙规则和侦听器回答不同的问题。规则允许流量(如果有服务接受它);侦听器显示等待的服务,但不显示网络流量是否可以到达它。一起读取两者可以缩小调查范围,而不声称外部暴露。
📝 注意:ss 显示本地绑定状态,UFW 显示一个主机防火墙。两者都不能证明跨提供商防火墙或 NAT 的 Internet 可达性;这需要从另一个系统进行授权测试。
v0.2.0 尽管如此,在丢弃绑定地址后,将相同列表标记为”总计”和”公共”,尽管九个 TCP 端口中有四个仅限环回。其 LISTEN 过滤器也会遗漏标记为 UNCONN 的 UDP 行。将此结果读作本地 TCP 端口计数,而不是公共暴露。
将验证的发现转化为实际行动队列
按置信度、暴露程度、影响和意图设置优先级。优先级 1 涵盖需要采取行动的已确认弱点。优先级 2 涵盖仍需调查的重要发现,而优先级 3 涵盖低风险或策略驱动的项目。如果设置是有意的,请记录原因、任何补偿控制和审查时间。
该表将该方法应用于此运行;不完整的证据使优先级保持暂定状态:
| 发现 | 已知内容 | 优先级 | 后续步骤 |
|---|---|---|---|
| Root 登录和 SSH 密码身份验证已启用 | 由 sshd -T 确认 | 优先级 1(除非明确要求) | 遵循单独的 SSH 加固程序,具有经过测试的恢复访问。 |
| 端口 37985 可能可访问 | 通配符侦听器和 UFW 规则;所有者和外部路径未知 | 优先级 2;如果无意且可访问则为优先级 1 | 识别服务并检查提供商控制和外部可访问性。 |
| 端口 2096 和 5678 无法解释 | 通配符侦听器;没有显示的 UFW 规则或进程详情 | 优先级 2,直到识别为止 | 将每个套接字映射到其服务、所有者、目的和依赖项。 |
| 报告了 16,051 次失败登录 | 日志源、时间段和模式未验证 | 优先级 2;如有泄露证据则升级 | 单独审查存储的身份验证日志。 |
| 报告了 12 次升级和 1 次重启 | 安全相关性未验证 | 优先级 1–2(基于暴露程度和影响) | 审查包元数据并规划应用程序感知的维护窗口。 |
| Sudo 日志记录和密码策略失败 | 实际日志记录和身份验证策略未验证 | 优先级 3,除非更强的证据提高风险 | 检查实际配置并记录任何有意的例外。 |

优先级 2 并不意味着无害;证据仍然不完整。为每个未解决的项目分配所有者和截止日期。如果验证确认暴露或弱点,则升级它。如果它是有意的且受控的,请清楚地记录该决定。
报告标签不设置顺序:验证和背景信息才是。
⚠️ 警告:不要从此命令序列更改 SSH 身份验证或远程防火墙规则。错误可能会将您锁定。在进行修复之前,请确认经过测试的密钥访问并验证新配置。保持第二个会话打开并确保控制台或恢复访问有效。
将每个修复作为单独的工作流处理。在停止服务之前映射依赖项,在计划更新之前对其进行分类,并在更改 SUID 权限之前验证所有权和校验和。
vps-audit 的视图停止位置
vps-audit v0.2.0 是一个时间点 Bash 检查清单。它无法建立外部暴露、检测漏洞或恶意软件、检查工作负载、分析存储的日志或提供持续监控。它不是渗透测试或 CIS Benchmark 评估。

该代码添加了重要的警告。
- 端口状态在解析的 TCP 端口少于三个时为 PASS,三个或四个时为 WARN,五个或更多时为 FAIL——尽管名义上有 10/20 变量。
- 一个 unattended-upgrades PASS 仅检查包本身,不检查其配置、计时器或运行历史。
- 更新测试使用 apt-get -s upgrade 的缓存元数据,然后将列出的每个包都称为”安全更新”。
sudo 日志记录测试仅读取 /etc/sudoers,遗漏了 /etc/sudoers.d/ 和正常的日志或 syslog 记录。Issue #33 在 2026 年 9 月 8 日检查时处于开放状态,记录了 Ubuntu 20.04 和 24.04 上的此误报 FAIL。解析也可能因非英文输出而失败,如开放的 issue #37 所跟踪的那样。尽管其 README 措辞如此,此版本不列出已建立的连接。
在需要时扩大审查范围。可疑行为需要进行存储日志和工作负载分析。对于重要的 VPS,请确认测试的备份并考虑授权的外部测试。关键或受监管的系统可能需要 Lynis、Ubuntu 24.04 CIS Benchmark 或专业审查。
底线:验证、优先级排序和重新检查

保持原始报告私密,并维护一份编辑过的副本。记录脚本的 SHA-256、标签和提交,以及运行时间、预期服务、验证结果和操作队列。
- 在更改服务器之前,使用本地命令验证高影响力的发现。
- 安全地修复已确认的高风险问题,调查未知问题,并记录有意的例外。
- 在更改后或按计划重新运行相同的固定版本,然后手动比较报告。
比较报告时,重点关注身份验证更改、防火墙规则、监听器和已解决的发现。时间戳和资源读数会变化。记录有意的更改,以便下一位审查者理解为什么结果不同。
vps-audit 没有基线数据库、调度程序、趋势分析或比较引擎。它的价值来自于一个可重复的习惯:运行、验证、优先级排序和重新检查。
