防火墙策略审计
策略是防火墙唯一「说了算」的东西,但长期运营后必然膨胀出 any-any、冗余、遮蔽、失效规则。本技能给出从策略导出、遮蔽检测、过宽收敛、失效清理到合规对照、变更回退的完整审计链路,并用脚本自动找出「被遮蔽、永远命不中」的规则。
一、核心原理
防火墙按自上而下的顺序匹配规则:包到达后从第 1 条开始找,命中即停止。这个「顺序敏感」特性带来两类典型问题:
- 遮蔽(Shadow):某规则被它前面一条范围更宽的规则完全覆盖,导致它永远不可能被命中——等于「死规则」,既占资源又制造审计噪音。
- 冗余(Redundancy):两条规则范围相同、动作相同,后者多余。
flowchart TD
A[数据包到达] --> B{按顺序匹配规则1..N}
B -->|命中 rule i| C[执行 rule i 动作<br/>permit/deny]
B -->|遍历到末尾| D[默认 deny / 隐式 deny]
C --> E[更新命中计数 hit count]
D --> E
E --> F{hit count == 0?}
F -->|长期为零| G[失效规则, 复核下线]
- 默认拒绝:策略集末尾必须是
deny any(或设备隐式 deny),否则未匹配流量会被放行。 - 命中计数(hit count):长期为 0 的规则要么是遮蔽死规则,要么是失效业务,都要复核。
二、审计工作流(参考架构)
flowchart TB
EXP[1. 导出策略清单<br/>含顺序/五元组/动作/命中计数] --> ANAL[2. 遮蔽与冗余分析<br/>policy_shadow_analyzer.py]
ANAL --> REV[3. 逐条复核<br/>any-any/大网段/全端口]
REV --> CHG[4. 收敛变更<br/>删冗余/收紧范围/关失效]
CHG --> VER[5. 回归验证<br/>业务连通性]
VER --> BACK[6. 备份与回退预案]
配套 ASCII 流程(文档用):
策略集(顺序敏感)
rule 1 permit any -> web 443 [hit=1200000]
rule 2 permit 10.0.0.0/8 -> web 443 [hit=0] <-- 被 rule1 遮蔽
rule 3 permit any any [hit=8000] <-- any-any 过宽
...
rule N deny any any [兜底]
三、关键参数 / 决策表
| 审计项 | 判定阈值 / 标准 | 依据 | 常见错误 |
|---|---|---|---|
| 默认拒绝 | 末尾必须 deny any(或确认隐式 deny) | 最小权限兜底 | 误信「设备默认就拒绝」而不验证 |
| 遮蔽规则 | 被更早更宽规则完全覆盖,hit=0 | 顺序匹配语义 | 只看内容不看顺序 |
| 冗余规则 | 五元组+动作完全一致 | 去重 | 只删一条导致另一条误删 |
| any-any permit | 一律要求说明业务理由 | 高危过宽 | 图省事留 any-any |
| 大网段源/目的 | 收敛到业务真实网段(/24~) | 压缩横向面 | 用 /8 /16 代表「内网」 |
| 全端口 | 收敛到业务端口(≤20 个) | 压缩暴露面 | 用 any 代表「服务端口」 |
| 失效规则 | hit count 连续 90 天为 0 | 业务下线判断 | 只看瞬时值为 0 就删 |
| 临时规则 | 到期自动关闭,不留存 | 防临时放通长期化 | 临时规则忘了回收 |
| 变更回退 | 变更前完整备份策略 | 可恢复 | 无备份直接改 |
> 命中计数阈值建议取「连续 90 天为 0」而非瞬时,规避周期性业务误判。
四、分步 SOP
- 导出策略:按厂商命令全量导出,保留顺序、五元组、动作、命中计数,导出为 CSV(见
assets/policy-list.csv)。 - 遮蔽分析:跑
policy_shadow_analyzer.py自动标记被遮蔽、冗余、失效、过宽规则。 - 人工复核:对被标记规则逐条确认业务依赖,尤其是 any-any 与长期零命中规则。
- 制定收敛方案:删除冗余/遮蔽、收紧过宽、关闭失效、给临时规则设到期。
- 备份与变更:完整备份 → 按审批窗口变更 → 记录变更前后策略 diff。
- 回归验证:验证关键业务连通性,抽查命中计数是否正常增长。
- 建立周期:按月/季度定期审计,纳入合规证据链。
五、真实配置示例
思科 ASA:导出策略与命中计数
! 查看所有 access-list(含 hitcnt)
show access-list
! 查看单条命中计数(hitcnt 在每条 ACE 之后)
show access-list OUTSIDE_IN | include 10.0.0
! 查看丢弃计数(判断 deny 是否生效)
show asp drop
华为 USG:导出策略与会话
display security-policy all
display firewall session table
display policy interzone trust untrust outbound
Fortinet FortiGate:查看策略与命中
get firewall policy
show firewall policy
# 命中计数在每条 policy 的 hit count 字段
diagnose firewall proute list
Linux nftables:导出当前规则集(审计对照组)
# 按编号列出规则(含 counters,用于判断命中)
nft list ruleset -a
# 只看计数器
nft list ruleset | grep -E "counter|handle"
> 更多厂商审计命令与逐行解释见 references/policy-audit-configs.md。
六、验证方法
# 思科:确认命中计数随业务增长(非零)
show access-list | include hitcnt
# 华为:确认会话建立
display firewall session table verbose
| 验证项 | 达标线 | 采集方式 |
|---|---|---|
| 默认拒绝 | 末尾 deny any 存在并命中 | 策略导出 + 抽查 |
| 遮蔽/冗余规则 | 0 条(或已说明保留理由) | policy_shadow_analyzer.py |
| 过宽规则占比 | any-any 类 < 1% | 脚本统计 |
| 失效规则 | 已关闭或加白名单 | 命中计数连续 90 天 |
| 回退可用 | 备份可恢复(演练过) | 备份文件 + 恢复演练记录 |
七、常见故障排查
| 现象 | 根因方向 | 首要动作 |
|---|---|---|
| 审计发现大量 hit=0 | 遮蔽或业务下线 | 跑遮蔽分析,区分死规则与失效规则 |
| 收敛后业务中断 | 误删了仍被依赖的规则 | 用备份回退,重查业务依赖 |
| any-any 清不掉 | 业务依赖不明 | 逐条开启日志/命中观察,再分阶段收紧 |
| deny 日志刷屏 | 正常被拒流量也记日志 | 给噪声源加去噪,保留关键 deny 日志 |
| 命中计数始终为 0 但有业务 | 流量走了更早的宽规则 | 检查顺序,调整到宽规则之前 |
八、输出规范
交付时应产出:策略清单(CSV,含顺序/五元组/动作/命中计数)、遮蔽与冗余分析报告、过宽规则收敛建议、失效/过期规则清单、变更前后 diff、备份与回退记录。
九、边界与风险
- 收敛策略前必须确认业务依赖,误删仍在使用的规则会直接断业务,务必备份 + 分阶段 + 可回退。
- 命中计数为 0 不等于可删,需排除遮蔽、周期性业务、冷备路径。
- 不同厂商「命中计数」口径与重置时机不同,审计需注明采集时间窗。
- 本技能做策略级审计,不替代防火墙自身的威胁检测与 IPS 能力。
配套资源
- 参数手册:
references/policy-audit-parameters.md - 厂商审计命令对照:
references/policy-audit-configs.md - 故障案例库:
references/policy-audit-troubleshooting.md - 策略清单数据:
assets/policy-list.csv - 审计与收敛模板:
assets/policy-audit-template.txt - 脚本:
scripts/policy_shadow_analyzer.py(策略冗余与遮蔽分析器) - 配套检查清单:《防火墙策略审计清单》