提升云安全与资源效率的终极指南
目录导读
- 什么是未使用策略?为什么它们危害巨大?
- 手动清理 vs 自动化脚本:效率差距有多大?
- 主流云平台(AWS/Azure/GCP)自动化清理脚本实战
- 核心清理逻辑与代码示例(Python + Boto3)
- 常见问答:清理前必须规避的三大陷阱
- 总结与最佳实践建议
什么是未使用策略?为什么它们危害巨大?
未使用策略 指的是在IAM、防火墙、资源组等系统中,已经创建但长期未被任何用户、角色或资源引用的访问控制规则。

- AWS 中未附加到任何实体的 IAM 策略
- Azure 中孤立的 RBAC 角色定义
- 云防火墙中废弃的入站/出站规则
危害:
- 安全风险:废弃策略可能被恶意利用,成为权限提升的跳板(据Gartner报告,60%的云安全事故与未管理权限有关)
- 成本浪费:某些云服务(如AWS Config规则、Azure Policy)按策略数量计费
- 合规混乱:审计时,冗余策略会造成“权限迷雾”,无法清晰追踪实际生效的访问控制
手动清理 vs 自动化脚本:效率差距有多大?
| 维度 | 手动清理 | 自动化脚本 |
|---|---|---|
| 耗时(1000个策略) | 2~3天 | < 10分钟 |
| 误删风险 | 高(依赖人工记忆) | 低(基于API精确校验) |
| 可重复性 | 一次性工作 | 可定时执行(每周/每月) |
| 审计日志 | 无 | 完整记录删除操作 |
对于拥有超过50个策略的云环境,手动清理几乎不可能彻底,自动化脚本是唯一选择。
主流云平台自动化清理脚本实战
1 AWS IAM 未使用策略清理(Python + Boto3)
核心逻辑:
- 通过
list_policies获取所有策略(只筛选OnlyAttached=False) - 检查策略是否被任何用户、组或角色引用(通过
list_entities_for_policy) - 删除超过90天未使用的策略(配置阈值)
关键代码:
import boto3
from datetime import datetime, timedelta
iam = boto3.client('iam')
cutoff = datetime.now() - timedelta(days=90)
def delete_unused_policies():
policies = iam.list_policies(Scope='Local', OnlyAttached=False)['Policies']
for policy in policies:
# 检查策略是否被引用
entities = iam.list_entities_for_policy(PolicyArn=policy['Arn'])
if not any([entities['PolicyGroups'], entities['PolicyUsers'], entities['PolicyRoles']]):
# 检查创建时间是否超过阈值
if policy['CreateDate'] < cutoff:
print(f"删除未使用策略: {policy['PolicyName']}")
iam.delete_policy(PolicyArn=policy['Arn'])
2 Azure 孤立策略清理(Azure CLI + PowerShell)
# 获取所有自定义角色定义
$roles = Get-AzRoleDefinition | Where-Object {$_.IsCustom -eq $true}
foreach ($role in $roles) {
$assignments = Get-AzRoleAssignment -RoleDefinitionId $role.Id
if ($assignments.Count -eq 0) {
Write-Host "删除未分配角色: $($role.Name)"
Remove-AzRoleDefinition -Id $role.Id -Force
}
}
3 GCP 废弃防火墙规则清理(gcloud + jq)
# 列出所有未被任何资源引用的防火墙规则
gcloud compute firewall-rules list --format="json" | jq '.[] | select(.targetTags == null and .targetServiceAccounts == null) | .name' | xargs -I {} gcloud compute firewall-rules delete {} --quiet
核心清理逻辑与代码示例(Python + Boto3)
1 扩展版:安全清理流程
def safe_clean_unused_policies(dry_run=True):
"""dry_run=True时只输出日志,不实际删除"""
iam = boto3.client('iam')
paginator = iam.get_paginator('list_policies')
for page in paginator.paginate(Scope='Local', OnlyAttached=False):
for policy in page['Policies']:
# 1. 检查是否存在依赖
entities = iam.list_entities_for_policy(PolicyArn=policy['Arn'])
if not (entities['PolicyGroups'] or entities['PolicyUsers'] or entities['PolicyRoles']):
# 2. 检查策略版本数(避免删除仍有历史的策略)
versions = iam.list_policy_versions(PolicyArn=policy['Arn'])
if len(versions['Versions']) <= 2: # 默认版本+至少1个历史版本?
# 3. 最后确认删除
if not dry_run:
iam.delete_policy(PolicyArn=policy['Arn'])
print(f"已删除: {policy['PolicyName']}")
else:
print(f"[模拟]将删除: {policy['PolicyName']}")
2 需要注意的边界情况
- AWS 托管策略不能列出或删除,需跳过
Scope='Local' - Azure 内置角色无法删除,需要先筛选
IsCustom属性 - GCP 规则删除前需确认无目标标签或服务账户指向
常见问答:清理前必须规避的三大陷阱
Q1:如何避免误删正在使用的策略? A:采用 三步验证法:
- 确认策略未附加到任何 IAM 实体(用户/组/角色)
- 检查该策略是否被其他策略通过
AssumeRole间接引用(需额外扫描所有信任策略) - 设置 30天软删除:先移动到
DeletedPolicies文件夹或添加_DISABLED后缀,观察期后再彻底删除
Q2:如果策略被某个角色引用,但该角色长期未使用,是否应该删除? A:绝对不要直接删除,应先审计该角色的最后一次使用时间(通过 CloudTrail 或 Access Advisor),对于90天未使用的角色,先冻结权限再删除关联策略。
Q3:自动化脚本运行频率设置多少最合理? A:建议:
- 周清理:针对直接附加到用户的策略(高频变更)
- 月清理:针对角色/组的策略(低频变更)
- 季度审计:全量策略扫描,生成未使用策略报告
总结与最佳实践建议
核心原则
- 先审计,再清理:每次运行脚本前,生成CSV报告并邮件通知团队
- 保留恢复能力:使用
dry_run模式,删除前备份策略JSON到 S3/Blob 存储 - 与CI/CD集成:在基础设施即代码(Terraform/Pulumi)的
plan阶段自动标记未使用策略
推荐工具矩阵
| 云平台 | 推荐脚本语言 | 自动化触发方式 | 审计工具 |
|---|---|---|---|
| AWS | Python (Boto3) | EventBridge 定时任务 | IAM Access Advisor |
| Azure | PowerShell | Automation Account | Azure Monitor |
| GCP | Go/gcloud | Cloud Scheduler | Policy Analyzer |
最终提醒
未使用策略清理不是一次性的“大扫除”,而是持续的安全运维习惯,建议每月至少执行一次全量扫描,并将清理结果纳入运维周报。每一个被删除的废弃策略,都是在减少一个潜在的攻击面。