关于 alibabacloud-waf-security-monitor
用于检查和监控 Alibaba Cloud WAF 3.0 实例的安全巡检技能,覆盖 cn-hangzhou 和 ap-southeast-1。它汇总资产、攻击事件、流量、HTTP 状态码和防护状态,并生成结构化报告。
主要功能
- 01双地域 WAF 实例巡检
- 02统计攻击事件与流量
- 03检测 HTTP 状态码异常
- 04检查告警、DDoS 与防护状态
- 05生成结构化巡检报告
适用场景
- 01定期检查 WAF 资产和证书
- 02比较不同时间段的流量变化
- 03排查 4xx 或 5xx 状态码异常
- 04核对告警及防护是否暂停
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aliyun/ alibabacloud-aiops-skills --skill alibabacloud-waf-security-monitor安装后在 Claude Code 中输入/alibabacloud-waf-security-monitor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/acceptance-criteria.mdapi-reference.mdcli-installation-guide.mdcli-setup.mddefense-templates.mdram-policies.mdrelated-commands.mdreport-template.mdverification-method.mdscripts/detect_region_mismatch.pyextract_bot_template.pyrequirements.txtverify_output.py详细介绍
WAF 安全产品检查与监控
此技能可对阿里云 WAF 3.0 实例进行全面安全检查,覆盖两个业务地域(cn-hangzhou 和 ap-southeast-1)。检查内容包括资产清单(CNAME 域名、云产品接入、SSL 证书)、攻击事件统计(通过 bot_manager 模板统计 Bot/CC)、流量分析(QPS/带宽及同期对比)、HTTP 状态码异常检测(4xx/5xx)和防护状态检查(告警、DDoS、暂停状态)。检查结果将按照标准化模板生成结构化报告。
架构:waf-openapi (WAF 3.0) -> aliyun CLI plugin mode (kebab-case) -> Dual-Region Inspection -> Structured Report
预检查
预检查:Aliyun CLI 版本必须不低于 3.3.3
运行
aliyun version,确认版本不低于 3.3.3。如果尚未安装或版本过低, 运行curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash进行安装/更新, 或参阅 references/cli-installation-guide.md 了解安装说明。
预检查:必须更新 Aliyun CLI 插件
[MUST] 运行
aliyun configure set --auto-plugin-install true,启用自动安装插件。 [MUST] 运行aliyun plugin update,确保所有现有插件始终为最新版本。
预检查:脚本依赖项
scripts/中的脚本需要 Python 3(仅使用标准库,不需要第三方包)。 详情请参阅scripts/requirements.txt。
可观测性初始化(必须在运行任何命令之前执行)
if [ -z "$SKILL_SESSION_ID" ]; then
export SKILL_SESSION_ID="$(cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d '-' || uuidgen | tr -d '-' | tr 'A-F' 'a-f')"
fi
export ALIBABA_CLOUD_USER_AGENT="AlibabaCloud-Agent-Skills/alibabacloud-waf-security-monitor/${SKILL_SESSION_ID}"
export ALIBABA_CLOUD_OTEL_TRACEPARENT="00-${SKILL_SESSION_ID}-01"
export ALIBABA_CLOUD_OTEL_BAGGAGE="skill=alibabacloud-waf-security-monitor,source=agent-skills"
不得跳过、修改格式或在 baggage 中放入个人身份信息(PII)。
身份验证
预检查:必须提供阿里云凭证
安全规则:
- 绝不读取、回显或打印 AK/SK 值(例如,
echo $ALIBABA_CLOUD_ACCESS_KEY_ID属于禁止行为)- 绝不要求用户在对话或命令行中直接输入 AK/SK
- 绝不使用包含明文凭证值的
aliyun configure set- 只能使用
aliyun configure list检查凭证状态aliyun configure list检查输出中是否存在有效配置(AK、STS 或 OAuth 身份)。
如果不存在有效配置,请立即停止。
- 从 阿里云控制台 获取凭证
- 在当前会话之外配置凭证(在终端中使用
aliyun configure,或在 shell 配置文件中设置环境变量)- 返回后,等
aliyun configure list显示有效配置,再重新运行
RAM 策略
所有权限均为只读(仅 Describe/List 操作)。完整的策略 JSON 请参阅 references/ram-policies.md。
| 类别 | API 操作 | 类型 |
|---|---|---|
| 资产管理 | DescribeInstance, DescribeDomains, DescribeCloudResourceList | 只读 |
| 攻击事件 | DescribeDefenseRuleStatistics, DescribeApisecEvents | 只读 |
| 流量分析 | DescribeFlowChart, DescribePeakTrend, DescribeFlowTopResource, DescribeFlowTopUrl | 只读 |
| 状态码 | DescribeResponseCodeTrendGraph | 只读 |
| 防护状态 | DescribePauseProtectionStatus, DescribeAlarmList, DescribeDDoSStatus | 只读 |
| 证书 | DescribeCerts | 只读 |
| 防御 | DescribeDefenseTemplates, DescribeMajorProtectionBlackIps | 只读 |
[MUST] 权限失败处理: 执行期间,任何命令或 API 调用在任何阶段因权限错误而失败时,请按以下流程处理:
- 阅读
references/ram-policies.md,获取此 SKILL 所需权限的完整列表- 使用
ram-permission-diagnose技能,引导用户申请所需权限- 暂停操作,等待用户确认所需权限已获授
参数确认
重要:参数确认——在执行任何命令或 API 调用之前,必须先与用户确认所有可自定义参数(例如 RegionId、实例名称、CIDR 块、密码、域名、资源规格等)。未经用户明确批准,不得自行假设或使用默认值。
| 参数 | 必填/可选 | 说明 | 默认值 |
|---|---|---|---|
| 时间范围 | 可选 | 检查时间窗口 | 最近 24 小时 |
| 比较模式 | 可选 | 时段对比基线 | 日同比 |
| 区域范围 | 可选 | 要检查的 WAF 区域 | cn-hangzhou 和 ap-southeast-1 |
注意:InstanceId 会自动发现,无需用户输入。 阶段 1 会对每个区域调用
describe-instance,自动获取 WAF InstanceId。后续所有 API 调用都会使用发现的值。用户无需手动提供--instance-id。
核心检查工作流
执行指南:
- 区域规则:WAF 3.0 只有两个业务区域:
cn-hangzhou和ap-southeast-1。请分别查询两者——每个区域都有自己的 InstanceId。仅使用--region标志(--region-id会导致“未知标志”错误;--biz-region-id无法正确路由)。请参阅 API 参考。- 每条命令的 User-Agent:每次
aliyun waf-openapiCLI 调用都必须包含--user-agent "$ALIBABA_CLOUD_USER_AGENT"标志(在可观测性初始化期间设置)。- 阶段 1-2-3-4 必须在同一 shell 会话中执行:
REGION_INSTANCES、BASE_START、EFFECTIVE_BOT_ID等变量会在各阶段间共享。拆分到不同 shell 会话会导致这些值丢失并引发未定义变量错误。- 使用 bash 运行每个代码块。不要只进行描述或规划。
- API 调用输出的变量名必须使用
RESULT,因为验证脚本(scripts/verify_output.py)和日志汇总模式依赖统一的变量命名。- 将每条
aliyun waf-openapi命令的输出追加到/tmp/waf_skill_output.log——阶段 4.7 的验证脚本会解析此单个文件以检查完整性。- 出错时:向用户报告并继续。结果为空时:报告“0”,不要省略该部分。
阶段 1-2-3:环境、资产和时间戳(单个代码块)
# === Phase 1: Heartbeat ===
HEARTBEAT_CN=$(aliyun waf-openapi describe-instance \
--region cn-hangzhou --user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$HEARTBEAT_CN" > /tmp/waf_skill_output.log
HEARTBEAT_INTL=$(aliyun waf-openapi describe-instance \
--region ap-southeast-1 --user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$HEARTBEAT_INTL" >> /tmp/waf_skill_output.log
# Setup
aliyun version
aliyun configure set --auto-plugin-install true --connect-timeout 10 --read-timeout 30 2>/dev/null || true
aliyun plugin update 2>/dev/null || true
# === Phase 2.1: Instance discovery (from heartbeat, no redundant calls) ===
declare -A REGION_INSTANCES
for region in cn-hangzhou ap-southeast-1; do
if [ "$region" = "cn-hangzhou" ]; then RAW="$HEARTBEAT_CN"; else RAW="$HEARTBEAT_INTL"; fi
IDS=$(echo "$RAW" | python3 -c "
import sys,json,re
raw=sys.stdin.read()
raw=re.sub(r'[\x00-\x1f\x7f]','',raw)
try:
d=json.loads(raw)
if 'InstanceId' in d: print(d['InstanceId'])
except:
for line in raw.splitlines():
if '\"InstanceId\"' in line and 'waf_' in line:
print(line.split('\"InstanceId\"')[1].split('\"')[1]); break
" 2>/dev/null)
REGION_INSTANCES[$region]="$IDS"
echo "[MAPPING] $region -> $IDS"
done
echo "[CHECK] cn-hangzhou=${REGION_INSTANCES[cn-hangzhou]} | ap-southeast-1=${REGION_INSTANCES[ap-southeast-1]}"
# DEGRADED FALLBACK
[ -z "${REGION_INSTANCES[cn-hangzhou]}" ] && REGION_INSTANCES[cn-hangzhou]="UNKNOWN" && echo "[DEGRADED] cn-hangzhou=UNKNOWN"
[ -z "${REGION_INSTANCES[ap-southeast-1]}" ] && REGION_INSTANCES[ap-southeast-1]="UNKNOWN" && echo "[DEGRADED] ap-southeast-1=UNKNOWN"
# === Phase 2.2: Domains (use page-size 10 -- larger values like 100 trigger API parameter errors) ===
for region in cn-hangzhou ap-southeast-1; do
for instance_id in ${REGION_INSTANCES[$region]}; do
RESULT=$(aliyun waf-openapi describe-domains \
--instance-id $instance_id --region $region \
--page-number 1 --page-size 10 \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
done
# === Phase 2.3: Cloud resources + Certificates ===
for region in cn-hangzhou ap-southeast-1; do
for instance_id in ${REGION_INSTANCES[$region]}; do
RESULT=$(aliyun waf-openapi describe-cloud-resource-list \
--instance-id $instance_id --region $region \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
# Cross-region mismatch detection: flag resources whose ResourceRegionId != WAF instance region
echo "$RESULT" | python3 scripts/detect_region_mismatch.py \
--region "$region" --instance-id "$instance_id" >> /tmp/waf_skill_output.log
RESULT=$(aliyun waf-openapi describe-certs \
--instance-id $instance_id --region $region \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
done
# === Phase 3: Timestamps ===
if [ -n "$BASE_END" ] && ! echo "$BASE_END" | grep -qE '^[0-9]+$'; then
echo "[ERROR] BASE_END is not a valid integer: $BASE_END"; exit 1
fi
if [ -n "$BASE_START" ] && ! echo "$BASE_START" | grep -qE '^[0-9]+$'; then
echo "[ERROR] BASE_START is not a valid integer: $BASE_START"; exit 1
fi
BASE_END=${BASE_END:-$(date +%s)}; BASE_START=${BASE_START:-$((BASE_END - 86400))}
COMPARE_END=$((BASE_START)); COMPARE_START=$((COMPARE_END - (BASE_END - BASE_START)))
echo "[TIMESTAMP] BASE=$BASE_START~$BASE_END COMPARE=$COMPARE_START~$COMPARE_END"
echo "[PHASE 1-2-3 DONE] Instances: cn-hangzhou=${REGION_INSTANCES[cn-hangzhou]} ap-southeast-1=${REGION_INSTANCES[ap-southeast-1]}"
中止规则:各区域独立处理。cn-hangzhou 失败不代表要跳过 ap-southeast-1。 只有遇到
InvalidAccessKeyId(凭证问题会影响所有区域)时才终止。其他情况均以 UNKNOWN 占位符进入降级模式。
阶段 4:检查(按区域、按实例)
无论之前的结果如何,都应执行所有代码块 4.1-4.5,因为各检查维度相互独立。
- 调用 N 出错:记录错误并立即执行调用 N+1。
- 每次调用都必须包含
--user-agent "$ALIBABA_CLOUD_USER_AGENT"标志。- 每次调用均使用:
RESULT=$(aliyun waf-openapi <cmd> --region $region --user-agent "$ALIBABA_CLOUD_USER_AGENT" ... 2>&1); echo "$RESULT" >> /tmp/waf_skill_output.log- 循环:
for region in cn-hangzhou ap-southeast-1; do for instance_id in ${REGION_INSTANCES[$region]}; do- 每个区域完成 4.1-4.5 后,打印:
echo "[CHECKPOINT] region=$region ALL phases done"- 不要在区域循环中使用 break/continue/return。
4.1 防护模板
使用 python3 提取 JSON(不要使用 grep/sed/awk/bash 字符串操作)。请参阅 防护模板指南。
RESULT=$(aliyun waf-openapi describe-defense-templates \
--instance-id $instance_id --region $region \
--page-number 1 --page-size 50 \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
BOT_TEMPLATE_ID=$(echo "$RESULT" | python3 scripts/extract_bot_template.py 2>/dev/null)
if ! echo "$BOT_TEMPLATE_ID" | grep -qE '^[0-9]+$'; then BOT_TEMPLATE_ID=""; fi
EFFECTIVE_BOT_ID="${BOT_TEMPLATE_ID:-0}"
echo "[TEMPLATE] BOT=$EFFECTIVE_BOT_ID region=$region"
describe-defense-rule-statistics仅支持bot_manager。其他场景会返回DefenseSceneNotSupported。- 模板 ID 为空时:使用
0作为回退值(确保调用能够到达服务器;服务器会返回“找不到模板”,并记录该错误)。
4.2 攻击事件(每个实例调用 3 次)
CC 检测映射:CC 攻击数据来自
describe-defense-rule-statistics(primary-key=scene/action/status)。 如果 API 返回为空,写“CC/Bot 攻击:0(此期间没有拦截记录)”——避免写“未检测到”,因为这会暗示已主动进行检测。
for key in scene action status; do
RESULT=$(aliyun waf-openapi describe-defense-rule-statistics \
--instance-id $instance_id --primary-key $key \
--template-id $EFFECTIVE_BOT_ID --region $region \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
RESULT=$(aliyun waf-openapi describe-apisec-events \
--instance-id $instance_id --region $region \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
RESULT=$(aliyun waf-openapi describe-major-protection-black-ips \
--instance-id $instance_id --region $region \
--page-number 1 --page-size 50 \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
4.3 流量(基础期 + 对比期,均为必需)
for api in describe-flow-chart describe-peak-trend; do
RESULT=$(aliyun waf-openapi $api \
--instance-id $instance_id --region $region \
--start-timestamp $BASE_START --end-timestamp $BASE_END --interval 300 \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
# COMPARE period (execute even if base returned empty)
for api in describe-flow-chart describe-peak-trend; do
RESULT=$(aliyun waf-openapi $api \
--instance-id $instance_id --region $region \
--start-timestamp $COMPARE_START --end-timestamp $COMPARE_END --interval 300 \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
RESULT=$(aliyun waf-openapi describe-flow-top-resource \
--instance-id $instance_id --region $region \
--start-timestamp $BASE_START --end-timestamp $BASE_END \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
RESULT=$(aliyun waf-openapi describe-flow-top-url \
--instance-id $instance_id --region $region \
--start-timestamp $BASE_START --end-timestamp $BASE_END \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
echo "[SELF-CHECK-4.3] region=$region BASE+COMPARE flow calls done."
4.4 HTTP 状态码(每个区域调用 4 次:2 种类型 × 2 个期间)
for type_val in waf upstream; do
for start_ts end_ts in $BASE_START $BASE_END $COMPARE_START $COMPARE_END; do
RESULT=$(aliyun waf-openapi describe-response-code-trend-graph \
--instance-id $instance_id --region $region \
--start-timestamp $start_ts --end-timestamp $end_ts \
--interval 300 --type $type_val \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
done
echo "[CHECKPOINT-4.4] region=$region status_code_calls=4."
4.5 防护状态
for api in describe-pause-protection-status describe-alarm-list describe-ddos-status; do
RESULT=$(aliyun waf-openapi $api \
--instance-id $instance_id --region $region \
--user-agent "$ALIBABA_CLOUD_USER_AGENT" 2>&1)
echo "$RESULT" >> /tmp/waf_skill_output.log
done
echo "[CHECKPOINT] region=$region ALL phases done"
证书阈值:<7 天=严重,<30 天=警告,>=30 天=正常。数据来自阶段 2.3 describe-certs(不要重新调用)。
4.6 期间环比
变化率 =(基础期 - 对比期)/ 对比期 × 100%。阈值:+/-50-100%=需关注,>+/-100%=异常。
4.7 报告与验证
报告:遵循报告模板。按区域分组。
跨区域不匹配:验证后,检查日志中是否包含
[REGION_MISMATCH_SUMMARY]行。如果存在,在报告中加入“跨区域资源风险”部分,列出每个不匹配的资源。在结论中将其视为配置风险事项。错误与空结果——区分两者可避免将 API 故障误报为“零事件”:
- API 200 +
[]->0(API 返回为空)- API 错误 ->
[QUERY FAILED (ErrorCode: XXX)]- API 返回错误时,不要写
0。验证——在编写报告前运行此命令,以发现数据遗漏:
python3 scripts/verify_output.py /tmp/waf_skill_output.log报告完整性规则:
- 所有报告数字都应来自日志解析。没有 API 来源的硬编码值 = 捏造。
- 不要跨区域归属域名。
- 拦截数 = 0 时,不要写“检测到攻击”。
- 不要推断 API 响应中未出现的具体路径/端点。
- 如果
QUERY FAILED超过 50% 的部分,结论应注明“评估不完整”。- 每个数据点都应注明其来源 API。
空数据报告规则:
- API 返回空数组/0:写“此期间未返回数据(API 返回为空)”
- 不要写“未检测到重大攻击”“流量保持稳定”等推测性描述
- 期间环比:如果基础期=0 且对比期=0,写“两个期间均无数据,无法计算”
- 期间环比:如果对比期=0 且基础期>0,写“对比期无数据,缺少基准”
证书与时间戳规则:
- 证书到期天数应引用
scripts/verify_output.py输出的[CERT]行。不要通过 bash 算术计算到期天数。- 使用
python3 datetime或date -d @ts将时间戳转换为日期。- 生成报告前进行交叉核对:验证脚本中的
[VERIFY] Domains= 报告域名列表;[CERT]数量 = 报告证书数量。
成功验证
有关执行证据、参数正确性、结果处理和防捏造规则的详细评估层级及通过/失败标准,请参阅 references/verification-method.md。
清理
无需显式清理。所有操作均为只读操作,且不会配置任何资源。
最佳实践
- 始终分别查询两个 WAF 业务区域(cn-hangzhou、ap-southeast-1)
- 仅使用
--region,绝不使用--region-id或--biz-region-id - 每条
aliyun waf-openapi命令都必须包含--user-agent "$ALIBABA_CLOUD_USER_AGENT" - 使用 python3 提取 JSON,绝不使用 grep/sed/awk 处理 API 响应
- 仅使用
DefenseScene=bot_manager筛选防护模板——其他所有场景都会返回错误 - 无论之前是否发生错误,都要执行所有检查阶段——各个维度相互独立
- 在报告中区分 API 错误和空结果
- 编写报告前,使用
scripts/verify_output.py验证数据完整性 - 绝不编造数据——所有数字都必须能在日志文件中的 API 响应里找到依据
- 无论之前是否发生错误,都要执行所有检查阶段——各个维度相互独立
- describe-domains 使用
--page-size 10(较大的值会触发 API 参数错误)