puppet 用 file、package、user 资源可覆盖基础合规,但需显式声明 mode/owner/group、锁定 package 来源、慎用 managehome;audit 模式比 enforce 更适合审计留痕;报告需对比 baseline 而非仅看执行结果;运行时行为、进程状态、内核参数生效等需外部补位。

怎么用 Puppet 检查用户、软件包、文件权限是否合规
直接用 file、package、user 这三个核心资源类型就能覆盖大多数基础架构合规项。关键不是“能不能定义”,而是“怎么让定义本身变成可验证的约束”。
常见错误是把 Puppet 当成一次性配置工具——比如只写 ensure => present,却不加 validate_cmd 或 audit => true,结果配置跑通了,但实际没做合规校验。
-
file资源必须显式声明mode、owner、group,否则默认值依赖系统,不同发行版行为不一致(比如 Ubuntu 的/etc/shadow默认 mode 是0640,RHEL 是0600) -
package用ensure => 'installed'不够,要配合source或provider锁定来源,避免被本地 repo 替换为非标版本 -
user资源里managehome => true很危险:如果 home 目录已存在且权限混乱,Puppet 不会自动修复,反而可能跳过后续属性设置
为什么 audit 模式比 enforce 更适合合规审计
合规不是“改完就完”,而是“改完还能持续证明没被绕过”。audit 模式让 Puppet 只报告偏差,不自动修正,这对审计留痕和变更审批流程更友好。
典型场景:安全团队要求每月出具 /etc/passwd 所有 UID audit => 'content' 配合自定义 fact 比硬编码 user { 'root': ... } 更可靠。
- 启用
audit需在资源里加audit => ['mode', 'owner'],同时 agent 端配置report = true和reports = store - audit 不触发修改,所以不会因权限问题失败;enforce 模式下若
file { '/etc/ssh/sshd_config': ... }被 chmod 777,Puppet 会反复尝试修复,可能掩盖真实配置漂移原因 - audit 日志默认只存 24 小时,长期留存需配
rrdgraph或导出到外部 SIEM,别指望 PuppetDB 自动归档半年数据
如何让 Puppet 报告真正反映“合规状态”而不是“执行结果”
默认 report 里 status 是 changed/failed,但这对合规没意义——你关心的是“当前是否符合策略”,不是“这次有没有改东西”。得靠自定义 report processor 或 post-run 检查。
最轻量做法:用 puppet resource 导出当前状态,再用 diff 对比 baseline。比如生成标准 /etc/hosts 模板后,运行 puppet resource file /etc/hosts --render-as json 提取 mode/owner/content,再脚本比对。
- 别信
puppet agent --test --noop的输出:它模拟的是“如果运行会怎样”,但不保证实际环境能拿到同样 catalog(比如 conditional logic 依赖 fact 值,而 noop 下 fact 可能被缓存) - 敏感路径如
/etc/cron.d/下的文件,Puppet 默认不递归 audit,必须显式用file_line或自定义 type 处理每行内容,否则漏掉注释里的后门命令 - report 中的
corrective_change字段只在 7.0+ 版本可用,老版本得靠last_run_report.yaml解析,字段名是resource_statuses不是resources
哪些合规项 Puppet 天然不擅长,得绕开或补位
Puppet 擅长静态声明,但对运行时行为、进程级控制、内核参数动态生效等,要么支持弱,要么代价高。
比如“禁止 root SSH 登录”看似只需改 /etc/ssh/sshd_config,但实际要确认 sshd 进程已重载配置、监听端口未被其他服务劫持、且 SELinux context 正确——这些 Puppet 做不了闭环验证。
-
sysctl资源只能写/etc/sysctl.conf,但 kernel 参数是否生效得靠exec { 'check-kernel-param': command => '/sbin/sysctl net.ipv4.ip_forward' }配合logoutput => on_failure - 检测开放端口不能只靠
package { 'firewalld': ensure => installed },得用exec调ss -tlnp并解析输出,注意 CentOS 7 默认用firewalld,Ubuntu 20.04 默认用ufw,命令不兼容 - 密码策略(如最小长度、历史记录)依赖 PAM 模块,Puppet 只能改
/etc/pam.d/common-password,但无法验证pam_pwquality.so是否真在链中生效,得额外跑passwd -S测试
合规不是堆砌资源声明,而是清楚知道哪部分 Puppet 能兜底,哪部分必须靠外部扫描或人工复核。尤其当审计项涉及“是否正在运行”“是否被篡改”“是否响应请求”时,Puppet 的角色只是配置快照,不是运行时探针。











