跳到內容

診斷與驗證

本頁面提供一套分層 UAT 驗證矩陣,用於端對端驗證您的用戶端防禦(Client-Side Defense)部署。每個測試案例均遵循基礎架構依賴鏈——從 DNS 解析到 CSD 遙測——讓您能夠系統性地確認每個元件均正常運作。

這些指令是 CSD 主控台操作說明API 對應版本——當您需要從終端機進行驗證、自動化監控,或在不使用 UI 的情況下展示 CSD 功能時,請使用這些指令。

API 自動化 — 環境設定 所述,設定您的環境變數:

Terminal window
set -a && source .env && set +a

以下所有指令均使用 xTOKENx 佔位符格式。請以您的環境變數($F5XC_API_TOKEN$F5XC_NAMESPACE 等)替換,或使用頁面頂端的互動式表單。

許多 CSD 端點需要 epoch 時間戳記(自 Unix epoch 起的秒數)。以下單行指令可計算常見範圍的起始/結束時間。

跨平台(macOS + Linux):

Terminal window
# 目前時間(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 ))

以下每個測試均遵循此結構:

欄位說明
測試 ID層級編號 + 序號(例如 DNS-1、TLS-2)
驗證內容所驗證的特定基礎架構事實
指令可直接執行的 curldig 指令
通過 / 失敗健康與不健康狀態的預期輸出
修復相關設定或疑難排解章節的連結

DNS 是基礎——若網域無法解析至負載平衡器 VIP,其他一切均無法運作。

驗證內容: 網域解析至負載平衡器 VIP IP 位址。

Terminal window
dig +short xF5XC_DOMAINNAMEx A
結果含義
通過 — 回傳 VIP IP(例如 72.19.3.185網域解析至 LB 虛擬 IP
失敗 — 回應為空DNS A 記錄未設定

修復: API 自動化 — 步驟 4:設定 DNS

驗證內容: ACME 驗證記錄已存在,可自動佈建 TLS 憑證。

Terminal window
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
dig +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

驗證內容: 確認 F5 XC 是否為根網域的權威 DNS 提供者。

Terminal window
dig +short NS xF5XC_ROOT_DOMAINx
結果含義
包含 ns1.f5clouddns.comns2.f5clouddns.comF5 XC 受管 DNS — 記錄可自動建立
其他名稱伺服器外部 DNS — 記錄必須手動建立

修復: API 自動化 — 偵測 DNS 授權

驗證內容: F5 XC DNS 區域允許自動為負載平衡器建立記錄(僅限 F5 XC 受管 DNS)。

Terminal window
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 記錄
失敗falsenull受管記錄已停用;請透過區域更新加以啟用

修復: API 自動化 — 選項 A:F5 XC 受管 DNS


DNS 解析成功後,負載平衡器必須具備有效的 TLS 憑證。

驗證內容: HTTPS LB 上的自動 TLS 憑證已成功簽發。

Terminal window
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 不受影響。

驗證內容: 憑證涵蓋預期網域並顯示到期資訊。僅適用於 HTTPS LB。

Terminal window
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_infonull 或空白憑證尚未佈建

驗證內容: TLS 憑證有效且可從用戶端完成交握。僅在 HTTPS LB 具有有效憑證時適用。

Terminal window
curl -sv "https://xF5XC_DOMAINNAMEx/" 2>&1 \
| grep -E 'SSL connection|subject:|expire date:|issuer:'
結果含義
通過 — 顯示 SSL connection using TLSv1.3、有效的主體與到期日端對端 TLS 正常運作
失敗 — 連線被拒或憑證錯誤請檢查 DNS 解析和憑證狀態;若受速率限制,請改用 HTTP

驗證內容: HTTPS 負載平衡器回報正確的 ACME 目標,供憑證驗證使用。

Terminal window
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_ipacme_target 均已填入可依這些值驗證 DNS 記錄
失敗 — 值為 nullLB 可能未設定 https_auto_cert

負載平衡器必須處於就緒狀態且設定正確。

驗證內容: HTTP 負載平衡器(主要)已完全運作並接受流量。

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'
結果含義
通過"VIRTUAL_HOST_READY"LB 正常運作
失敗"VIRTUAL_HOST_PENDING_A_RECORD"DNS A 記錄未設定 — 請參閱 DNS-1

修復: LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD

驗證內容: HTTP 負載平衡器已設定正確的網域。

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.domains'
結果含義
通過 — 陣列包含您的 FQDN(例如 ["app.example.com"]LB 已設定預期網域
失敗 — 網域缺失或錯誤請使用正確的網域更新 LB 規格

驗證內容: 負載平衡器上已啟用用戶端防禦,並設定正確的 JS 注入策略。

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 '{
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_pagesCSD 已啟用並在所有頁面注入 JS
失敗csd_enabled: falseLB 未設定 CSD

修復: API 參考 — 在負載平衡器上啟用 CSD

驗證內容: 負載平衡器參照正確的來源集區,並具備預期的權重與優先順序。

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.default_route_pools[] | {
pool: .pool.name,
namespace: .pool.namespace,
weight: .weight,
priority: .priority
}'
結果含義
通過 — 顯示您的來源集區名稱及權重/優先順序LB 正在路由至正確的後端
失敗 — 集區為空或錯誤請更新 LB 的 default_route_pools 設定

驗證內容: 負載平衡器已部署,並在所有站點回報健康狀況。

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 '{
state: .spec.state,
dns_info: .spec.dns_info,
host_name: .spec.host_name
}'
結果含義
通過stateVIRTUAL_HOST_READYdns_info 已填入LB 已完整部署且 VIP 已指派
失敗 — 待處理狀態或 dns_info 為空DNS 或憑證問題阻礙部署

驗證內容: 兩個 LB 設定的全面快照,供除錯使用。

HTTP LB(主要):

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 '{
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(次要 — 包含憑證狀態):

Terminal window
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]
}'

