诊断与验证
本页提供一个分层 UAT 验证矩阵,用于端到端验证您的客户端防护(Client-Side Defense)部署。每个测试用例遵循基础设施依赖链——从 DNS 解析到 CSD 遥测——以便您系统地验证每个组件是否正常运行。
这些命令是 CSD 控制台演练 的 API 等效操作——当您需要从终端进行验证、自动化监控或在无需 UI 的情况下演示 CSD 功能时使用。
按照 API 自动化 — 环境设置 中的说明配置您的环境变量:
set -a && source .env && set +a以下所有命令均使用 xTOKENx 占位符格式。请替换为您的环境变量($F5XC_API_TOKEN、$F5XC_NAMESPACE 等),或使用页面顶部的交互表单。
API 行为说明
Section titled “API 行为说明”时间范围辅助工具
Section titled “时间范围辅助工具”许多 CSD 端点需要 epoch 时间戳(自 Unix 纪元起的秒数)。以下单行命令可计算常用时间范围的起止时间。
跨平台(macOS + Linux):
# 当前时间的 epoch 秒数NOW=$(date +%s)
# 1 小时前START_1H=$(( NOW - 3600 ))
# 24 小时前START_24H=$(( NOW - 86400 ))
# 7 天前START_7D=$(( NOW - 604800 ))
# 30 天前START_30D=$(( NOW - 2592000 ))| 预设 | 秒数 | Shell 表达式 |
|---|---|---|
| 1 小时 | 3,600 | $(( $(date +%s) - 3600 )) |
| 24 小时 | 86,400 | $(( $(date +%s) - 86400 )) |
| 7 天 | 604,800 | $(( $(date +%s) - 604800 )) |
| 30 天 | 2,592,000 | $(( $(date +%s) - 2592000 )) |
测试用例格式
Section titled “测试用例格式”以下每个测试均遵循以下结构:
| 字段 | 说明 |
|---|---|
| 测试 ID | 层号 + 顺序 ID(如 DNS-1、TLS-2) |
| 验证内容 | 所验证的具体基础设施事实 |
| 命令 | 可直接运行的 curl 或 dig 命令 |
| 通过 / 失败 | 正常与异常状态下的预期输出 |
| 修复 | 指向相关设置或故障排除章节的链接 |
第 1 层:DNS 解析
Section titled “第 1 层:DNS 解析”DNS 是基础——如果域名无法解析到负载均衡器的 VIP,其他一切均无法正常工作。
DNS-1:A 记录解析
Section titled “DNS-1:A 记录解析”验证内容: 域名解析到负载均衡器的 VIP IP 地址。
dig +short xF5XC_DOMAINNAMEx A| 结果 | 含义 |
|---|---|
通过 — 返回 VIP IP(如 72.19.3.185) | 域名解析到 LB 虚拟 IP |
| 失败 — 空响应 | DNS A 记录未配置 |
DNS-2:ACME 质询记录
Section titled “DNS-2:ACME 质询记录”验证内容: ACME 质询记录已存在,用于自动 TLS 证书签发。
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAMEdig +short _acme-challenge.xF5XC_DOMAINNAMEx TXT| 结果 | 含义 |
|---|---|
通过 — CNAME 指向 *.autocerts.ves.volterra.io.(外部 DNS) | ACME 质询 CNAME 已就位 |
| 通过 — TXT 记录包含域名值(F5 Distributed Cloud (F5 XC) 托管 DNS) | 平台通过 TXT 记录管理 ACME 质询 |
| 失败 — 两者均为空 | ACME 记录未配置;证书将保持 PreDomainChallengePending 状态 |
修复: 对于外部 DNS,请创建 CNAME:_acme-challenge.xF5XC_DOMAINNAMEx → *.autocerts.ves.volterra.io。对于 F5 XC 托管 DNS,请在 DNS 区域上启用 allow_http_lb_managed_records — 参见 DNS-4。请参阅 API 自动化 — 第 4 步。
DNS-3:域名服务器权威性
Section titled “DNS-3:域名服务器权威性”验证内容: F5 XC 是否为根域的权威 DNS 提供商。
dig +short NS xF5XC_ROOT_DOMAINx| 结果 | 含义 |
|---|---|
包含 ns1.f5clouddns.com 和 ns2.f5clouddns.com | F5 XC 托管 DNS — 记录可自动创建 |
| 其他域名服务器 | 外部 DNS — 记录必须手动创建 |
DNS-4:F5 XC 托管记录已启用
Section titled “DNS-4:F5 XC 托管记录已启用”验证内容: F5 XC DNS 区域允许为负载均衡器自动创建记录(仅适用于 F5 XC 托管 DNS)。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx" \ | jq '.spec.primary.allow_http_lb_managed_records'| 结果 | 含义 |
|---|---|
通过 — true | 平台将为 LB 自动创建 A 记录和 ACME 记录 |
失败 — false 或 null | 托管记录已禁用;请通过区域更新启用 |
修复: API 自动化 — 选项 A:F5 XC 托管 DNS
第 2 层:TLS 证书
Section titled “第 2 层:TLS 证书”DNS 解析成功后,负载均衡器必须具备有效的 TLS 证书。
TLS-1:证书状态
Section titled “TLS-1:证书状态”验证内容: HTTPS LB 上的自动 TLS 证书已签发。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \ | jq '.spec.cert_state'| 结果 | 含义 |
|---|---|
通过 — "CertificateValid" 或 "AutoCertRenewing" | 证书有效且处于激活状态 |
警告 — "DomainChallengePending" 或 "DomainChallengeStarted" | ACME 质询进行中 — 等待 5–10 分钟 |
信息 — "AutoCertDomainRateLimited" | 触发 Let’s Encrypt 速率限制 — 演示环境中属正常现象,不影响 HTTP LB |
失败 — "PreDomainChallengePending" | ACME 质询记录缺失 — 参见 DNS-2 |
修复: 确保 ACME 质询记录已就位(外部 DNS 使用 CNAME,F5 XC DNS 启用托管记录)。记录配置完成后,证书签发需要 5–10 分钟。若超过 15 分钟仍未完成,请参阅 证书卡住 — 清理重建。若触发速率限制,HTTP LB 不受影响。
TLS-2:证书详情
Section titled “TLS-2:证书详情”验证内容: 证书覆盖了预期域名并显示过期信息。仅适用于 HTTPS LB。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \ | jq '{ cert_state: .spec.cert_state, auto_cert_info: .spec.auto_cert_info }'| 结果 | 含义 |
|---|---|
通过 — auto_cert_info 包含 dns_records 和证书元数据 | 证书签发详情可用 |
失败 — auto_cert_info 为 null 或为空 | 证书尚未签发 |
TLS-3:实时 TLS 握手
Section titled “TLS-3:实时 TLS 握手”验证内容: TLS 证书有效且握手从客户端侧成功完成。仅在 HTTPS LB 具有有效证书时适用。
curl -sv "https://xF5XC_DOMAINNAMEx/" 2>&1 \ | grep -E 'SSL connection|subject:|expire date:|issuer:'| 结果 | 含义 |
|---|---|
通过 — 显示 SSL connection using TLSv1.3、有效的主题和过期信息 | 端到端 TLS 正常工作 |
| 失败 — 连接被拒绝或证书错误 | 检查 DNS 解析和证书状态;若触发速率限制,请改用 HTTP |
TLS-4:LB 中的 ACME 记录目标
Section titled “TLS-4:LB 中的 ACME 记录目标”验证内容: HTTPS 负载均衡器报告了用于证书验证的正确 ACME 目标。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \ | jq '{ vip_ip: .spec.dns_info[0].ip_address, acme_target: .spec.auto_cert_info.dns_records }'| 结果 | 含义 |
|---|---|
通过 — vip_ip 和 acme_target 均已填充 | 可根据这些值验证 DNS 记录 |
失败 — 值为 null | LB 可能未配置 https_auto_cert |
第 3 层:HTTP 负载均衡器
Section titled “第 3 层:HTTP 负载均衡器”负载均衡器必须处于就绪状态且配置正确。
LB-1:运行状态
Section titled “LB-1:运行状态”验证内容: HTTP 负载均衡器(主要)完全运行并接受流量。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '.spec.state'| 结果 | 含义 |
|---|---|
通过 — "VIRTUAL_HOST_READY" | LB 正常运行 |
失败 — "VIRTUAL_HOST_PENDING_A_RECORD" | DNS A 记录未配置 — 参见 DNS-1 |
修复: LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD
LB-2:域名配置
Section titled “LB-2:域名配置”验证内容: HTTP 负载均衡器已为正确的域名配置。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '.spec.domains'| 结果 | 含义 |
|---|---|
通过 — 数组包含您的 FQDN(如 ["app.example.com"]) | LB 已为预期域名配置 |
| 失败 — 缺少或错误的域名 | 使用正确的域名更新 LB 规格 |
LB-3:LB 上已启用 CSD
Section titled “LB-3:LB 上已启用 CSD”验证内容: 负载均衡器上已启用客户端防护,并配置了正确的 JS 注入策略。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '{ csd_enabled: (if .spec.client_side_defense then true else false end), js_policy: .spec.client_side_defense.policy }'| 结果 | 含义 |
|---|---|
通过 — csd_enabled: true 且策略中包含 js_insert_all_pages | CSD 已激活并在所有页面注入 JS |
失败 — csd_enabled: false | LB 上未配置 CSD |
LB-4:默认路由池
Section titled “LB-4:默认路由池”验证内容: 负载均衡器引用了正确的源池,并具有预期的权重和优先级。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '.spec.default_route_pools[] | { pool: .pool.name, namespace: .pool.namespace, weight: .weight, priority: .priority }'| 结果 | 含义 |
|---|---|
| 通过 — 显示您的源池名称及权重/优先级 | LB 正在路由到正确的后端 |
| 失败 — 池为空或错误 | 更新 LB 的 default_route_pools 配置 |
LB-5:部署状态(每站点条件)
Section titled “LB-5:部署状态(每站点条件)”验证内容: 负载均衡器已部署,并在所有站点报告健康状态。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '{ state: .spec.state, dns_info: .spec.dns_info, host_name: .spec.host_name }'| 结果 | 含义 |
|---|---|
通过 — state 为 VIRTUAL_HOST_READY,dns_info 已填充 | LB 已完全部署并分配了 VIP |
失败 — 处于待处理状态或 dns_info 为空 | DNS 或证书问题阻碍了部署 |
LB-6:完整 LB 摘要
Section titled “LB-6:完整 LB 摘要”验证内容: 两个 LB 配置的综合快照,用于调试。
HTTP LB(主要):
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '{ name: .metadata.name, state: .spec.state, domains: .spec.domains, csd_enabled: (if .spec.client_side_defense then true else false end), route_pools: [.spec.default_route_pools[] | .pool.name], advertise: (if .spec.advertise_on_public_default_vip then "public_default_vip" else "custom" end) }'HTTPS LB(次要 — 包含证书状态):
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \ | jq '{ name: .metadata.name, state: .spec.state, cert_state: .spec.cert_state, domains: .spec.domains, csd_enabled: (if .spec.client_side_defense then true else false end), route_pools: [.spec.default_route_pools[] | .pool.name] }'第 4 层:源池
Section titled “第 4 层:源池”源池定义了负载均衡器将流量路由到的后端服务器。
OP-1:源池配置
Section titled “OP-1:源池配置”验证内容: 源池存在,并配置了正确的后端服务器、端口和 LB 算法。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \ | jq '{ name: .metadata.name, origin_servers: [.spec.origin_servers[] | { ip: .public_ip.ip, labels: .labels }], port: .spec.port, lb_algorithm: .spec.loadbalancer_algorithm, endpoint_selection: .spec.endpoint_selection }'| 结果 | 含义 |
|---|---|
| 通过 — 显示正确的 IP、端口和算法 | 源池配置正确 |
失败 — 404 或值错误 | 源池缺失或配置错误 |
OP-2:到源的 TLS
Section titled “OP-2:到源的 TLS”验证内容: LB 与源服务器之间的连接是否配置了 TLS。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \ | jq '{ tls_config: (if .spec.no_tls then "no_tls (plaintext)" elif .spec.use_tls then "use_tls (encrypted)" else "unknown" end) }'| 结果 | 含义 |
|---|---|
no_tls (plaintext) | LB 通过 HTTP 连接到源(Juice Shop 演示的预期行为) |
use_tls (encrypted) | LB 通过 HTTPS 连接到源 |
OP-3:健康检查关联
Section titled “OP-3:健康检查关联”验证内容: 源池已关联正确的健康检查(如适用)。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \ | jq '.spec.healthcheck'| 结果 | 含义 |
|---|---|
| 通过 — 包含健康检查引用的数组(名称、命名空间、类型) | 健康检查已关联 |
正常 — 空数组 [] | 无健康检查(可接受 — CSD 不要求) |
| 失败 — 预期有健康检查但数组为空 | 创建时未找到健康检查 — 参见 健康检查未关联 |
OP-4:源连接性
Section titled “OP-4:源连接性”验证内容: 源服务器可从客户端侧访问(不测试 LB 到源的路径)。
curl -s -o /dev/null -w '%{http_code}' \ "http://xF5XC_ORIGIN_IPx:xF5XC_ORIGIN_PORTx/"| 结果 | 含义 |
|---|---|
通过 — 200(或其他有效 HTTP 状态码) | 源服务器正在响应 |
失败 — 000 或连接被拒绝 | 源服务器无法从当前网络访问 |
第 5 层:健康检查
Section titled “第 5 层:健康检查”健康检查监控后端可用性。对于 CSD 是可选的,但对于生产部署很有用。
HC-1:健康检查配置
Section titled “HC-1:健康检查配置”验证内容: 健康检查存在,并配置了正确的类型、路径、时间和阈值。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/xF5XC_HC_NAMEx" \ | jq '{ name: .metadata.name, type: (if .spec.http_health_check then "HTTP" elif .spec.tcp_health_check then "TCP" else "unknown" end), path: .spec.http_health_check.path, expected_status: .spec.http_health_check.expected_status_codes, timeout: .spec.timeout, interval: .spec.interval, unhealthy_threshold: .spec.unhealthy_threshold, healthy_threshold: .spec.healthy_threshold }'| 结果 | 含义 |
|---|---|
通过 — 显示 HTTP 类型,路径为 /,预期状态码为 200 | 健康检查配置正确 |
失败 — 404 响应 | 健康检查不存在(可能已跳过 — 参见 第 1 阶段第 1 步) |
HC-2:列出所有健康检查
Section titled “HC-2:列出所有健康检查”验证内容: 枚举命名空间中的所有健康检查,以验证命名和数量。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks" \ | jq -r ' ["NAME", "NAMESPACE", "DESCRIPTION"], (.items[] | [ .name, .namespace, (.description | if length == 0 then "—" else . end) ]) | @tsv' | column -t第 6 层:CSD 配置
Section titled “第 6 层:CSD 配置”CSD 必须在租户级别启用,并配置 JavaScript 注入标签。
CSD-1:租户 CSD 状态
Section titled “CSD-1:租户 CSD 状态”验证内容: CSD 已为租户配置并启用。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \ | jq '{isConfigured, isEnabled}'| 结果 | 含义 |
|---|---|
通过 — 两者均为 true | CSD 对此租户处于激活状态 |
失败 — isConfigured: false | CSD 未在租户级别启用 — 请联系 F5 XC 管理员 |
失败 — isEnabled: false | CSD 已配置但未激活 |
CSD-2:JS 注入标签
Section titled “CSD-2:JS 注入标签”验证内容: CSD JavaScript 注入标签已生成并准备好注入。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \ | jq '{has_script_tag: (.scriptTag | length > 0)}'| 结果 | 含义 |
|---|---|
通过 — has_script_tag: true | JS 注入标签已配置 |
失败 — has_script_tag: false | 无脚本标签 — 请验证 CSD 是否已启用且已注册受保护域名 |
CSD-3:JS 标签内容
Section titled “CSD-3:JS 标签内容”验证内容: 显示完整的脚本标签以供验证或手动注入。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \ | jq '.scriptTag'CSD-4:受保护域名注册
Section titled “CSD-4:受保护域名注册”验证内容: 根域已作为 CSD 受保护域名在租户上注册。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \ | jq '.items[] | {name, namespace, description}'| 结果 | 含义 |
|---|---|
通过 — 显示一个具有非空 name 的条目 | 域名已受保护 |
失败 — 条目的 name 和 namespace 字段为空 | 未注册受保护域名 — 参见 第 1 阶段第 6 步 |
CSD-5:实时 JS 注入验证
Section titled “CSD-5:实时 JS 注入验证”验证内容: CSD JavaScript 实际上正在注入到负载均衡器提供的页面响应中。
curl -s "http://xF5XC_DOMAINNAMEx/" \ | grep -oE '(zeronaught|shape)\.com[^"]*' | head -1| 结果 | 含义 |
|---|---|
通过 — 返回 zeronaught.com 或 shape.com URL 片段(如 zeronaught.com/__imp_apg__/js/...) | CSD JavaScript 正在注入到页面中 |
| 失败 — 空输出 | JS 未注入 — 检查 LB-3 和 CSD-1 |
第 7 层:流量验证
Section titled “第 7 层:流量验证”验证实时流量正在到达负载均衡器并被正确处理。
TV-1:请求数(过去 24 小时)
Section titled “TV-1:请求数(过去 24 小时)”验证内容: 流量正在到达负载均衡器。零结果意味着没有流量到达。
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "start_time": "'"$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-24H +%Y-%m-%dT%H:%M:%SZ)"'", "end_time": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'" }' \ "xF5XC_API_URLx/api/data/namespaces/xF5XC_NAMESPACEx/access_logs/aggregation" \ | jq '{total_requests: .total_hits}'| 结果 | 含义 |
|---|---|
通过 — total_requests 为非零字符串(如 "380") | 流量正在通过 LB |
失败 — "0" 或无数据 | 没有流量到达 LB — 检查 DNS-1 和 LB-1 |
TV-2:状态码分布
Section titled “TV-2:状态码分布”验证内容: 响应状态码的分布揭示错误模式。
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "start_time": "'"$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-24H +%Y-%m-%dT%H:%M:%SZ)"'", "end_time": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "sort": "DESCENDING", "limit": 100 }' \ "xF5XC_API_URLx/api/data/namespaces/xF5XC_NAMESPACEx/access_logs" \ | jq -r ' [.logs[] | fromjson | .rsp_code_class] | group_by(.) | map({class: .[0], count: length}) | sort_by(-.count) | ["STATUS_CLASS", "COUNT"], (.[] | [.class, .count]) | @tsv' | column -t健康站点的预期输出:
STATUS_CLASS COUNT2xx 82downstream_remote_disconnect 18| 结果 | 含义 |
|---|---|
通过 — 大多数为 2xx | 站点正在提供成功响应 |
警告 — 高 4xx 数量 | 客户端错误(错误的 URL、缺少资源) |
失败 — 高 5xx 数量 | 服务器错误 — 检查源服务器健康状况 |
downstream_remote_disconnect 类表示客户端在响应完成之前关闭了连接(常见于长轮询或 WebSocket 升级请求)。
TV-3:近期请求样本
Section titled “TV-3:近期请求样本”验证内容: 单个请求已正确记录并包含正确字段。
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "start_time": "'"$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ)"'", "end_time": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "sort": "DESCENDING", "limit": 10 }' \ "xF5XC_API_URLx/api/data/namespaces/xF5XC_NAMESPACEx/access_logs" \ | jq -r ' ["TIMESTAMP", "METHOD", "PATH", "STATUS", "SRC_IP"], (.logs[] | fromjson | [.["@timestamp"], .method, .req_path, .rsp_code, .src_ip]) | @tsv' | column -tTV-4:访问日志中的 CSD JS 注入
Section titled “TV-4:访问日志中的 CSD JS 注入”验证内容: 访问日志确认 CSD JavaScript 正在注入到响应中。
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d '{ "start_time": "'"$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ)"'", "end_time": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "sort": "DESCENDING", "limit": 20 }' \ "xF5XC_API_URLx/api/data/namespaces/xF5XC_NAMESPACEx/access_logs" \ | jq '[.logs[] | fromjson | select(.csd_js_injection == "true")] | length as $injected | {injected_count: $injected, total_sampled: 20}'| 结果 | 含义 |
|---|---|
通过 — injected_count > 0 | CSD JS 正在注入到页面响应中 |
失败 — injected_count: 0 | JS 未注入 — 检查 CSD-1 和 LB-3 |
TV-5:端到端连接性测试
Section titled “TV-5:端到端连接性测试”验证内容: 完整请求从客户端经 DNS、LB 和源服务器流转,并返回有效响应。
curl -sv "http://xF5XC_DOMAINNAMEx/" 2>&1 \ | grep -E 'Connected to|< HTTP|< content-type'| 结果 | 含义 |
|---|---|
| 通过 — 显示连接、HTTP 200 和内容类型 | 完整堆栈正常运行 |
| 失败 — 连接被拒绝或 DNS 错误 | 从 第 1 层:DNS 开始排查 |
第 8 层:CSD 遥测与域策略
Section titled “第 8 层:CSD 遥测与域策略”这些命令查询 CSD 控制台 仪表板、脚本列表、表单字段和网络视图中显示的相同数据。
TEL-1:脚本清单
Section titled “TEL-1:脚本清单”验证内容: CSD 正在检测并编目在受保护域上运行的脚本。
NOW=$(date +%s)START=$(( NOW - 604800 ))
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{ \"startTime\": \"${START}\", \"endTime\": \"${NOW}\" }" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \ | jq -r ' ["SCRIPT", "RISK", "STATUS", "FIELDS", "USERS"], (.scripts[] | [ (.script_name | if length > 50 then .[:47] + "..." else . end), .risk_level, .status, (.form_fields_read // 0), (.affected_users_count // 0) ]) | @tsv' | column -t| 结果 | 含义 |
|---|---|
| 通过 — 列出了带有风险级别的脚本 | CSD 正在主动监控脚本 |
| 失败 — 空数组 | 参见 故障排除:脚本数组为空 |
TEL-2:检测到的域名
Section titled “TEL-2:检测到的域名”验证内容: CSD 已检测到脚本来源域名并按状态对其分类。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{ summary: { action_needed: .domain_summary.actionNeededCount.count, mitigated: .domain_summary.mitigatedDomains.count, allowed: .domain_summary.allowedDomains.count, total: .domain_summary.totalDomains.count }, domains: [.domains_list[] | { domain: .domain, category: .category, status: .status, first_seen: (.firstSeenDate | tonumber | todate), latest_seen: (.latestSeenDate | tonumber | todate) }] }'| 结果 | 含义 |
|---|---|
通过 — total > 0 且列出了域名 | CSD 正在跟踪脚本域名 |
警告 — action_needed > 0 | 某些域名需要审查 |
| 失败 — 空响应 | 无遥测数据 — 检查 CSD-5 |
TEL-3:域策略状态
Section titled “TEL-3:域策略状态”验证内容: 显示允许与已缓解域名的分布,以及策略是否一致。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{ action_needed: .domain_summary.actionNeededCount.count, mitigated: .domain_summary.mitigatedDomains.count, allowed: .domain_summary.allowedDomains.count, total: .domain_summary.totalDomains.count, domains_needing_action: [.domains_list[] | select(.status == "AN") | .domain] }'| 结果 | 含义 |
|---|---|
通过 — action_needed: 0 | 所有域名已审查并分类 |
警告 — action_needed > 0 | domains_needing_action 中列出的域名需要审查 |
TEL-4:表单字段清单
Section titled “TEL-4:表单字段清单”验证内容: CSD 已检测到脚本正在读取的表单字段,并进行了敏感性分类。
NOW=$(date +%s)START=$(( NOW - 604800 ))
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/formFields?startTime=${START}&endTime=${NOW}" \ | jq -r ' ["FIELD", "SENSITIVITY", "SCRIPTS"], (.form_fields[] | [ .name, .analysis, (.scripts_count // 0) ]) | @tsv' | column -t| 结果 | 含义 |
|---|---|
| 通过 — 列出了带有敏感性的表单字段 | CSD 正在跟踪表单字段访问 |
| 信息 — 空数组 | 未检测到表单字段(若站点没有表单,属预期行为) |
TEL-5:脚本深度分析
Section titled “TEL-5:脚本深度分析”验证内容: 关于特定脚本的详细信息,包括风险、行为和网络交互。
首先从 TEL-1 获取脚本 ID,然后查询其详情:
SCRIPT_ID="your-script-id"
# 概览(风险级别、类型、来源域名)curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts/${SCRIPT_ID}/dashboard" \ | jq '{script_name, risk_level, type, source_domain, status}'
# 随时间变化的行为curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts/${SCRIPT_ID}/behaviors" \ | jq '.behaviors'
# 网络交互(脚本与之通信的域名)curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts/${SCRIPT_ID}/networkInteractions" \ | jq '.network_interactions'TEL-6:受影响用户
Section titled “TEL-6:受影响用户”验证内容: 列出受特定脚本影响的用户,显示暴露范围。
SCRIPT_ID="your-script-id"NOW=$(date +%s)START=$(( NOW - 604800 ))
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{ \"startTime\": \"${START}\", \"endTime\": \"${NOW}\" }" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts/${SCRIPT_ID}/affectedUsers" \ | jq -r ' ["IP_ADDRESS", "DEVICE_ID", "GEO", "CHANNEL", "USER_AGENT"], (.affected_users[] | [ .ip_address, (.device_id | if length > 12 then .[:12] + "..." else . end), .geolocation, .channel, (.user_agent | if length > 30 then .[:27] + "..." else . end) ]) | @tsv' | column -tTEL-7:按风险级别统计脚本数量
Section titled “TEL-7:按风险级别统计脚本数量”验证内容: 所有检测到的脚本的汇总风险分布。
NOW=$(date +%s)START=$(( NOW - 604800 ))
curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{ \"startTime\": \"${START}\", \"endTime\": \"${NOW}\" }" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \ | jq '[.scripts[] | .risk_level] | group_by(.) | map({risk_level: .[0], count: length}) | sort_by(-.count)'| 结果 | 含义 |
|---|---|
通过 — 全部为 No Risk | 未检测到风险脚本 |
警告 — 存在 Low Risk 或 High Risk | 在 TEL-5 中审查标记的脚本 |
TEL-8:遥测数据新鲜度
Section titled “TEL-8:遥测数据新鲜度”验证内容: CSD 遥测数据是最新的,确认主动监控正在进行。
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{ total_domains: .domain_summary.totalDomains.count, latest_update: (.domain_summary.totalDomains.lastUpdated // "unknown"), most_recent_domain: (.domains_list | sort_by(.latestSeenDate) | last | { domain: .domain, latest_seen: (.latestSeenDate | tonumber | todate) }) }'| 结果 | 含义 |
|---|---|
通过 — latest_seen 在过去 24 小时内 | 遥测正在主动收集数据 |
警告 — latest_seen 早于 24 小时前 | 流量可能已停止或 CSD 处理存在延迟 |
运行一条命令,检查每一层的所有关键健康指标并生成摘要表:
echo "=== CSD Verification Dashboard ==="echo ""
# 第 1 层:DNSDNS_A=$(dig +short xF5XC_DOMAINNAMEx A | head -1)DNS_ACME=$(dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME | head -1)
# 第 2-3 层:LB + TLSLB=$(curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http")LB_HTTPS=$(curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https")
LB_STATE=$(echo "$LB" | jq -r '.spec.state // "UNKNOWN"')CERT_STATE=$(echo "$LB_HTTPS" | jq -r '.spec.cert_state // "UNKNOWN"')CSD_ON_LB=$(echo "$LB" | jq -r 'if .spec.client_side_defense then "ENABLED" else "DISABLED" end')DOMAINS=$(echo "$LB" | jq -r '.spec.domains | join(", ")')ROUTE_POOL=$(echo "$LB" | jq -r '[.spec.default_route_pools[] | .pool.name] | join(", ")')
# 第 6 层:CSD 状态CSD=$(curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status")
CSD_CONFIGURED=$(echo "$CSD" | jq -r '.isConfigured // false')CSD_ENABLED=$(echo "$CSD" | jq -r '.isEnabled // false')
# 第 6 层:JS 配置JS_TAG=$(curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \ | jq -r 'if (.scriptTag | length) > 0 then "PRESENT" else "MISSING" end')
# 第 7 层:流量(过去 24 小时)TRAFFIC=$(curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{ \"start_time\": \"$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-24H +%Y-%m-%dT%H:%M:%SZ)\", \"end_time\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" }" \ "xF5XC_API_URLx/api/data/namespaces/xF5XC_NAMESPACEx/access_logs/aggregation" \ | jq -r '.total_hits // "0"')
printf "%-28s %s\n" "CHECK" "STATUS"printf "%-28s %s\n" "----------------------------" "----------------------------"printf "%-28s %s\n" "[DNS] A Record" "${DNS_A:-NOT_FOUND}"printf "%-28s %s\n" "[DNS] ACME CNAME" "${DNS_ACME:-NOT_FOUND}"printf "%-28s %s\n" "[TLS] Certificate" "$CERT_STATE"printf "%-28s %s\n" "[LB] State" "$LB_STATE"printf "%-28s %s\n" "[LB] Domains" "$DOMAINS"printf "%-28s %s\n" "[LB] Route Pool" "$ROUTE_POOL"printf "%-28s %s\n" "[LB] CSD on LB" "$CSD_ON_LB"printf "%-28s %s\n" "[CSD] Configured (tenant)" "$CSD_CONFIGURED"printf "%-28s %s\n" "[CSD] Enabled" "$CSD_ENABLED"printf "%-28s %s\n" "[CSD] JS Script Tag" "$JS_TAG"printf "%-28s %s\n" "[Traffic] Requests (24h)" "$TRAFFIC"访问日志字段参考
Section titled “访问日志字段参考”| 字段 | 类型 | 说明 |
|---|---|---|
@timestamp | string | 请求时间戳(ISO 8601)。注意 @ 前缀 — 在 jq 中使用 .["@timestamp"] 访问 |
method | string | HTTP 方法(GET、POST 等) |
req_path | string | 请求 URI 路径 |
rsp_code | string | HTTP 响应状态码(字符串形式,如 "200"、"404") |
rsp_code_class | string | 状态码类别(2xx、3xx、4xx、5xx 或 downstream_remote_disconnect) |
src_ip | string | 客户端源 IP 地址 |
dst_ip | string | 目标(VIP)IP 地址 |
domain | string | 请求 Host 头部值 |
user_agent | string | 客户端 User-Agent 字符串 |
rsp_size | string | 响应正文大小(字节,以字符串形式返回) |
req_size | string | 请求正文大小(字节,以字符串形式返回) |
duration_with_data_tx_delay | string | 请求总持续时间(秒,以字符串形式返回,如 "0.024219") |
csd_js_injection | string | CSD JavaScript 已注入时为 "true"(仅在激活时存在) |
CSD 遥测字段参考
Section titled “CSD 遥测字段参考”| 字段 | 端点 | 说明 |
|---|---|---|
isConfigured | status | CSD 在租户级别已启用 |
isEnabled | status | CSD 对此命名空间处于激活状态 |
scripts[] | scripts | 检测到的脚本对象数组 |
.script_name | scripts | JavaScript 文件的完整 URL |
.risk_level | scripts | 风险级别(No Risk、Low Risk、High Risk) |
.status | scripts | AN(需要操作)或 NA(无需操作) |
.form_fields_read | scripts | 脚本读取的表单字段数量 |
.affected_users_count | scripts | 受影响的唯一用户/会话数量 |
domain_summary | detected_domains | 按状态统计:.actionNeededCount.count、.mitigatedDomains.count、.allowedDomains.count、.totalDomains.count(每个均有 .count 和 .lastUpdated) |
domains_list[] | detected_domains | 检测到的域名对象数组,包含 .domain、.status、.category、.firstSeenDate、.latestSeenDate(epoch 秒数,以字符串形式表示) |
form_fields[] | formFields | 检测到的表单字段对象数组 |
.analysis | formFields | 敏感性分类(Sensitive、Not Sensitive) |
访问日志为零
Section titled “访问日志为零”如果 TV-1 返回 0:
-
检查 DNS 解析 — 验证域名是否解析到 LB VIP:
Terminal window dig +short xF5XC_DOMAINNAMEx A如果为空,则 DNS 未配置。参见 API 自动化 — 第 4 步。
-
检查 LB 状态 — 负载均衡器必须处于
VIRTUAL_HOST_READY状态:Terminal window curl -s \-H "Authorization: APIToken xF5XC_API_TOKENx" \"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \| jq '.spec.state' -
发送测试请求 — 生成流量以确认端到端连接性:
Terminal window curl -sv "http://xF5XC_DOMAINNAMEx/" 2>&1 | head -20查找成功的 HTTP 响应。仅在 HTTPS LB 证书有效时才使用
https://。
DNS 区域上禁用了托管记录
Section titled “DNS 区域上禁用了托管记录”如果 DNS-4 返回 false,即使 F5 XC 是权威 DNS 提供商,自动记录创建也被禁用。这是一种常见的配置错误,会导致 A 记录和 ACME CNAME 均缺失,从而阻止负载均衡器达到 VIRTUAL_HOST_READY 状态以及证书的签发。
要启用托管记录,请更新 DNS 区域配置以设置 allow_http_lb_managed_records: true。有关 API 调用,请参阅 API 自动化 — 选项 A:F5 XC 托管 DNS。
LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD
Section titled “LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD”负载均衡器正在等待指向其 VIP 的 DNS A 记录。有关详细解决步骤,请参阅 LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD。
证书卡在 PreDomainChallengePending
Section titled “证书卡在 PreDomainChallengePending”自动 TLS 证书需要 ACME 质询记录。具体方法取决于您的 DNS 提供商:
F5 XC 托管 DNS: 在 DNS 区域上启用 allow_http_lb_managed_records(DNS-4)。平台将在 x-ves-io-managed RR 集组中自动创建基于 TXT 的 ACME 质询记录。如果启用托管记录后证书仍然卡住,请删除并重新创建负载均衡器以触发新的证书请求。
外部 DNS: 在您的 DNS 提供商处创建 CNAME 记录:
_acme-challenge.xF5XC_DOMAINNAMEx CNAME *.autocerts.ves.volterra.io验证记录是否存在:
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAMEdig +short _acme-challenge.xF5XC_DOMAINNAMEx TXT如果两者均为空,则 ACME 记录未配置。记录就位后,证书签发需要 5–10 分钟。检查 LB 错误状态以获取具体的 ACME 验证错误:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \ | jq '[.status[]? | select(.virtual_host_status != null) | .virtual_host_status.error_description]'CSD isConfigured 为 false
Section titled “CSD isConfigured 为 false”CSD 必须由 F5 XC 管理员在租户级别启用。这是一个全租户范围的设置,无法通过命名空间 API 配置。请联系您的管理员以启用客户端防护。
脚本数组为空
Section titled “脚本数组为空”如果 TEL-1 返回空数组:
-
检查受保护域名 — CSD 仅监控已注册域名上的脚本:
Terminal window curl -s \-H "Authorization: APIToken xF5XC_API_TOKENx" \"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \| jq '.items[] | {name, namespace}' -
验证 JS 注入 — 确认 CSD 脚本标签正在注入到页面中:
Terminal window curl -s "http://xF5XC_DOMAINNAMEx/" | grep -oE '(zeronaught|shape)\.com[^"]*' | head -1如果无匹配,则 CSD JavaScript 未被注入。检查 LB 是否已启用
client_side_defense。 -
等待处理时间 — 在首次启用 CSD 或注册新的受保护域名后,脚本检测可能需要 5–15 分钟。在重新检查之前,请向站点生成流量并等待。
时间范围预设
Section titled “时间范围预设”| 周期 | Epoch 偏移量 | ISO 8601(Linux) | ISO 8601(macOS) |
|---|---|---|---|
| 1 小时 | $(( $(date +%s) - 3600 )) | date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ | date -u -v-1H +%Y-%m-%dT%H:%M:%SZ |
| 24 小时 | $(( $(date +%s) - 86400 )) | date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ | date -u -v-24H +%Y-%m-%dT%H:%M:%SZ |
| 7 天 | $(( $(date +%s) - 604800 )) | date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ | date -u -v-7d +%Y-%m-%dT%H:%M:%SZ |
| 30 天 | $(( $(date +%s) - 2592000 )) | date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ | date -u -v-30d +%Y-%m-%dT%H:%M:%SZ |
| 层 | 测试 | 覆盖内容 |
|---|---|---|
| 1. DNS 解析 | DNS-1 至 DNS-4 | A 记录、ACME CNAME、域名服务器权威性、托管记录 |
| 2. TLS 证书 | TLS-1 至 TLS-4 | 证书状态、证书详情、实时握手、ACME 目标 |
| 3. HTTP 负载均衡器 | LB-1 至 LB-6 | 状态、域名、CSD 标志、路由池、部署、摘要 |
| 4. 源池 | OP-1 至 OP-4 | 配置、TLS 模式、HC 关联、源连接性 |
| 5. 健康检查 | HC-1 至 HC-2 | HC 配置、列出所有 HC |
| 6. CSD 配置 | CSD-1 至 CSD-5 | 租户状态、JS 标签、受保护域名、实时注入 |
| 7. 流量验证 | TV-1 至 TV-5 | 请求数、状态码、样本、日志中的 JS、端到端测试 |
| 8. CSD 遥测 | TEL-1 至 TEL-8 | 脚本、域名、策略、表单字段、深度分析、用户、风险、新鲜度 |
| 诊断 | 端点 | 方法 | 时间格式 |
|---|---|---|---|
| 请求数 | /api/data/namespaces/\{ns\}/access_logs/aggregation | POST | ISO 8601 |
| 状态码 | /api/data/namespaces/\{ns\}/access_logs | POST | ISO 8601 |
| 近期请求 | /api/data/namespaces/\{ns\}/access_logs | POST | ISO 8601 |
| LB 状态 | /api/config/namespaces/\{ns\}/http_loadbalancers/\{name\} | GET | 无 |
| 源池 | /api/config/namespaces/\{ns\}/origin_pools/\{name\} | GET | 无 |
| 健康检查 | /api/config/namespaces/\{ns\}/healthchecks/\{name\} | GET | 无 |
| DNS 区域 | /api/config/dns/namespaces/system/dns_zones/\{zone\} | GET | 无 |
| CSD 状态 | /api/shape/csd/namespaces/\{ns\}/status | GET | 无 |
| JS 配置 | /api/shape/csd/namespaces/\{ns\}/js_configuration | GET | 无 |
| 受保护域名 | /api/shape/csd/namespaces/\{ns\}/protected_domains | GET | 无 |
| 脚本列表 | /api/shape/csd/namespaces/\{ns\}/scripts | POST | Epoch 秒数 |
| 检测到的域名 | /api/shape/csd/namespaces/\{ns\}/detected_domains | GET | 无 |
| 表单字段 | /api/shape/csd/namespaces/\{ns\}/formFields | GET | Epoch 秒数(查询参数) |
| 脚本详情 | /api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/dashboard | GET | 无 |
| 脚本行为 | /api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/behaviors | GET | 无 |
| 脚本网络 | /api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/networkInteractions | GET | 无 |
| 受影响用户 | /api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/affectedUsers | POST | Epoch 秒数 |