コンテンツにスキップ

診断と検証

このページでは、クライアントサイド防御のデプロイメントをエンドツーエンドで検証するための階層型 UAT 検証マトリクスを提供します。各テストケースは、DNS 解決から CSD テレメトリまでのインフラ依存関係チェーンに従っており、すべてのコンポーネントが正常に動作していることを体系的に証明できます。

これらのコマンドは、CSD コンソールウォークスルーAPI 相当です。ターミナルから検証する必要がある場合、モニタリングを自動化する場合、または UI を使用せずに CSD の機能を実証する場合に使用してください。

API 自動化 — 環境設定に記載されているように、環境変数を設定してください:

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

以下のすべてのコマンドは xTOKENx プレースホルダー形式を使用しています。環境変数($F5XC_API_TOKEN$F5XC_NAMESPACE など)に置き換えるか、ページ上部のインタラクティブフォームを使用してください。

多くの CSD エンドポイントはエポックタイムスタンプ(Unix エポックからの秒数)を必要とします。これらのワンライナーは、一般的な範囲の開始/終了時刻を計算します。

クロスプラットフォーム(macOS + Linux):

Terminal window
# 現在時刻をエポック秒として取得
NOW=$(date +%s)
# 1時間前
START_1H=$(( NOW - 3600 ))
# 24時間前
START_24H=$(( NOW - 86400 ))
# 7日前
START_7D=$(( NOW - 604800 ))
# 30日前
START_30D=$(( NOW - 2592000 ))
プリセット秒数シェル式
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レイヤー番号 + 連番 ID(例:DNS-1、TLS-2)
証明すること検証される特定のインフラ上の事実
コマンドすぐに実行できる curl または dig コマンド
合格 / 不合格正常状態と異常状態の期待される出力
修正方法関連するセットアップまたはトラブルシューティングセクションへのリンク

DNS は基盤です — ドメインがロードバランサーの VIP に解決されない場合、他のすべてが機能しません。

証明すること: ドメインがロードバランサーの VIP IP アドレスに解決される。