來源集區定義了負載平衡器將流量路由至的後端伺服器。

驗證內容: 來源集區已存在,並具備正確的後端伺服器、連接埠與 LB 演算法。

Terminal window
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 或值錯誤來源集區缺失或設定錯誤

修復: API 自動化 — 步驟 2:建立來源集區

驗證內容: 確認 LB 與來源伺服器之間的連線是否設定了 TLS。

Terminal window
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 連線至來源

驗證內容: 來源集區已連結正確的健康檢查(如適用)。

Terminal window
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 不要求健康檢查)
失敗 — 預期有健康檢查但陣列為空建立時未找到健康檢查 — 請參閱 健康檢查未連結至來源集區

驗證內容: 來源伺服器可從用戶端側連線(不測試 LB 至來源的路徑)。

Terminal window
curl -s -o /dev/null -w '%{http_code}' \
"http://xF5XC_ORIGIN_IPx:xF5XC_ORIGIN_PORTx/"
結果含義
通過200(或其他有效的 HTTP 代碼)來源伺服器正在回應
失敗000 或連線被拒來源伺服器無法從此網路連線

健康檢查用於監控後端可用性。對 CSD 而言為選用,但對正式環境部署很有用。

驗證內容: 健康檢查已存在,並具備正確的類型、路徑、時機與閾值。

Terminal window
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

驗證內容: 列舉命名空間中的所有健康檢查,以驗證命名與數量。

Terminal window
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

CSD 必須在租戶層級啟用,並已設定 JavaScript 注入標籤。

驗證內容: CSD 已為租戶設定並啟用。

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \
| jq '{isConfigured, isEnabled}'
結果含義
通過 — 兩者均為 trueCSD 對此租戶有效
失敗isConfigured: falseCSD 未在租戶層級啟用 — 請聯絡 F5 XC 管理員
失敗isEnabled: falseCSD 已設定但未啟用

驗證內容: CSD JavaScript 注入標籤已產生且可供注入。

Terminal window
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: trueJS 注入標籤已設定
失敗has_script_tag: false無指令碼標籤 — 請驗證 CSD 是否已啟用且已註冊受保護網域

驗證內容: 顯示完整的指令碼標籤,供驗證或手動注入使用。

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \
| jq '.scriptTag'

驗證內容: 根網域已在租戶上註冊為 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, description}'
結果含義
通過 — 顯示具有非空 name 的項目網域受到保護
失敗 — 項目的 namenamespace 欄位均為空未註冊受保護網域 — 請參閱 第 1 階段步驟 6

驗證內容: CSD JavaScript 確實被注入到負載平衡器提供的頁面回應中。

