stat 命令仅输出文件权限、属主、属组等实际值,无法自动比对安全基线;真正自动化核验需结合期望值(如 /etc/passwd: 644 root root、/etc/shadow: 600 root root)进行逻辑判断,并补充存在性、符号链接、selinux上下文及特殊权限位检查。

直接用 stat -C "%a %U %G" 检查 /etc/passwd 等文件权限,只能看到当前权限和属主属组,但**无法自动判断是否合规**——它不带规则比对能力。真正实现自动化基线核对,需要把“期望值”和“实际值”做逻辑比对,不能只靠 stat 输出完事。
四大文件的标准权限与属主属组要求
先明确合规基线(主流发行版如 RHEL/CentOS/Ubuntu/TencentOS 的通用安全要求):
-
/etc/passwd:权限
644,属主root,属组root -
/etc/group:权限
644,属主root,属组root -
/etc/shadow:权限
600,属主root,属组root(极敏感,仅 root 可读写) -
/etc/sudoers:权限
440,属主root,属组root(部分系统接受644,但440更稳妥)
用 stat + shell 判断实现自动化核对
单条命令无法完成“检查+判断+反馈”,需组合脚本逻辑。例如校验 /etc/passwd:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
file="/etc/passwd"; expected_mode="644"; expected_user="root"; expected_group="root" read mode user group /dev/null) if [[ "$mode" == "$expected_mode" && "$user" == "$expected_user" && "$group" == "$expected_group" ]]; then echo "✅ $file: 权限合规" else echo "❌ $file: 实际($mode $user $group) ≠ 期望($expected_mode $expected_user $expected_group)" fi
把四次校验封装成循环,就能批量执行:
files=("/etc/passwd" "/etc/group" "/etc/shadow" "/etc/sudoers")
rules=([/etc/passwd]="644 root root" [/etc/group]="644 root root" [/etc/shadow]="600 root root" [/etc/sudoers]="440 root root")
for f in "${files[@]}"; do
[[ -f "$f" ]] || { echo "⚠️ $f 不存在"; continue; }
read act_mode act_user act_group /dev/null)
read exp_mode exp_user exp_group
<h3>为什么不能只依赖 stat 输出?</h3>
<p>因为:</p>
-
stat -c "%a %U %G"不验证文件是否存在、是否被篡改、是否为符号链接(比如 /etc/shadow 被软链到 /tmp/ 是严重风险) - 它不检查 SELinux 上下文(如
system_u:object_r:shadow_t:s0),而某些等保或 CIS 基线明确要求 - 无法识别特殊权限位(如 setuid/setgid),而
/etc/sudoers绝对不能有这些位 - 不处理多组策略场景(例如某些环境要求 /etc/group 属组为
bin或sys,而非 root)
生产环境建议增强点
真正用于基线巡检时,应补充:
- 加
ls -ld "$f"辅助确认是否为符号链接或硬链接 - 用
getfattr -n security.selinux "$f" 2>/dev/null | grep -q 'shadow_t'验证 SELinux 类型(如启用) - 对
/etc/shadow额外运行sudo awk -F: '($2=="" || $2 ~ /^[!*]$/){print $1 " 密码为空或锁定"}' /etc/shadow检查空口令/禁用账号 - 将结果输出为 JSON 或 CSV,便于接入 CMDB 或 SIEM 系统