Terminal window
dig +short xF5XC_DOMAINNAMEx A
結果意味
合格 — VIP IP が返される(例:72.19.3.185ドメインが LB 仮想 IP に解決される
不合格 — 空のレスポンスDNS A レコードが設定されていない

修正方法: API 自動化 — ステップ 4: DNS の設定

証明すること: TLS 証明書の自動プロビジョニングのために ACME チャレンジレコードが存在する。

Terminal window
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
dig +short _acme-challenge.xF5XC_DOMAINNAMEx TXT
結果意味
合格*.autocerts.ves.volterra.io. への CNAME(外部 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.com および ns2.f5clouddns.com を含むF5 XC 管理 DNS — レコードを自動作成可能
その他のネームサーバー外部 DNS — レコードを手動で作成する必要がある

修正方法: API 自動化 — DNS 権威の検出

DNS-4: F5 XC 管理レコードの有効化

Section titled “DNS-4: F5 XC 管理レコードの有効化”

証明すること: 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 レコードを自動作成する
不合格false または null管理レコードが無効;ゾーン更新で有効にする

修正方法: 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_infodns_records と証明書メタデータが含まれる証明書プロビジョニングの詳細が利用可能
不合格auto_cert_infonull または空証明書がまだプロビジョニングされていない

TLS-3: ライブ TLS ハンドシェイク

Section titled “TLS-3: ライブ TLS ハンドシェイク”

証明すること: 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、有効な subject と有効期限が表示されるエンドツーエンドの TLS が機能している
不合格 — 接続拒否または証明書エラーDNS 解決と証明書の状態を確認;レート制限の場合は HTTP を使用する

TLS-4: LB からの ACME レコードターゲット

Section titled “TLS-4: LB からの ACME レコードターゲット”

証明すること: 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 が設定されていない可能性がある

レイヤー 3: HTTP ロードバランサー

Section titled “レイヤー 3: HTTP ロードバランサー”

ロードバランサーは準備完了状態にあり、正しく設定されている必要があります。

証明すること: 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_pages が含まれるCSD がすべてのページへの 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 設定を更新する

LB-5: デプロイメントステータス(サイトごとの条件)

Section titled “LB-5: デプロイメントステータス(サイトごとの条件)”

証明すること: ロードバランサーがデプロイされ、すべてのサイトで正常な状態を報告している。

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 でオリジンサーバーに接続する

OP-3: ヘルスチェックの関連付け

Section titled “OP-3: ヘルスチェックの関連付け”

証明すること: オリジンプールに正しいヘルスチェックがリンクされている(該当する場合)。

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'
結果意味
合格 — ヘルスチェック参照(名前、ネームスペース、種別)を含む配列ヘルスチェックがリンクされている
OK — 空の配列 []ヘルスチェックなし(許容可能 — 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
}'
結果意味
合格 — パス / と期待される 200 を持つ HTTP タイプが表示されるヘルスチェックが正しく設定されている
不合格404 レスポンスヘルスチェックが存在しない(スキップされた可能性あり — フェーズ 1 ステップ 1 を参照)

HC-2: すべてのヘルスチェックの一覧

Section titled “HC-2: すべてのヘルスチェックの一覧”

証明すること: ネームスペース内のすべてのヘルスチェックを列挙し、名前と数を確認する。

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: falseテナントレベルで CSD が有効になっていない — 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-5: ライブ JS インジェクション検証

Section titled “CSD-5: ライブ JS インジェクション検証”

証明すること: CSD JavaScript がロードバランサーによって提供されるページレスポンスに実際にインジェクションされている。

Terminal window
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-3CSD-1 を確認する

ライブトラフィックがロードバランサーに到達し、正しく処理されていることを確認します。

TV-1: リクエスト数(過去 24 時間)

Section titled “TV-1: リクエスト数(過去 24 時間)”

証明すること: トラフィックがロードバランサーに到達している。ゼロの結果はトラフィックが届いていないことを意味します。

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 アップグレードリクエストでよく見られます)。

TV-3: 最近のリクエストサンプル

Section titled “TV-3: 最近のリクエストサンプル”

証明すること: 個別のリクエストが正しいフィールドでログに記録されている。

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

TV-4: アクセスログ内の CSD JS インジェクション

Section titled “TV-4: アクセスログ内の CSD JS インジェクション”

証明すること: アクセスログが 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 を確認する

TV-5: エンドツーエンド接続テスト

Section titled “TV-5: エンドツーエンド接続テスト”

証明すること: クライアントから DNS、LB、オリジンサーバーを通じて完全なリクエストが流れ、有効なレスポンスが返される。

Terminal window
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 コンソールダッシュボード、スクリプトリスト、フォームフィールド、ネットワークビューに表示されるのと同じデータを照会します。

証明すること: 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 に一覧表示されたドメインのレビューが必要

TEL-4: フォームフィールドインベントリ

Section titled “TEL-4: フォームフィールドインベントリ”

証明すること: 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

TEL-7: リスクレベル別スクリプト数

Section titled “TEL-7: リスクレベル別スクリプト数”

証明すること: 検出されたすべてのスクリプトのリスク分布を集計する。

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 Risk または High 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 Verification Dashboard ==="
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"

アクセスログフィールドリファレンス

Section titled “アクセスログフィールドリファレンス”
フィールドタイプ説明
@timestampstringリクエストタイムスタンプ(ISO 8601)。@ プレフィックスに注意 — jq では .["@timestamp"] でアクセス
methodstringHTTP メソッド(GET、POST など)
req_pathstringリクエスト URI パス
rsp_codestring文字列としての HTTP レスポンスステータスコード(例:"200""404"
rsp_code_classstringステータスコードクラス(2xx3xx4xx5xx、または downstream_remote_disconnect
src_ipstringクライアントのソース IP アドレス
dst_ipstring宛先(VIP)IP アドレス
domainstringリクエストの Host ヘッダー値
user_agentstringクライアントの User-Agent 文字列
rsp_sizestringレスポンスボディサイズ(バイト単位、文字列として返される)
req_sizestringリクエストボディサイズ(バイト単位、文字列として返される)
duration_with_data_tx_delaystringリクエストの総時間(秒単位、文字列として返される、例:"0.024219"
csd_js_injectionstringCSD JavaScript がインジェクションされた場合は "true"(アクティブな場合のみ存在)

CSD テレメトリフィールドリファレンス

Section titled “CSD テレメトリフィールドリファレンス”
フィールドエンドポイント説明
isConfiguredstatusテナントレベルで CSD が有効
isEnabledstatusこのネームスペースで CSD がアクティブ
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(文字列としてのエポック秒)を持つ検出されたドメインオブジェクトの配列
form_fields[]formFields検出されたフォームフィールドオブジェクトの配列
.analysisformFields感度分類(Sensitive、Not Sensitive)

TV-10 を返す場合:

  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:// は HTTPS LB 証明書が有効な場合にのみ使用してください。

DNS ゾーンで管理レコードが無効

Section titled “DNS ゾーンで管理レコードが無効”

DNS-4false を返す場合、F5 XC が権威 DNS プロバイダーであるにもかかわらず、自動レコード作成が無効になっています。これは、A レコードと ACME CNAME の両方が欠落する一般的な設定ミスで、ロードバランサーが VIRTUAL_HOST_READY に到達できず、証明書が発行されないという問題を引き起こします。

管理レコードを有効にするには、allow_http_lb_managed_records: true を設定するように DNS ゾーン設定を更新してください。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

レコードが存在することを確認します:

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

両方が空の場合、ACME レコードが設定されていません。証明書のプロビジョニングは、レコードが設定されてから 5〜10 分かかります。特定の ACME 検証エラーについて 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 '[.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 分かかる場合があります。サイトへのトラフィックを生成し、再確認する前に待機してください。

期間エポックオフセット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、E2E テスト
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\}/scriptsPOSTエポック秒
検出されたドメイン/api/shape/csd/namespaces/\{ns\}/detected_domainsGETなし
フォームフィールド/api/shape/csd/namespaces/\{ns\}/formFieldsGETエポック秒(クエリパラメーター)
スクリプト詳細/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\}/affectedUsersPOSTエポック秒