Terminal window
curl -s "http://xF5XC_DOMAINNAMEx/" \
| grep -oE '(zeronaught|shape)\.com[^"]*' | head -1
結果含義
通過 — 回傳 zeronaught.comshape.com URL 片段(例如 zeronaught.com/__imp_apg__/js/...CSD JavaScript 正被注入到頁面中
失敗 — 輸出為空JS 未注入 — 請檢查 LB-3CSD-1

驗證即時流量是否到達負載平衡器並被正確處理。

驗證內容: 流量正在到達負載平衡器。零結果表示沒有流量到達。

Terminal window
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-1LB-1

驗證內容: 回應狀態碼的分布可揭示錯誤模式。

Terminal window
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 COUNT
2xx 82
downstream_remote_disconnect 18
結果含義
通過 — 大多數為 2xx站台正在提供成功回應
警告4xx 數量偏高用戶端錯誤(錯誤 URL、缺少資源)
失敗5xx 數量偏高伺服器錯誤 — 請檢查來源伺服器健康狀態

downstream_remote_disconnect 類別表示用戶端在回應完成前關閉了連線(長輪詢或 WebSocket 升級請求常見此情況)。

驗證內容: 個別請求正在以正確欄位記錄日誌。

Terminal window
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 -t

驗證內容: 存取日誌確認 CSD JavaScript 正被注入到回應中。

Terminal window
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 > 0CSD JS 正被注入到頁面回應中
失敗injected_count: 0JS 未注入 — 請檢查 CSD-1LB-3

驗證內容: 完整請求從用戶端流經 DNS、LB 和來源,並回傳有效回應。

Terminal window
curl -sv "http://xF5XC_DOMAINNAMEx/" 2>&1 \
| grep -E 'Connected to|< HTTP|< content-type'
結果含義
通過 — 顯示連線、HTTP 200 和 content-type完整堆疊正常運作
失敗 — 連線被拒或 DNS 錯誤請從 第 1 層:DNS 開始除錯

這些指令查詢與 CSD 主控台 儀表板、指令碼清單、表單欄位和網路視圖中顯示的相同資料。

驗證內容: CSD 正在偵測並建立受保護網域上執行的指令碼目錄。

Terminal window
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 正在主動監控指令碼
失敗 — 空陣列請參閱 疑難排解:空的指令碼陣列

驗證內容: CSD 已偵測到指令碼來源網域並依狀態分類。

Terminal window
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

驗證內容: 顯示已允許與已緩解網域的分布,以及策略是否一致。

Terminal window
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 > 0domains_needing_action 中列出的網域需要審查

驗證內容: CSD 已偵測到指令碼正在讀取的表單欄位,並附有敏感度分類。

Terminal window
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-1 取得指令碼 ID,然後查詢其詳細資訊:

Terminal window
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'

驗證內容: 列出受特定指令碼影響的使用者,顯示暴露範圍。

Terminal window
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 -t

驗證內容: 所有已偵測指令碼的風險分布彙總。

Terminal window
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 RiskHigh Risk請在 TEL-5 中審查標記的指令碼

驗證內容: CSD 遙測資料為最新,確認監控正在運作。

Terminal window
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 處理有延遲

執行單一指令,檢查所有層級的關鍵健康指標並產生摘要表:

Terminal window
echo "=== CSD 驗證儀表板 ==="
echo ""
# 第 1 層:DNS
DNS_A=$(dig +short xF5XC_DOMAINNAMEx A | head -1)
DNS_ACME=$(dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME | head -1)
# 第 2-3 層:LB + TLS
LB=$(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"

欄位類型說明
@timestamp字串請求時間戳記(ISO 8601)。請注意 @ 前綴——在 jq 中使用 .["@timestamp"] 存取
method字串HTTP 方法(GET、POST 等)
req_path字串請求 URI 路徑
rsp_code字串HTTP 回應狀態碼(字串形式,例如 "200""404"
rsp_code_class字串狀態碼類別(2xx3xx4xx5xxdownstream_remote_disconnect
src_ip字串用戶端來源 IP 位址
dst_ip字串目的地(VIP)IP 位址
domain字串請求 Host 標頭值
user_agent字串用戶端 User-Agent 字串
rsp_size字串回應本文大小(位元組,以字串回傳)
req_size字串請求本文大小(位元組,以字串回傳)
duration_with_data_tx_delay字串請求總時長(秒,以字串回傳,例如 "0.024219"
csd_js_injection字串當 CSD JavaScript 已注入時為 "true"(僅在啟用時出現)
欄位端點說明
isConfiguredstatusCSD 在租戶層級已啟用
isEnabledstatusCSD 對此命名空間有效
scripts[]scripts已偵測指令碼物件的陣列
.script_namescriptsJavaScript 檔案的完整 URL
.risk_levelscripts風險等級(No Risk、Low Risk、High Risk)
.statusscriptsAN(需要採取行動)或 NA(無需採取行動)
.form_fields_readscripts指令碼讀取的表單欄位數量
.affected_users_countscripts受影響的唯一使用者/工作階段數量
domain_summarydetected_domains依狀態的數量:.actionNeededCount.count.mitigatedDomains.count.allowedDomains.count.totalDomains.count(各含 .count.lastUpdated
domains_list[]detected_domains已偵測網域物件的陣列,包含 .domain.status.category.firstSeenDate.latestSeenDate(epoch 秒數,以字串表示)
form_fields[]formFields已偵測表單欄位物件的陣列
.analysisformFields敏感度分類(Sensitive、Not Sensitive)

TV-1 回傳 0

  1. 檢查 DNS 解析 — 驗證網域是否解析至 LB VIP:

    Terminal window
    dig +short xF5XC_DOMAINNAMEx A

    若為空,表示 DNS 未設定。請參閱 API 自動化 — 步驟 4

  2. 檢查 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'
  3. 發送測試請求 — 產生流量以確認端對端連線:

    Terminal window
    curl -sv "http://xF5XC_DOMAINNAMEx/" 2>&1 | head -20

    尋找成功的 HTTP 回應。僅在 HTTPS LB 憑證有效時才使用 https://

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

負載平衡器正在等待指向其 VIP 的 DNS A 記錄。詳細解決步驟請參閱 LB 卡在 VIRTUAL_HOST_PENDING_A_RECORD

自動 TLS 憑證需要 ACME 驗證記錄。方法取決於您的 DNS 提供者:

F5 XC 受管 DNS: 在 DNS 區域上啟用 allow_http_lb_managed_recordsDNS-4)。平台會在 x-ves-io-managed RR 集群組中自動建立 TXT 型 ACME 驗證記錄。若啟用受管記錄後憑證仍卡住,請刪除並重新建立負載平衡器以觸發全新的憑證請求。

外部 DNS: 在您的 DNS 提供者處建立 CNAME 記錄:

_acme-challenge.xF5XC_DOMAINNAMEx CNAME *.autocerts.ves.volterra.io

驗證記錄是否存在:

Terminal window
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
dig +short _acme-challenge.xF5XC_DOMAINNAMEx TXT

若兩者均為空,表示 ACME 記錄未設定。記錄就位後,憑證佈建需 5–10 分鐘。請檢查 LB 錯誤狀態以取得特定的 ACME 驗證錯誤:

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 '[.status[]? | select(.virtual_host_status != null) | .virtual_host_status.error_description]'

CSD 必須由 F5 XC 管理員在租戶層級啟用。這是整個租戶的設定,無法透過命名空間 API 設定。請聯絡您的管理員以啟用用戶端防禦。

TEL-1 回傳空陣列:

  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}'
  2. 驗證 JS 注入 — 確認 CSD 指令碼標籤正被注入到頁面中:

    Terminal window
    curl -s "http://xF5XC_DOMAINNAMEx/" | grep -oE '(zeronaught|shape)\.com[^"]*' | head -1

    若無符合結果,表示 CSD JavaScript 未被注入。請確認 LB 已啟用 client_side_defense

  3. 等待處理時間 — 首次啟用 CSD 或註冊新的受保護網域後,指令碼偵測可能需要 5–15 分鐘。請向站台產生流量並等待後再重新檢查。

期間Epoch 偏移量ISO 8601(Linux)ISO 8601(macOS)
1 小時$(( $(date +%s) - 3600 ))date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZdate -u -v-1H +%Y-%m-%dT%H:%M:%SZ
24 小時$(( $(date +%s) - 86400 ))date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZdate -u -v-24H +%Y-%m-%dT%H:%M:%SZ
7 天$(( $(date +%s) - 604800 ))date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZdate -u -v-7d +%Y-%m-%dT%H:%M:%SZ
30 天$(( $(date +%s) - 2592000 ))date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZdate -u -v-30d +%Y-%m-%dT%H:%M:%SZ
層級測試項目涵蓋內容
1. DNS 解析DNS-1 至 DNS-4A 記錄、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-2HC 設定、列出所有 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/aggregationPOSTISO 8601
狀態碼/api/data/namespaces/\{ns\}/access_logsPOSTISO 8601
近期請求/api/data/namespaces/\{ns\}/access_logsPOSTISO 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\}/statusGET
JS 設定/api/shape/csd/namespaces/\{ns\}/js_configurationGET
受保護網域/api/shape/csd/namespaces/\{ns\}/protected_domainsGET
指令碼清單/api/shape/csd/namespaces/\{ns\}/scriptsPOSTEpoch 秒數
已偵測網域/api/shape/csd/namespaces/\{ns\}/detected_domainsGET
表單欄位/api/shape/csd/namespaces/\{ns\}/formFieldsGETEpoch 秒數(查詢參數)
指令碼詳細資訊/api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/dashboardGET
指令碼行為/api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/behaviorsGET
指令碼網路/api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/networkInteractionsGET
受影響使用者/api/shape/csd/namespaces/\{ns\}/scripts/\{id\}/affectedUsersPOSTEpoch 秒數