name: aws-security-scanner
description: 扫描 AWS 账户中的安全配置错误与漏洞。当用户要求审计 AWS 安全状况、检查配置错误、查找公开的 S3 存储桶、审查 IAM 策略、检查安全组、审计 CloudTrail 或运行 AWS 安全检查时使用。涵盖 S3、IAM、EC2、RDS、CloudTrail 及常见 CIS 基准。
使用 AWS CLI 审计 AWS 基础设施的安全问题。
aws configure 或 IAM 角色)# 查找公开的存储桶
aws s3api list-buckets --query 'Buckets[].Name' --output text | tr '\t' '\n' | while read bucket; do
acl=$(aws s3api get-bucket-acl --bucket "$bucket" 2>/dev/null)
policy=$(aws s3api get-bucket-policy --bucket "$bucket" 2>/dev/null)
public_access=$(aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null)
echo "=== $bucket ==="
echo "$acl" | grep -q "AllUsers\|AuthenticatedUsers" && echo "⚠️ 公共 ACL"
echo "$policy" | grep -q '"Principal":"\*"' && echo "⚠️ 公共策略"
echo "$public_access" | grep -q "false" && echo "⚠️ 未完全阻止公共访问"
done
# 未启用 MFA 的用户
aws iam generate-credential-report && sleep 5
aws iam get-credential-report --query 'Content' --output text | base64 -d | grep -E "^[^,]+,.*,false" | cut -d',' -f1
# 权限过大的策略(管理员权限)
aws iam list-policies --scope Local --query 'Policies[].Arn' --output text | tr '\t' '\n' | while read arn; do
version=$(aws iam get-policy --policy-arn "$arn" --query 'Policy.DefaultVersionId' --output text)
aws iam get-policy-version --policy-arn "$arn" --version-id "$version" --query 'PolicyVersion.Document' | grep -q '"Action":"\*".*"Resource":"\*"' && echo "⚠️ 管理员策略: $arn"
done
# 超过 90 天的访问密钥
aws iam list-users --query 'Users[].UserName' --output text | tr '\t' '\n' | while read user; do
aws iam list-access-keys --user-name "$user" --query "AccessKeyMetadata[?CreateDate<='$(date -d '-90 days' +%Y-%m-%d)'].{User:UserName,KeyId:AccessKeyId,Created:CreateDate}" --output table
done
# 对全球开放(0.0.0.0/0)
aws ec2 describe-security-groups --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].{ID:GroupId,Name:GroupName,VPC:VpcId}' --output table
# SSH 对全球开放
aws ec2 describe-security-groups --filters "Name=ip-permission.from-port,Values=22" "Name=ip-permission.cidr,Values=0.0.0.0/0" --query 'SecurityGroups[].{ID:GroupId,Name:GroupName}' --output table
# RDP 对全球开放
aws ec2 describe-security-groups --filters "Name=ip-permission.from-port,Values=3389" "Name=ip-permission.cidr,Values=0.0.0.0/0" --query 'SecurityGroups[].{ID:GroupId,Name:GroupName}' --output table
# 检查所有区域是否启用了 CloudTrail
aws cloudtrail describe-trails --query 'trailList[].{Name:Name,IsMultiRegion:IsMultiRegionTrail,LogValidation:LogFileValidationEnabled,S3Bucket:S3BucketName}' --output table
# 检查未启用日志验证的跟踪
aws cloudtrail describe-trails --query 'trailList[?LogFileValidationEnabled==`false`].Name' --output text
# 可公开访问的 RDS 实例
aws rds describe-db-instances --query 'DBInstances[?PubliclyAccessible==`true`].{ID:DBInstanceIdentifier,Engine:Engine,Endpoint:Endpoint.Address}' --output table
# 未加密的 RDS 实例
aws rds describe-db-instances --query 'DBInstances[?StorageEncrypted==`false`].{ID:DBInstanceIdentifier,Engine:Engine}' --output table
# 未加密的 EBS 卷
aws ec2 describe-volumes --query 'Volumes[?Encrypted==`false`].{ID:VolumeId,Size:Size,State:State}' --output table
运行全面扫描并输出 Markdown 报告:
echo "# AWS 安全审计报告"
echo "生成时间: $(date)"
echo ""
echo "## S3 存储桶"
# ... 运行 S3 检查
echo ""
echo "## IAM"
# ... 运行 IAM 检查
echo ""
echo "## 安全组"
# ... 运行安全组检查
# 等等。
| 问题 | 严重性 |
|---|---|
| S3 存储桶公开 | 🔴 严重 |
| SSH/RDP 对全球开放 | 🔴 严重 |
| IAM 用户未启用 MFA | 🟠 高 |
| 附加了管理员策略 | 🟠 高 |
| CloudTrail 未启用 | 🟠 高 |
| RDS 可公开访问 | 🟠 高 |
| EBS/RDS 未加密 | 🟡 中 |
| 访问密钥超过 90 天 | 🟡 中 |
关于全面的 CIS AWS 基础基准合规性,请检查:
- 1.1:避免使用根账户
- 1.2:根账户启用 MFA
- 1.3:禁用未使用的凭据
- 2.1:启用 CloudTrail
- 2.2:日志文件验证
- 4.1:无安全组允许 0.0.0.0/0 访问端口 22
- 4.2:无安全组允许 0.0.0.0/0 访问端口 3389
对于定期扫描,可使用 AWS Config Rules 或设置 cron 任务:
0 6 * * * /path/to/aws-security-scan.sh | mail -s "每日 AWS 审计" security@company.com