Zum Inhalt springen

Demo

Diese Anleitung führt Sie durch eine vollständige Clientseitige Abwehr-Übung auf F5 Distributed Cloud mithilfe der API — strukturiert in vier Phasen, die ein KI-Assistent oder ein menschlicher Operator von Anfang bis Ende ausführen kann. Jeder Schritt enthält einen sofort ausführbaren curl-Befehl mit Platzhalterwerten, die Sie über das Formular am Anfang der Seite, eine .env-Datei oder ein beliebiges Automatisierungswerkzeug anpassen können.

PhaseZielSchritte
Phase 1 — AufbauenDie vollständige CSD-Infrastruktur bereitstellen und validierenSchritte 1–7
Phase 2 — AngreifenSimulierten Angriffsdatenverkehr erzeugen und bestätigen, dass CSD diesen erkannt hatSchritte 8–9
Phase 3 — AbwehrenNachweis vor/nach der Abwehr — Angriff ausführen, Abwehrmaßnahmen anwenden, Angriff wiederholen, vergleichenSchritte 1–6
Phase 4 — AbbauenAlle Bereitstellungsobjekte nach expliziter Bestätigung entfernenAbbau

Bevor Sie Phase 1 starten, vergewissern Sie sich, dass die Umgebung sauber ist. Führen Sie diese API-Prüfungen durch, um festzustellen, ob noch Objekte aus einem vorherigen Durchlauf vorhanden sind:

Terminal-Fenster
# Alle Phase-1-Objekte prüfen und den Umgebungsstatus ermitteln
HTTP_LB=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http")
HTTPS_LB=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https")
ORIGIN=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx")
HC=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/xF5XC_HC_NAMEx")
PD_COUNT=$(curl -s -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq '[.items // [] | .[] | select(.metadata.name != null)] | length')
MD_COUNT=$(curl -s -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains" \
| jq '[.items // [] | .[] | select(.metadata.name != null)] | length')
# Falls HTTPS LB vorhanden, Body abrufen, um Skeleton-Zustand zu erkennen
HTTPS_IS_SKELETON="false"
if [ "$HTTPS_LB" = "200" ]; then
HTTPS_LB_BODY=$(curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https")
HTTPS_IS_SKELETON=$(echo "$HTTPS_LB_BODY" | jq '
((.spec.default_route_pools // []) | length == 0) and
(.spec.client_side_defense == null)
')
fi
# Deterministischen Umgebungsstatus berechnen
jq -n \
--argjson http_lb "$HTTP_LB" \
--argjson https_lb "$HTTPS_LB" \
--argjson origin "$ORIGIN" \
--argjson hc "$HC" \
--argjson pd "$PD_COUNT" \
--argjson md "$MD_COUNT" \
--argjson https_skeleton "$HTTPS_IS_SKELETON" \
'{
objects: [
{ name: "http_lb", http_code: $http_lb, exists: ($http_lb == 200) },
{ name: "https_lb", http_code: $https_lb, exists: ($https_lb == 200), is_skeleton: $https_skeleton },
{ name: "origin_pool", http_code: $origin, exists: ($origin == 200) },
{ name: "healthcheck", http_code: $hc, exists: ($hc == 200) },
{ name: "protected_domains", count: $pd, exists: ($pd > 0) },
{ name: "mitigated_domains", count: $md, exists: ($md > 0) }
],
any_infra_exists: ($http_lb == 200 or ($https_lb == 200 and ($https_skeleton | not)) or $origin == 200 or $hc == 200),
any_csd_exists: ($pd > 0 or $md > 0),
status: (
if ($http_lb == 404 and $https_lb == 404 and $origin == 404 and $hc == 404 and $pd == 0 and $md == 0) then "CLEAN"
elif ($https_lb == 200 and $https_skeleton and $http_lb == 404 and $origin == 404 and $hc == 404 and $pd == 0 and $md == 0) then "HTTPS_SKELETON"
elif ($http_lb == 200 and $origin == 200) then "ALL_EXIST"
elif ($http_lb == 200 or ($https_lb == 200 and ($https_skeleton | not)) or $origin == 200 or $hc == 200) then "TEARDOWN_NEEDED"
elif ($md > 0 and $http_lb == 404 and ($https_lb == 404 or ($https_lb == 200 and $https_skeleton)) and $origin == 404 and $hc == 404) then "MITIGATIONS_ONLY"
else "TEARDOWN_NEEDED"
end
),
action: (
if ($http_lb == 404 and $https_lb == 404 and $origin == 404 and $hc == 404 and $pd == 0 and $md == 0) then "Proceed to Phase 1"
elif ($https_lb == 200 and $https_skeleton and $http_lb == 404 and $origin == 404 and $hc == 404 and $pd == 0 and $md == 0) then "Proceed to Phase 1 (HTTPS LB skeleton will be restored via PUT)"
elif ($http_lb == 200 and $origin == 200) then "All Phase 1 objects exist — verify health, optionally skip to Phase 2"
elif ($http_lb == 200 or ($https_lb == 200 and ($https_skeleton | not)) or $origin == 200 or $hc == 200) then "Run Phase 4 Teardown first, then re-check"
elif ($md > 0 and $http_lb == 404 and ($https_lb == 404 or ($https_lb == 200 and $https_skeleton)) and $origin == 404 and $hc == 404) then "Delete mitigated domains inline, then proceed"
else "Run Phase 4 Teardown first, then re-check"
end
)
}'

Wenn alle Phase-1-Objekte vorhanden sind (200) und Sie direkt zu Phase 2 übergehen möchten, führen Sie die Verifizierungsbefehle aus Phase 1 Schritt 7 aus, um den Infrastrukturzustand zu bestätigen, bevor Sie überspringen. Verwenden Sie die genauen Befehle aus Phase 1 — Schritt 7: Verifizieren:

  1. DNS-Auflösung: dig +short xF5XC_DOMAINNAMEx A
  2. HTTP-LB-Status: GET .../http_loadbalancers/xF5XC_LB_NAMEx-http weitergeleitet an jq '{state: .spec.state}' — muss VIRTUAL_HOST_READY anzeigen
  3. CSD-JS-Konfiguration: GET .../js_configuration — muss scriptTag enthalten
  4. CSD-Status: GET .../status weitergeleitet an jq '{configured: .isConfigured, enabled: .isEnabled}' — beide müssen true sein

Alle erforderlichen Prüfungen (DNS-1, LB-1, CSD-1, CSD-2) müssen BESTANDEN sein, bevor Sie zu Phase 2 überspringen. Schlägt eine Prüfung fehl, führen Sie Phase 1 ab dem fehlgeschlagenen Schritt aus.

Die obige Vorab-Prüfung verifiziert, dass die Umgebung sauber ist. Die nachstehende Bereitschaftsmatrix verifiziert, dass die Umgebung fähig ist — dass alle Voraussetzungen, Kontingente, Konnektivität und Plattformdienste für eine erfolgreiche Demo vorhanden sind. Führen Sie diese Matrix vor jedem Meeting als Teil der Vorbereitungsphase aus.

Jede Prüfung hat eine Test-ID, eine Stufe (T0–T5), BESTANDEN/FEHLGESCHLAGEN/WARNUNG-Kriterien und einen Behebungspfad. Stufen sind sequenziell — ein FEHLSCHLAG in einer früheren Stufe blockiert die Ausführung späterer Stufen.

StufeKategorieBlockiert Demo?Zweck
T0Konnektivität und AuthentifizierungJaKönnen wir die Plattform erreichen und uns authentifizieren?
T1Kontingente und KapazitätJa (bei Limit)Gibt es Spielraum für die Erstellung von Demo-Objekten?
T2Plattform-VoraussetzungenJaSind mandantenweite Dienste konfiguriert?
T3Ursprungs-ZustandWarnungAntwortet die Backend-Anwendung?
T4Saubere UmgebungAutomatische BehebungGibt es verbliebene Objekte aus einem früheren Durchlauf?
T5ZertifikatsbereitschaftInformativWird HTTPS funktionieren, oder sollten wir nur HTTP planen?

Diese Prüfungen bestätigen, dass der Ausführungshost die F5 XC API erreichen kann und die Anmeldeinformationen gültig sind.

Terminal-Fenster
HTTP_CODE=$(curl -s -o /dev/null -w '%\{http_code\}' --connect-timeout 10 --max-time 15 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces")
echo "{\"http_code\": $HTTP_CODE}" | jq '{
check: "PF-T0-1",
http_code: .http_code,
status: (
if .http_code == 200 then "PASS"
elif .http_code == 401 then "FAIL"
else "FAIL"
end
),
detail: (
if .http_code == 200 then "API reachable, token valid"
elif .http_code == 401 then "Token expired or invalid — regenerate under Administration > Credentials > API Credentials"
elif .http_code == 0 then "Network unreachable — check connectivity, VPN, or TLS compatibility (try --tlsv1.2 --tls-max 1.2)"
else "Unexpected HTTP \(.http_code)"
end
)
}'
Terminal-Fenster
HTTP_CODE=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers")
echo "{\"http_code\": $HTTP_CODE}" | jq '{
check: "PF-T0-2",
http_code: .http_code,
status: (
if .http_code == 200 then "PASS"
elif .http_code == 404 then "WARN"
else "FAIL"
end
),
detail: (
if .http_code == 200 then "Token has namespace access"
elif .http_code == 403 then "Token lacks permissions for namespace — check role bindings"
elif .http_code == 404 then "Namespace does not exist — will be created in Phase 1 Step 0"
else "Unexpected HTTP \(.http_code)"
end
)
}'
Terminal-Fenster
HTTP_CODE=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status")
echo "{\"http_code\": $HTTP_CODE}" | jq '{
check: "PF-T0-3",
http_code: .http_code,
status: (
if .http_code == 200 then "PASS"
elif .http_code == 404 then "WARN"
else "FAIL"
end
),
detail: (
if .http_code == 200 then "Token has CSD/Shape API permissions"
elif .http_code == 403 then "Token lacks CSD role binding — contact tenant administrator"
elif .http_code == 404 then "Namespace does not exist — CSD access will be verified after namespace creation in Phase 1"
else "Unexpected HTTP \(.http_code)"
end
)
}'

Nicht-destruktive Sonden testen Lese- und Schreibberechtigungen für jeden Objekttyp, den die Demo benötigt. Lesen wird über GET auf Listenendpunkte getestet. Schreiben wird über DELETE auf bekannte, nicht vorhandene Objekte getestet — die API gibt 403 zurück, wenn RBAC den Vorgang verweigert, oder 404, wenn der Vorgang erlaubt ist, das Objekt aber nicht existiert. Diese Technik ohne Nebeneffekte vermeidet die Erstellung temporärer Sonderobjekte.

Terminal-Fenster
PROBE_NAME="rbac-probe-nonexistent"
# Lese-Sonden
NS_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces/xF5XC_NAMESPACEx")
HC_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks")
OP_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools")
LB_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers")
CSD_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status")
PD_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains")
MD_R=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains")
# Schreib-Sonden (nicht-destruktiv: DELETE/cascade_delete auf nicht vorhandene Objekte)
NS_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X POST -H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d "{\"name\":\"$PROBE_NAME\"}" \
"xF5XC_API_URLx/api/web/namespaces/$PROBE_NAME/cascade_delete")
HC_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/$PROBE_NAME")
OP_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/$PROBE_NAME")
LB_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/$PROBE_NAME")
PD_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains/$PROBE_NAME.example.com")
MD_W=$(curl -s -o /dev/null -w '%\{http_code\}' --max-time 10 \
-X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/mitigated_domains/$PROBE_NAME.example.com")
# Deterministische Berechtigungsmatrix berechnen
jq -n \
--argjson ns_r "$NS_R" --argjson ns_w "$NS_W" \
--argjson hc_r "$HC_R" --argjson hc_w "$HC_W" \
--argjson op_r "$OP_R" --argjson op_w "$OP_W" \
--argjson lb_r "$LB_R" --argjson lb_w "$LB_W" \
--argjson csd_r "$CSD_R" \
--argjson pd_r "$PD_R" --argjson pd_w "$PD_W" \
--argjson md_r "$MD_R" --argjson md_w "$MD_W" \
'{
check: "PF-T0-4",
permissions: [
{ object: "namespace", read: ($ns_r != 403), write: ($ns_w != 403), required: false, note: "conditional — only if ns must be created" },
{ object: "healthcheck", read: ($hc_r != 403), write: ($hc_w != 403), required: false, note: "optional for CSD" },
{ object: "origin_pool", read: ($op_r != 403), write: ($op_w != 403), required: true, note: "" },
{ object: "http_loadbalancer", read: ($lb_r != 403), write: ($lb_w != 403), required: true, note: "" },
{ object: "csd_status", read: ($csd_r != 403), write: true, required: true, note: "read-only check" },
{ object: "protected_domain", read: ($pd_r != 403), write: ($pd_w != 403), required: true, note: "" },
{ object: "mitigated_domain", read: ($md_r != 403), write: ($md_w != 403), required: false, note: "Phase 3 only" }
],
status: (
if [
($op_r == 403), ($op_w == 403),
($lb_r == 403), ($lb_w == 403),
($csd_r == 403),
($pd_r == 403), ($pd_w == 403)
] | any then "FAIL"
elif ($ns_w == 403 or $hc_w == 403 or $md_w == 403) then "WARN"
else "PASS"
end
),
detail: (
[
(if ($op_r == 403 or $op_w == 403) then "Origin pool: permission denied" else null end),
(if ($lb_r == 403 or $lb_w == 403) then "Load balancer: permission denied" else null end),
(if $csd_r == 403 then "CSD API: permission denied — CSD may not be enabled for this namespace" else null end),
(if ($pd_r == 403 or $pd_w == 403) then "Protected domain: permission denied" else null end),
(if $ns_w == 403 then "Namespace: write denied — namespace must already exist (cannot create)" else null end),
(if $hc_w == 403 then "Healthcheck: write denied — will skip healthcheck creation" else null end),
(if $md_w == 403 then "Mitigated domain: write denied — Phase 3 mitigation will be skipped" else null end)
] | map(select(. != null)) | join("; ")
)
}'

Diese Prüfungen fragen die Kontingentnutzungs-API des Mandanten ab, um Limits, aktuelle Nutzung und verbleibende Kapazität für jeden Objekttyp zu ermitteln, den die Demo benötigt. Dies ersetzt Sonde-und-Löschen-Tests durch einen einzigen schreibgeschützten API-Aufruf, der genaue Zahlen meldet.

Fragen Sie den mandantenweiten Kontingentnutzungs-Endpunkt ab und berechnen Sie einen deterministischen BESTANDEN/WARNUNG/FEHLSCHLAG-Status für jeden Objekttyp, den die Demo benötigt. Dieser Endpunkt erfordert den system-Namespace. Ein einziger API-Aufruf prüft alle plattformweiten Kontingente auf einmal.

Das Gate definiert ein demo_needs-Array, das angibt, wie viele Objekte jeder Art die Demo verbrauchen wird, ob die Art erforderlich ist und die Mindestanzahl, die zum Fortfahren benötigt wird. Der jq-Filter vergleicht remaining mit needed und berechnet das status-Feld deterministisch — keine Operatorinterpretation erforderlich.

Terminal-Fenster
# Schritt 1: Kontingenddaten abrufen
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces/system/quota/usage?namespace=system" \
> /tmp/quota.json
# Schritt 2: Gate-Status berechnen
jq '
. as $data |
[
{ kind: "healthcheck", needed: 1, required: false, min_proceed: 0 },
{ kind: "origin_pool", needed: 1, required: true, min_proceed: 1 },
{ kind: "endpoint", needed: 1, required: true, min_proceed: 1 },
{ kind: "http_loadbalancer", needed: 2, required: true, min_proceed: 1 }
] | map(
. as $req |
$data.objects[$req.kind] as $obj |
$obj.limit.maximum as $limit |
$obj.usage.current as $usage |
(if $limit == -1 then null else ($limit - $usage) end) as $remaining |
{
kind: $req.kind,
limit: (if $limit == -1 then "unlimited" else $limit end),
usage: $usage,
remaining: (if $remaining == null then "unlimited" else $remaining end),
needed: $req.needed,
status: (
if $remaining == null then "PASS"
elif $remaining >= $req.needed then "PASS"
elif $remaining >= $req.min_proceed then "WARN"
else
(if $req.required then "FAIL" else "WARN" end)
end
)
}
)
| {
checks: .,
gate: (if any(.[]; .status == "FAIL") then "FAIL"
elif any(.[]; .status == "WARN") then "WARN"
else "PASS" end)
}
' /tmp/quota.json

Gate-Ausgabe — das gate-Feld ist das einzige deterministische Urteil:

  • PASS — alle Objektarten haben remaining >= needed. Die Demo kann fortfahren.
  • WARN — mindestens eine Art hat reduzierte Kapazität, aber das Minimum zum Fortfahren ist erfüllt (z. B. nur 1 LB-Slot verfügbar statt 2, oder Healthcheck-Kontingent erschöpft). Die Demo kann mit Einschränkungen fortfahren.
  • FAIL — mindestens eine erforderliche Art hat remaining < min_proceed. Die Demo kann erst fortgesetzt werden, wenn Kontingent freigegeben wurde.

Beispielausgabe (WARN — Endpunkt bei Kapazität, Healthcheck fast voll):

{
"checks": [
{ "kind": "healthcheck", "limit": 150, "usage": 149, "remaining": 1, "needed": 1, "status": "PASS" },
{ "kind": "origin_pool", "limit": "unlimited", "usage": 420, "remaining": "unlimited", "needed": 1, "status": "PASS" },
{ "kind": "endpoint", "limit": 500, "usage": 500, "remaining": 0, "needed": 1, "status": "FAIL" },
{ "kind": "http_loadbalancer", "limit": "unlimited", "usage": 116, "remaining": "unlimited", "needed": 2, "status": "PASS" }
],
"gate": "FAIL"
}
gate-WertAktion
PASSWeiter zu PF-T1-4 (Prüfung geschützter Domains), dann T2
WARNEinschränkungen im Bereitschaftsbericht vermerken, mit reduzierter Kapazität fortfahren
FAILStopp — melden, welche Arten erschöpft sind, und Behebungsschritte unten

Behebung nach Art:

ArtBehebung
healthcheckUngenutzte Healthchecks löschen, um Kapazität freizugeben. Die Demo fährt ohne Healthcheck fort (CSD erfordert keine Gesundheitsüberwachung).
origin_poolUngenutzte Ursprungspools löschen oder den Administrator kontaktieren, um das Mandantenlimit zu erhöhen.
endpointUngenutzte Ursprungspools in anderen Namespaces löschen, um Endpunktkapazität freizugeben (Endpunkte sind Unterobjekte von Ursprungspools), oder den Administrator kontaktieren.
http_loadbalancerUngenutzte Load Balancer löschen oder den Administrator kontaktieren. Wenn nur 1 Slot verfügbar ist, wird der HTTP-LB (primär) erstellt, der HTTPS-LB (sekundär) wird übersprungen.

CSD-geschützte Domains erscheinen nicht in der Plattform-Kontingentnutzungs-API. Verwenden Sie eine sondenbasierte Prüfung: Erstellen und löschen Sie sofort eine Sonden-geschützte Domain.

Terminal-Fenster
# Sonde erstellen und sowohl HTTP-Code als auch Antwort-Body erfassen
PROBE_BODY=$(curl -s -w '\n%\{http_code\}' -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "preflight-probe.example.com",
"namespace": "xF5XC_NAMESPACEx"
},
"spec": {
"protected_domain": "example.com"
}
}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains")
PROBE_HTTP=$(echo "$PROBE_BODY" | tail -1)
PROBE_JSON=$(echo "$PROBE_BODY" | sed '$d')
# Status berechnen
echo "$PROBE_JSON" | jq --argjson http "$PROBE_HTTP" '{
check: "PF-T1-4",
http_code: $http,
status: (
if $http == 409 then "PASS"
elif (.code // 0) == 8 then "FAIL"
elif .metadata.name then "PASS"
else "FAIL"
end
),
detail: (
if $http == 409 then "example.com already registered — quota not exhausted"
elif (.code // 0) == 8 then "Protected domain quota exhausted — delete unused protected domains"
elif .metadata.name then "Probe created — quota available"
else "Unexpected response"
end
)
}'
# Sonde bereinigen (404 ist zu erwarten, wenn 409 aufgetreten ist)
curl -s -X DELETE \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains/preflight-probe.example.com" \
> /dev/null

Wenn PF-T1-0 fehlschlägt (die Kontingentnutzungs-API gibt 403, 404 oder ein unerwartetes Format zurück), wechseln Sie zu sondenbasierten Prüfungen für Healthcheck-, Ursprungspool-, Endpunkt- und Load-Balancer-Kontingente. Diese Prüfungen erstellen ein temporäres Objekt und löschen es sofort — wenn die Erstellung den Fehlercode 8 mit “exhausted limits” zurückgibt, ist das Kontingent erschöpft.

Jede Fallback-Sonde verwendet dasselbe Muster: ein temporäres Objekt erstellen, einen deterministischen Status aus der Antwort berechnen und die Sonde dann löschen. Das status-Feld ist PASS, wenn das Objekt erstellt wurde (.metadata.name vorhanden), WARN oder FAIL, wenn Fehlercode 8 (erschöpfte Limits) vorliegt, je nachdem, ob die Art erforderlich ist.

Healthcheck-Sonde (WARNUNG bei Erschöpfung — Healthchecks sind optional für CSD):

Terminal-Fenster
RESULT=$(curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "preflight-quota-probe",
"namespace": "xF5XC_NAMESPACEx"
},
"spec": {
"http_health_check": {
"use_origin_server_name": {},
"path": "/",
"use_http2": false
},
"timeout": 3,
"interval": 15,
"unhealthy_threshold": 1,
"healthy_threshold": 3
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks")
echo "$RESULT" | jq '{
check: "fallback-healthcheck",
status: (if .metadata.name then "PASS" elif (.code // 0) == 8 then "WARN" else "FAIL" end),
detail: (if .metadata.name then "Quota available" elif (.code // 0) == 8 then "Quota full — healthcheck optional, demo proceeds" else "Unexpected: \(.message // "unknown error")" end)
}'
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/preflight-quota-probe" \
> /dev/null

Ursprungspool- und Endpunkt-Sonde (FEHLSCHLAG bei Erschöpfung — beide sind erforderlich):

Terminal-Fenster
RESULT=$(curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "preflight-origin-probe",
"namespace": "xF5XC_NAMESPACEx"
},
"spec": {
"origin_servers": [{
"public_ip": { "ip": "192.0.2.1" },
"labels": {}
}],
"no_tls": {},
"port": 80,
"same_as_endpoint_port": {},
"healthcheck": [],
"loadbalancer_algorithm": "LB_OVERRIDE",
"endpoint_selection": "LOCAL_PREFERRED"
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools")
echo "$RESULT" | jq '{
check: "fallback-origin-pool",
status: (if .metadata.name then "PASS" elif (.code // 0) == 8 then "FAIL" else "FAIL" end),
detail: (if .metadata.name then "Quota available" elif (.code // 0) == 8 then "Quota exhausted — \(.message // "limit reached")" else "Unexpected: \(.message // "unknown error")" end)
}'
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/preflight-origin-probe" \
> /dev/null

HTTP-Load-Balancer-Sonde (FEHLSCHLAG bei Erschöpfung — LBs sind erforderlich):

Terminal-Fenster
RESULT=$(curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "preflight-lb-probe",
"namespace": "xF5XC_NAMESPACEx",
"disable": false
},
"spec": {
"domains": ["preflight-probe.example.com"],
"http": {
"dns_volterra_managed": false,
"port": 80
},
"advertise_on_public_default_vip": {},
"default_route_pools": [],
"disable_rate_limit": {},
"no_service_policies": {},
"round_robin": {},
"disable_waf": {},
"no_challenge": {},
"disable_bot_defense": {},
"disable_api_definition": {},
"disable_api_discovery": {},
"disable_ip_reputation": {},
"disable_malicious_user_detection": {},
"single_lb_app": {
"disable_discovery": {},
"disable_ddos_detection": {},
"disable_malicious_user_detection": {}
},
"disable_trust_client_ip_headers": {},
"user_id_client_ip": {},
"disable_threat_mesh": {},
"l7_ddos_action_default": {},
"system_default_timeouts": {},
"default_sensitive_data_policy": {},
"disable_malware_protection": {},
"disable_api_testing": {}
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers")
echo "$RESULT" | jq '{
check: "fallback-http-lb",
status: (if .metadata.name then "PASS" elif (.code // 0) == 8 then "FAIL" else "FAIL" end),
detail: (if .metadata.name then "Quota available" elif (.code // 0) == 8 then "Quota exhausted — \(.message // "limit reached")" else "Unexpected: \(.message // "unknown error")" end)
}'
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/preflight-lb-probe" \
> /dev/null

Diese Prüfungen verifizieren mandantenweite Dienste, von denen die Demo abhängt.

Terminal-Fenster
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \
| jq '{
check: "PF-T2-1",
configured: .isConfigured,
enabled: .isEnabled,
status: (if .isConfigured and .isEnabled then "PASS" else "FAIL" end),
detail: (
if .isConfigured and .isEnabled then "CSD is active"
elif (.isConfigured | not) then "CSD not enabled at tenant level — contact F5 XC administrator"
else "CSD configured but not active — contact administrator"
end
)
}'
Terminal-Fenster
HTTP_CODE=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx")
echo "{\"http_code\": $HTTP_CODE}" | jq '{
check: "PF-T2-2",
http_code: .http_code,
status: (
if .http_code == 200 then "PASS"
elif .http_code == 404 then "WARN"
elif .http_code == 403 then "WARN"
else "FAIL"
end
),
detail: (
if .http_code == 200 then "DNS zone exists in F5 XC"
elif .http_code == 404 then "No F5 XC DNS zone — external DNS may be in use"
elif .http_code == 403 then "Token lacks DNS zone read access (system namespace)"
else "Unexpected HTTP \(.http_code)"
end
)
}'

Nur ausführen, wenn PF-T2-2 200 zurückgegeben hat (F5 XC DNS-Zone vorhanden).

Aktuellen Zustand prüfen:

Terminal-Fenster
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx" \
| jq '{
check: "PF-T2-3",
managed_records: (.spec.primary.allow_http_lb_managed_records // false),
status: (if .spec.primary.allow_http_lb_managed_records == true then "PASS" else "WARN" end),
detail: (if .spec.primary.allow_http_lb_managed_records == true then "LB-managed DNS records enabled" else "Managed records not enabled — auto-remediation may be needed" end)
}'

Automatische Behebung bei Bedarf: Wenn der status WARN ist UND PF-T2-4 F5 XC-Nameserver (ns1.f5clouddns.com, ns2.f5clouddns.com) anzeigt, aktivieren Sie verwaltete Einträge automatisch mithilfe von GET+PUT:

Terminal-Fenster
# Aktuelle Zonenkonfiguration abrufen
ZONE_CONFIG=$(curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx")
# Mit aktivierten verwalteten Einträgen aktualisieren
echo "$ZONE_CONFIG" \
| jq '.spec.primary.allow_http_lb_managed_records = true' \
| curl -s -X PUT \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d @- \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx" \
| jq .

Dann erneut prüfen, um zu bestätigen, dass die Aktualisierung wirksam wurde:

Terminal-Fenster
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'
ErgebnisDNS-AutoritätStatusBehebung
trueBeliebigBESTANDENVon LB verwaltete DNS-Einträge werden automatisch erstellt
false/nullF5 XCAutomatisch behebenÜber GET+PUT aktivieren, verifizieren, Ergebnis melden
false/nullExternINFOVerwaltete Einträge nicht anwendbar für externes DNS — Phase 1 Schritt 4 verwendet Option B (manuelle Eintragserstellung)
Automatische Behebung fehlgeschlagenF5 XCFEHLSCHLAGToken fehlt möglicherweise Schreibzugriff auf den system-Namespace — Mandantenadministrator kontaktieren
Terminal-Fenster
NS_RECORDS=$(dig +short NS xF5XC_ROOT_DOMAINx)
echo "$NS_RECORDS" | jq -Rs '{
check: "PF-T2-4",
nameservers: (split("\n") | map(select(length > 0))),
status: (
if (split("\n") | map(select(length > 0)) | length) == 0 then "FAIL"
elif test("f5clouddns\\.com") then "PASS"
else "INFO"
end
),
detail: (
if (split("\n") | map(select(length > 0)) | length) == 0 then "No NS records — DNS is broken for this domain"
elif test("f5clouddns\\.com") then "F5 XC is authoritative — automatic DNS management available"
else "External DNS provider — Phase 1 Step 4 will use Option B (manual record creation)"
end
)
}'

Diese Prüfungen verifizieren, ob die Backend-Anwendung erreichbar ist.

Bedingung zum Überspringen prüfen: Berechnen Sie, ob die Ursprungs-IP eine RFC-5737-TEST-NET-Adresse ist, bevor Sie Konnektivitätstests ausführen:

Terminal-Fenster
echo "xF5XC_ORIGIN_IPx" | jq -Rs '{
check: "PF-T3-skip",
origin_ip: (rtrimstr("\n")),
is_test_net: (rtrimstr("\n") | test("^192\\.0\\.2\\.|^198\\.51\\.100\\.|^203\\.0\\.113\\.")),
status: (if (rtrimstr("\n") | test("^192\\.0\\.2\\.|^198\\.51\\.100\\.|^203\\.0\\.113\\.")) then "SKIP" else "CONTINUE" end),
detail: (if (rtrimstr("\n") | test("^192\\.0\\.2\\.|^198\\.51\\.100\\.|^203\\.0\\.113\\.")) then "RFC 5737 TEST-NET address — not routable, connectivity testing skipped" else "Routable IP — proceed with connectivity tests" end)
}'

Wenn status SKIP ist, erfassen Sie PF-T3-1 und PF-T3-2 als ÜBERSPRINGEN und fahren Sie mit T4 fort. Andernfalls führen Sie die folgenden Prüfungen durch.

Terminal-Fenster
HTTP_CODE=$(curl -s -o /dev/null -w '%\{http_code\}' --connect-timeout 10 --max-time 15 \
"http://xF5XC_ORIGIN_IPx:xF5XC_ORIGIN_PORTx/")
echo "{\"http_code\": $HTTP_CODE}" | jq '{
check: "PF-T3-1",
http_code: .http_code,
status: (if .http_code >= 200 and .http_code < 600 then "PASS" elif .http_code == 0 then "WARN" else "WARN" end),
detail: (
if .http_code >= 200 and .http_code < 600 then "Origin responding with HTTP \(.http_code)"
elif .http_code == 0 then "Origin unreachable from this network — LB may use a different path"
else "Unexpected response code \(.http_code)"
end
)
}'

Nur ausführen, wenn PF-T3-1 einen gültigen HTTP-Status zurückgegeben hat:

Terminal-Fenster
curl -s --max-time 10 "http://xF5XC_ORIGIN_IPx:xF5XC_ORIGIN_PORTx/" \
| grep -qi '</html>' && echo "PASS: HTML content" || echo "WARN: No HTML detected"
ErgebnisStatusBehebung
PASS: HTML contentBESTANDENUrsprung liefert HTML-Seiten (erforderlich für CSD-JS-Injektion)
WARN: No HTML detectedWARNUNGUrsprung ist möglicherweise ein reiner API-Dienst oder gibt kein HTML zurück — CSD-JS-Injektion erfordert HTML-Seitenresponses

Diese Prüfungen verifizieren, dass keine benannten F5-XC-Konfigurationsobjekte aus einem früheren Demo-Durchlauf verblieben sind — HTTP-Load-Balancer, HTTPS-Load-Balancer, Ursprungspools, Healthchecks, geschützte Domains und abgewehrte Domains. T4 betrifft die Bereinigung auf Objektebene: ob API-Objekte, die mit der Phase-1-Erstellung in Konflikt geraten würden, noch vorhanden sind. Es werden keine IP-Adressen, Netzwerkkonnektivität oder der Ursprungszustand getestet (diese Belange gehören zu T3).

Führen Sie die sechs Vorab-Prüfungsbefehle aus dem Abschnitt Vorab-Prüfung oben aus. Wenden Sie die Entscheidungslogik an, um die nächsten Schritte zu bestimmen. Wenn Objekte vorhanden sind, wird während der Vorbereitungsphase ein automatischer Abbau durchgeführt (keine Bestätigung erforderlich).

Prüfen Sie auch auf veraltete Sondeobjekte aus früheren unterbrochenen Vorab-Prüfungsläufen und löschen Sie diese. Diese Sonden werden nur erstellt, wenn die Kontingentnutzungs-API nicht verfügbar ist und die sondenbasierten Fallback-Prüfungen verwendet wurden, oder für die geschützte Domain-Sonde (PF-T1-4), die immer sondenbasierte Prüfungen verwendet:

Terminal-Fenster
# Bereinigung veralteter Sonden (in beliebiger Reihenfolge löschen — Sonden haben keine Abhängigkeiten)
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/preflight-quota-probe" \
> /dev/null
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/preflight-lb-probe" \
> /dev/null
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/preflight-origin-probe" \
> /dev/null
curl -s -X DELETE -H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains/preflight-probe.example.com" \
> /dev/null

Jedes DELETE gibt 200 (leeres {}) zurück, wenn das Objekt vorhanden war, oder 404, wenn es nicht vorhanden war — beides ist erwartet.

Diese Prüfungen beurteilen, ob HTTPS funktionieren wird oder die Demo nur für HTTP geplant werden sollte.

Prüfen Sie, ob kürzlich ein Let’s-Encrypt-Zertifikat für die Demo-Domain ausgestellt wurde. Häufige Erstellungs-/Zerstörungszyklen können das wöchentliche Ratenlimit erschöpfen (5 doppelte Zertifikate pro Woche pro Domain).

Nur ausführen, wenn ein HTTPS-LB aus einem früheren Durchlauf vorhanden ist (PF-T4 hat Objekte gefunden):

Terminal-Fenster
CERT_BODY=$(curl -s -w '\n%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https")
CERT_HTTP=$(echo "$CERT_BODY" | tail -1)
CERT_JSON=$(echo "$CERT_BODY" | sed '$d')
if [ "$CERT_HTTP" = "404" ]; then
echo '{"check":"PF-T5-2","cert_state":null,"status":"SKIP","detail":"No HTTPS LB — certificate state assessed after Phase 1 Step 3"}'
else
echo "$CERT_JSON" | jq '{
check: "PF-T5-2",
cert_state: .spec.cert_state,
status: (
if .spec.cert_state == "CertificateValid" then "PASS"
elif .spec.cert_state == "AutoCertDomainRateLimited" then "INFO"
elif (.spec.cert_state | test("Pending|Started")) then "INFO"
else "INFO"
end
),
detail: (
if .spec.cert_state == "CertificateValid" then "Certificate healthy — HTTPS will work"
elif .spec.cert_state == "AutoCertDomainRateLimited" then "Let'\''s Encrypt rate limit hit — plan for HTTP-only demo"
elif (.spec.cert_state | test("Pending|Started")) then "Certificate provisioning in progress"
else "Certificate state: \(.spec.cert_state // "unknown")"
end
)
}'
fi

Nach der Ausführung aller Stufen erstellen Sie einen konsolidierten Bereitschaftsbericht:

## Demo-Bereitschaft: BEREIT / NICHT BEREIT / BEREIT MIT WARNUNGEN
### T0: Konnektivität & Authentifizierung
| Prüfung | Ergebnis | Status |
|---|---|---|
| PF-T0-1: API-Konnektivität | 200 | PASS |
| PF-T0-2: Namespace-Zugriff | 200 | PASS |
| PF-T0-3: CSD-API-Zugriff | 200 | PASS |
### T1: Kontingente & Kapazität
| Prüfung | Art | Limit | Nutzung | Verbleibend | Benötigt | Status |
|---|---|---|---|---|---|---|
| PF-T1-0: Kontingentnutzungs-Gate | `healthcheck` | 150 | 148 | 2 | 1 | PASS |
| PF-T1-0: Kontingentnutzungs-Gate | `origin_pool` | unlimited | 420 | unlimited | 1 | PASS |
| PF-T1-0: Kontingentnutzungs-Gate | `endpoint` | 500 | 498 | 2 | 1 | PASS |
| PF-T1-0: Kontingentnutzungs-Gate | `http_loadbalancer` | unlimited | 116 | unlimited | 2 | PASS |
| PF-T1-0: Kontingentnutzungs-Gate | **gate** | — | — | — | — | **PASS** |
| PF-T1-4: Geschützte Domain | — | — | — | — | 1 | PASS (Sonde) |
### T2: Plattform-Voraussetzungen
| Prüfung | Ergebnis | Status |
|---|---|---|
| PF-T2-1: CSD-Mandantenstatus | konfiguriert + aktiviert | PASS |
| PF-T2-2: DNS-Zone vorhanden | 200 | PASS |
| PF-T2-3: Verwaltete DNS-Einträge | true | PASS |
| PF-T2-4: DNS-Nameserver-Autorität | f5clouddns.com | PASS |
### T3: Ursprungs-Zustand
| Prüfung | Ergebnis | Status |
|---|---|---|
| PF-T3-1: Ursprungs-Konnektivität | TEST-NET-Adresse (192.0.2.1) | ÜBERSPRINGEN |
| PF-T3-2: HTML-Inhalt | TEST-NET-Adresse | ÜBERSPRINGEN |
### T4: Saubere Umgebung
| Prüfung | Ergebnis | Status |
|---|---|---|
| HTTP LB | 404 | PASS |
| HTTPS LB | 404 | PASS |
| Ursprungspool | 404 | PASS |
| Healthcheck | 404 | PASS |
| Geschützte Domains | 0 | PASS |
| Abgewehrte Domains | 0 | PASS |
### T5: Zertifikatsbereitschaft
| Prüfung | Ergebnis | Status |
|---|---|---|
| PF-T5-2: Zertifikatsstatus | ÜBERSPRINGEN (kein HTTPS LB) | INFO |
### Warnungen
- (alle WARN- oder INFO-Einträge mit Kontext auflisten)

Gesamtstatusregeln:

BedingungStatus
Alle T0–T4-Prüfungen BESTANDENBEREIT
Alle T0–T4-Prüfungen BESTANDEN, aber T3 oder T5 haben WARN/INFOBEREIT MIT WARNUNGEN
Irgendeine T0-, T1- oder T2-Prüfung FEHLGESCHLAGENNICHT BEREIT — vor dem Fortfahren beheben
T4 hat verbliebene ObjekteAutomatisch beheben (Abbau), dann erneut prüfen

Dieser Abschnitt definiert einen deterministischen Workflow für KI-Assistenten (Claude Code, Copilot usw.), die die API-Automatisierungsschritte ausführen. Die Einhaltung dieses Protokolls eliminiert Ratespiele — jeder Entscheidungspunkt hat einen definierten Lösungspfad.

Lösen Sie jede Variable in genau dieser Reihenfolge auf. Halten Sie bei der ersten Quelle an, die einen Nicht-Platzhalterwert liefert:

  1. .env-Datei prüfen — suchen Sie nach .env im Stammverzeichnis des Repositorys. Wenn vorhanden, parsen Sie alle KEY=VALUE-Paare.
  2. Shell-Umgebung prüfen — führen Sie env | grep F5XC_ aus, um bereits in der aktuellen Sitzung exportierte Werte zu finden.
  3. Fehlende Werte identifizieren — vergleichen Sie aufgelöste Werte mit der nachstehenden Tabelle für erforderliche/optionale Variablen. Ein Wert gilt als “fehlend”, wenn er fehlt, leer ist oder noch auf einen Platzhalterwert gesetzt ist (z. B. example-api-token, example-tenant, example-namespace, app.example.com, user@example.com).
  4. Menschlichen Operator befragen — für jede fehlende erforderliche Variable bitten Sie den Operator, den Wert anzugeben. Fahren Sie nicht fort, bis alle erforderlichen Variablen aufgelöst sind.
  5. Standardwerte anwenden — für jede fehlende optionale Variable verwenden Sie den Standardwert aus der nachstehenden Tabelle, ohne nachzufragen.

Leerer String = fehlend: Eine mit einem leeren Wert exportierte Variable (z. B. F5XC_HC_NAME="") wird genauso behandelt wie eine nicht gesetzte Variable — wenden Sie den Standardwert an. Verwenden Sie die Shell-Parameterexpansion (${F5XC_HC_NAME:-csd-hc}), um Standardwerte in einem Schritt anzuwenden.

  1. Bestätigung anzeigen — zeigen Sie dem Operator die endgültige aufgelöste Variablentabelle an und warten Sie auf Genehmigung, bevor Sie API-Aufrufe ausführen.

Überschreibung in der Vorbereitungsphase: Überspringen Sie während Phase 1 Vorbereitung das Warten in Schritt 6. Zeigen Sie die aufgelöste Variablentabelle zur Protokollierung an und fahren Sie sofort fort. Die Schritte 1–5 gelten weiterhin — wenn eine erforderliche Variable nach dem Prüfen von .env und Shell fehlt, stoppen Sie und melden Sie die fehlenden Variablen.

VariableErforderlichStandardPlatzhalter (als fehlend behandeln)
F5XC_API_TOKENJaexample-api-token
F5XC_API_URLJahttps://example-tenant.console.ves.volterra.io
F5XC_NAMESPACEJaexample-namespace
F5XC_DOMAINNAMEJaapp.example.com
F5XC_ROOT_DOMAINJaexample.com
F5XC_LB_NAMEJaexample-lb-name, example-lb
F5XC_EMAILJauser@example.com
F5XC_HC_NAMEOptionalcsd-hc
F5XC_ORIGIN_IPOptional44.232.69.192
F5XC_ORIGIN_POOLOptionalcsd-origin
F5XC_ORIGIN_PORTOptional3000

Der KI-Assistent arbeitet während der Demo in einem von drei Modi:

ModusAktiv wennVerhalten
NormalStandard während Vorbereitung, Ausführung, AbbauWortgetreu dokumentierte Befehle
DebugAktiviert sich automatisch bei FehlschlagKreative Fehlersuche, Dokumentation aktualisieren
Q&AWährend der Q&A-PhaseImprovisiert — Ad-hoc-Befehle erlaubt, um Fragen des Publikums zu beantworten

Normalmodus (Standard):

  • Jeder API-Aufruf, jede Verifizierungsabfrage und jeder Shell-Befehl muss wortgetreu aus den Phasendateien (Phase 1–4) oder dem obigen Abschnitt zur Vorab-Prüfung stammen
  • Ersetzen Sie nur xTOKENx-Platzhalter durch aufgelöste Variablenwerte
  • Konstruieren Sie keine API-Endpunkte, jq-Filter oder cURL-Befehle aus allgemeinem Wissen oder Schlussfolgerungen
  • Wenn ein benötigter Befehl nicht dokumentiert ist, stoppen Sie und melden Sie dem Operator: “Dieser Verifizierungsschritt ist nicht durch die Phasendokumentation abgedeckt”

Debug-Modus (aktiviert sich automatisch bei Fehlschlag):

  • Aktiviert sich automatisch, wenn ein dokumentierter Befehl ein unerwartetes Ergebnis liefert: Nicht-2xx-HTTP-Antwort, jq-Analysefehler, Befehlstimeout oder Antwort-Body, der den Belegen widerspricht
  • Im Debug-Modus kann der KI-Assistent Diagnosebefehle konstruieren, rohe API-Antworten untersuchen, Endpunktvarianten testen und kreative Fehlersuche zur Ursachenermittlung einsetzen
  • Stellen Sie allen Debug-Ausgaben [DEBUG] voran, damit der Operator diagnostische Aktivitäten von der normalen Ausführung unterscheiden kann
  • Dokumentieren Sie, was Sie lernen: Aktualisieren Sie nach der Behebung eines Problems die relevante Phasendatei oder den Fehlerbehebungsabschnitt mit:
    1. Dem Fehlerszenario (was schiefgegangen ist)
    2. Was versucht wurde und NICHT funktioniert hat (damit zukünftige Läufe es nicht wiederholen)
    3. Der funktionierenden Lösung (dem Befehl oder der Korrektur, die das Problem gelöst hat)
  • Das Ziel des Debug-Modus ist es, sich selbst zu eliminieren — jede Debug-Sitzung sollte eine Dokumentationsaktualisierung erzeugen, die den nächsten Durchlauf vollständig deterministisch macht
  • Sobald die Dokumentation aktualisiert und das Problem behoben ist, kehren Sie zum Normalmodus zurück und fahren Sie ab dem letzten erfolgreichen dokumentierten Schritt fort
  • Wenn der Debug-Modus das Problem nicht beheben kann, melden Sie die Ergebnisse dem Operator und stoppen — fahren Sie nicht mit der nächsten Phase fort

Q&A-Modus (während der Q&A-Phase):

  • Nur während der Q&A-Meeting-Phase aktiv, nach dem Demo-Abschluss
  • Der KI-Assistent kann Ad-hoc-API-Aufrufe konstruieren, Diagnosebefehle ausführen, zu nicht geskripteten Seiten navigieren und die Live-Demo-Umgebung ändern, um Antworten auf Fragen des Publikums zu veranschaulichen
  • Kein [DEBUG]-Präfix — dies ist beabsichtigtes improvisiertes Verhalten, kein Fehler-Recovery
  • Verwendet den Abschnitt CSD-Produktkompetenz in DEMO_EXECUTOR.md als Wissensbasis für Produktfragen

Die Akkumulation von initScript ist eine häufige Ursache für Demo-Fehlschläge. Jeder navigate_page-Aufruf mit einem initScript-Parameter fügt das Skript einer dauerhaften Liste hinzu, die bei jedem nachfolgenden Dokumentladen ausgeführt wird. Befolgen Sie diese Regeln:

  • Navigieren Sie immer zu about:blank, bevor Sie mit initScript navigieren, um akkumulierte Skripte aus früheren Läufen zu löschen
  • Verwenden Sie new_page mit isolatedContext, wenn Sie zwischen Demo-Phasen wechseln (z. B. Phase 2 → Phase 3), um einen vollständig sauberen Browser-Zustand sicherzustellen
  • Wiederherstellung bei nicht reagierenden Seiten — wenn take_screenshot- oder take_snapshot-Timeouts auftreten, ist der Browser-Kontext ressourcenerschöpft. Verwenden Sie new_page mit isolatedContext, um einen frischen Kontext zu erstellen, und wiederholen Sie dann den about:blank-Navigationsschritt
  • Weitere Hinweise zu vorübergehenden Ursprungsfehlern und der Wiederherstellung bei Ressourcenerschöpfung finden Sie in den Asides zur Phase-2-Angriffssimulation

Nach jedem API-Aufruf muss der KI-Assistent dem menschlichen Operator strukturierte Belege in diesem Format präsentieren:

Erstellungsschritte (POST):

FeldWertStatus
HTTP-Status200BESTANDEN
Objektnamecsd-origin
Schlüsseleigenschaft(via jq extrahiert)

Nach jedem Erstellungsschritt führen Sie einen GET durch, um zu bestätigen, dass das Objekt vorhanden ist, und zeigen seine Schlüsseleigenschaften an. Wenn der GET 404 zurückgibt, melden Sie FEHLSCHLAG und stoppen.

Verifizierungsschritte (GET/dig):

TestErgebnisStatus
DNS-1: A-Eintrag198.51.100.10BESTANDEN
LB-1: HTTP-LB-StatusVIRTUAL_HOST_READYBESTANDEN
LB-2: HTTPS-LB-StatusVIRTUAL_HOST_READYINFO (optional)
TLS-1: ZertifikatsstatusCertificateValidINFO (optional)
CSD-1: JS-TagscriptTag vorhandenBESTANDEN

Verwenden Sie die Test-Fall-IDs aus Diagnose und Verifizierung (DNS-1, TLS-1, LB-1, CSD-1 usw.) als Verifizierungsstandard für jede Schicht.

Die Phasenausführung ist sequenziell und gatekontrolliert: Jede Phase muss bei allen erforderlichen Prüfungen BESTANDEN erreichen, bevor die nächste Phase beginnt. Die Demo folgt einem vierstufigen Meeting-Lebenszyklus — Trigger-Phrasen und Verhaltensregeln finden Sie im Abschnitt Meeting-Stufen in DEMO_EXECUTOR.md.

Der KI-Assistent folgt dieser Sequenz:

  1. Vorbereiten — Variablen auflösen, Vorab-Prüfungen ausführen, saubere Umgebung bestätigen (kann separat vor dem Meeting ausgeführt werden)
  2. Einführung — SE stellt sich vor und nennt die Ergebnisziele (Sichtbarkeit clientseitiger Bedrohungen, PCI-Compliance, Echtzeit-Erkennung)
  3. Phase 1 ausführen (Schritte 1–7) — Infrastrukturerstellung und -verifizierung; alle Phase-1-Prüfungen müssen BESTANDEN sein, bevor fortgefahren wird
  4. Phase 2 ausführen (Schritte 8–9) — Angriffssimulation und Erkennungsverifizierung via API; KI-Assistenten mit Browser-Automatisierung führen die Browser-Schritte direkt aus, Operatoren ohne Browser-Werkzeuge führen sie manuell durch
  5. Phase 3 ausführen — Abwehrmaßnahmen für alle erkannten Domains anwenden, Angriff wiederholen, verifizieren, dass die Blockierung wirksam ist
  6. Abschluss — Ergebnisziele wiederholen, Belege aus jeder Phase zusammenfassen, wichtige Erkennungen und Abwehrmaßnahmen hervorheben
  7. Q&A — improvisierte Phase, Demo bleibt aktiv, SE beantwortet Publikumsfragen und stellt Rückfragen
  8. Abbau (nach dem Meeting) — Phase 4, explizite Operatorbestätigung erforderlich, alle Objekte in umgekehrter Abhängigkeitsreihenfolge löschen, saubere Umgebung bestätigen

Wenn ein Schritt FEHLSCHLAG zurückgibt, stoppen Sie, melden Sie den Fehlschlag mit dem relevanten Link zur Fehlerbehebung und fahren Sie erst danach fort.

  • Ein F5-XC-API-Token — generieren Sie eines unter VerwaltungAnmeldeinformationenAPI-Anmeldeinformationen
  • curl und jq lokal installiert
  • Ein Namespace mit Berechtigungen zur Erstellung von Healthchecks, Ursprungspools und HTTP-Load-Balancern

Erstellen Sie eine .env-Datei mit Ihren Umgebungswerten. Eine Vorlage ist im Repository enthalten:

Terminal-Fenster
cp .env.example .env

Bearbeiten Sie .env mit Ihren tatsächlichen Werten:

.env
# Erforderlich — Ihre Umgebung
F5XC_API_TOKEN=example-api-token
F5XC_API_URL=https://example-tenant.console.ves.volterra.io
F5XC_DOMAINNAME=app.example.com
F5XC_EMAIL=user@example.com
F5XC_LB_NAME=example-lb-name
F5XC_NAMESPACE=example-namespace
F5XC_ROOT_DOMAIN=example.com
# Optional — Juice-Shop-Demo-Standardwerte werden verwendet, wenn nicht gesetzt
# F5XC_HC_NAME=csd-hc
# F5XC_ORIGIN_IP=44.232.69.192
# F5XC_ORIGIN_POOL=csd-origin
# F5XC_ORIGIN_PORT=3000

Sourcen Sie die Datei, um Variablen in Ihre Shell-Sitzung zu laden:

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

Jeder xTOKENx-Platzhalter in den curl-Befehlen entspricht direkt einer Umgebungsvariable — beispielsweise entspricht xF5XC_API_TOKENx $F5XC_API_TOKEN. Sie können diese Werte über das interaktive Formular am Anfang der Seite ersetzen oder einen KI-Assistenten wie Claude Code Ihre .env lesen und die Befehle für Sie erstellen lassen.

TokenStandardBeschreibung
xF5XC_API_URLxhttps://example-tenant.console.ves.volterra.ioXC-Konsole API-URL
xF5XC_API_TOKENxexample-api-tokenAPI-Anmeldeinformations-Token
xF5XC_EMAILxuser@example.comCSD-Benachrichtigungs-E-Mail-Adresse
xF5XC_NAMESPACExexample-namespaceNamespace
xF5XC_LB_NAMExexample-lbHTTP-Load-Balancer-Basisname (erstellt ${name}-http und ${name}-https)
xF5XC_DOMAINNAMExapp.example.comZu schützender FQDN
xF5XC_ROOT_DOMAINxexample.comStammdomäne (eTLD+1) für CSD-geschützte Domain
xF5XC_ORIGIN_POOLxcsd-originName des Ursprungspools
xF5XC_ORIGIN_IPx44.232.69.192IP des Ursprungsservers
xF5XC_ORIGIN_PORTx3000Port des Ursprungsservers
xF5XC_HC_NAMExcsd-hcHealthcheck-Name

Dieser Abschnitt fasst den vollständigen Übungsworkflow für Scripting oder Automatisierung zusammen.

  1. Repository klonen und die Umgebungsvorlage kopieren: cp .env.example .env
  2. .env mit Ihrer Mandanten-URL, Ihrem API-Token, Namespace und Domainwerten bearbeiten
  3. Umgebung sourcen: set -a && source .env && set +a
  4. Jede Phase der Reihe nach ausführen und BESTANDEN bei jedem Belegblock verifizieren, bevor Sie zur nächsten Phase übergehen

Werte werden mithilfe des deterministischen Protokolls aufgelöst, das im Ausführungsprotokoll für KI-Assistenten definiert ist:

  1. .env-DateiKEY=VALUE-Paare aus dem Stammverzeichnis des Repositorys parsen
  2. Shell-Umgebungenv | grep F5XC_ auf exportierte Werte prüfen
  3. Platzhalter-Erkennung — jeden Wert, der einem Platzhalterstandard entspricht (z. B. example-api-token, example-namespace), als fehlend markieren
  4. Operator befragen — für jede fehlende erforderliche Variable nachfragen
  5. Standardwerte anwenden — eingebaute Standardwerte für fehlende optionale Variablen verwenden
  6. Bestätigen — die aufgelöste Variablentabelle anzeigen und auf Operatorgenehmigung warten
  1. Phase 1 — Aufbauen: Infrastruktur bereitstellen (Healthcheck, Ursprungspool, HTTP-LB + HTTPS-LB), DNS konfigurieren, CSD aktivieren, geschützte Domain registrieren, alle Komponenten verifizieren. Der HTTP-LB ist das primäre Demo-Ziel; der HTTPS-LB ist optional.
  2. Phase 2 — Angreifen: Angriffssimulation in einem Browser mit http://-URLs ausführen, 5–10 Minuten warten, Erkennungen via API verifizieren (/scripts, /detected_domains, /formFields)
  3. Phase 3 — Abwehren: Saubere Baseline bestätigen, Angriff ausführen (Nachweis vorher), jede Domain per POST an /mitigated_domains senden, Anwenden der Abwehrmaßnahmen verifizieren, Angriff mit http://-URLs wiederholen (Nachweis nachher), Vorher-Nachher-Vergleich präsentieren
  4. Phase 4 — Abbauen (erfordert explizite menschliche Bestätigung): HTTPS-LB löschen → HTTP-LB → Ursprungspool → DNS-Zonenbereinigung (nur manuelle Einträge) → Healthcheck → geschützte Domain. Die DNS-Zone nicht löschen.
TokenBeschreibungStandard
xF5XC_API_URLxXC-Konsole API-URLhttps://example-tenant.console.ves.volterra.io
xF5XC_API_TOKENxAPI-Anmeldeinformations-Token(vom Benutzer angegeben)
xF5XC_EMAILxCSD-Benachrichtigungs-E-Mailuser@example.com
xF5XC_NAMESPACExNamespaceexample-namespace
xF5XC_LB_NAMExHTTP-Load-Balancer-Basisname (erstellt ${name}-http und ${name}-https)example-lb
xF5XC_DOMAINNAMExZu schützender FQDNapp.example.com
xF5XC_ROOT_DOMAINxStammdomäne (eTLD+1)example.com
xF5XC_ORIGIN_POOLxName des Ursprungspoolscsd-origin
xF5XC_ORIGIN_IPxIP des Ursprungsservers44.232.69.192
xF5XC_ORIGIN_PORTxPort des Ursprungsservers3000
xF5XC_HC_NAMExHealthcheck-Namecsd-hc

Die HTTP-Load-Balancer-Spezifikation verwendet oneOf-Auswahlgruppen, bei denen pro Gruppe genau eine Option gesetzt sein muss. Das Setzen von null oder mehr als einer Option in einer Gruppe verursacht einen 422-Fehler.

Wichtige CSD-bezogene Auswahlmöglichkeiten:

AuswahlgruppeOptionenCSD-Standard
client_side_defense_choiceclient_side_defense, disable_client_side_defenseclient_side_defense
java_script_choice (verschachtelt in CSD)disable_js_insert, js_insert_all_pages, js_insert_all_pages_except, js_insertion_rulesjs_insert_all_pages

Listener-Typ-Auswahl (HTTP vs. HTTPS):

Die Demo erstellt zwei LBs mit unterschiedlichen Listener-Konfigurationen:

LBListener-AuswahlKonfiguration
${F5XC_LB_NAME}-http (primär)http"http": { "dns_volterra_managed": true, "port": 80 }
${F5XC_LB_NAME}-https (sekundär)https_auto_cert"https_auto_cert": { "http_redirect": true, "port": 443, ... }

Die Schlüssel http und https_auto_cert schließen sich gegenseitig aus — jeder LB verwendet genau einen.

Verschachtelte HTTPS-Auto-Cert-Auswahlmöglichkeiten (nur sekundärer LB):

AuswahlgruppeOptionenStandard
Portport (Zahl)443
server_header_choicedefault_header, server_name, append_server_namedefault_header
path_normalize_choiceenable_path_normalize, disable_path_normalizeenable_path_normalize
mtls_choiceno_mtls, use_mtlsno_mtls
default_loadbalancer_choicedefault_loadbalancer, non_default_loadbalancerdefault_loadbalancer

Verschachtelte single_lb_app-Auswahlmöglichkeiten (ML-Konfiguration):

Das single_lb_app-Objekt hat eigene erforderliche oneOf-Gruppen. Das Setzen von single_lb_app: \{\} ohne diese verschachtelten Auswahlmöglichkeiten verursacht einen 400-Fehler.

AuswahlgruppeOptionenStandard
api_discovery_choicedisable_discovery, enable_discoverydisable_discovery
ddos_detection_choicedisable_ddos_detection, enable_ddos_detectiondisable_ddos_detection
malicious_user_detection_choicedisable_malicious_user_detection, enable_malicious_user_detectiondisable_malicious_user_detection

Weitere LB-Ebenen-Auswahlmöglichkeiten (alle auf Deaktivieren/Standard gesetzt):

disable_rate_limit · no_service_policies · round_robin · disable_waf · no_challenge · disable_bot_defense · disable_api_definition · disable_api_discovery · disable_ip_reputation · disable_malicious_user_detection · single_lb_app · disable_trust_client_ip_headers · user_id_client_ip · disable_threat_mesh · l7_ddos_action_default · system_default_timeouts · default_sensitive_data_policy · disable_malware_protection · disable_api_testing

  • 401 Unauthorized — API-Token ist ungültig oder abgelaufen. Neu generieren unter VerwaltungAnmeldeinformationen.
  • 403 Forbidden — Token fehlen Berechtigungen für den Namespace. Rollenbindungen prüfen.
  • 404 Not Found — Namespace- oder Objektname ist falsch. Objekte auflisten mit GET /api/config/namespaces/\{namespace\}/\{object_type\}.
  • 409 Conflict — Objekt existiert bereits. Bei geschützten Domains bedeutet ein 409 mit “domain already exists (in uriList)”, dass die Stammdomäne bereits beim Mandanten registriert ist — dies ist eine Erfolgsbedingung, kein Fehler. Bei anderen Objekten zuerst löschen oder PUT zum Aktualisieren verwenden.
  • 422 Unprocessable Entity — JSON-Schema-Validierung fehlgeschlagen. Häufige Ursachen: fehlende oneOf-Auswahl, mehrere Auswahlmöglichkeiten in derselben Gruppe gesetzt, falscher Feldtyp. Fehlermeldung auf das spezifische Feld prüfen.
  • Objektlimit erschöpft (Fehlercode 8, Meldung "Object kind {kind} has exhausted limits({N})") — Mandant hat ein Objektkontingentlimit erreicht. Die API gibt HTTP 200 mit einem JSON-Fehler-Body zurück, der "code": 8 enthält, nicht HTTP 429. Sie können die Kontingentkapazität proaktiv vor diesem Fehler mit der Kontingentnutzungs-API prüfen (GET /api/web/namespaces/system/quota/usage?namespace=system). Das Verhalten hängt vom Objekttyp ab:
    • Healthcheck (Limit ~150): Nicht blockierend — Phase 1 Schritt 1 überspringen und den Ursprungspool ohne Healthcheck-Referenz erstellen. CSD ist nicht von der Gesundheitsüberwachung abhängig.
    • Endpunkt (Limit ~500): Blockierend — Endpunkte sind Unterobjekte, die innerhalb von Ursprungspools erstellt werden. Wenn dieses Limit erreicht wird, schlägt die Ursprungspool-Erstellung fehl. Ungenutzte Ursprungspools löschen (was ihre Endpunkt-Unterobjekte freigibt) oder den Administrator kontaktieren, um das Mandantenlimit zu erhöhen.
    • Ursprungspool: Blockierend — ungenutzte Ursprungspools löschen oder den Administrator kontaktieren.
    • HTTP-Load-Balancer: Blockierend — ungenutzte Load Balancer löschen oder den Administrator kontaktieren.
    • Geschützte Domain: Blockierend — ungenutzte geschützte Domains löschen oder den Administrator kontaktieren.

Wenn Phase 1 Schritt 2 (Healthcheck-Verknüpfung verifizieren) ein leeres Array [] anzeigt:

  1. Ursprungspool löschen: DELETE /api/config/namespaces/{namespace}/origin_pools/{pool_name}
  2. Sicherstellen, dass der Healthcheck vorhanden ist: GET /api/config/namespaces/{namespace}/healthchecks/{hc_name}
  3. Ursprungspool mit der richtigen Healthcheck-Referenz neu erstellen

Wenn der state des Load Balancers nach Phase 1 Schritt 4 bei VIRTUAL_HOST_PENDING_A_RECORD bleibt:

  1. DNS-Zone verifizieren (nur F5 XC verwaltetes DNS):

    Terminal-Fenster
    curl -s \
    -H "Authorization: APIToken xF5XC_API_TOKENx" \
    "xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx" \
    | jq '.metadata.name'

    Ein 404 bedeutet, dass die DNS-Zone in F5 XC nicht erstellt wurde.

  2. allow_http_lb_managed_records prüfen — wenn die Zone vorhanden ist, der LB aber ausstehend ist, sind verwaltete Einträge möglicherweise deaktiviert:

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

    Wenn false oder null, aktivieren Sie dies mit dem PUT-Befehl in Phase 1 Schritt 4, Option A.

  3. Externes DNS — wenn F5 XC nicht autoritativ ist, erstellen Sie die A- und ACME-CNAME-Einträge manuell bei Ihrem DNS-Anbieter (siehe Phase 1 Schritt 4, Option B).

  4. Auflösung verifizieren — nach der DNS-Korrektur bestätigen:

    Terminal-Fenster
    dig +short xF5XC_DOMAINNAMEx A

    Wenn der A-Eintrag aufgelöst wird, wechselt der LB zu VIRTUAL_HOST_READY. Alle 30 Sekunden abfragen, bis zu 4 Iterationen (insgesamt 2 Minuten). Wenn nach 2 Minuten noch VIRTUAL_HOST_PENDING_A_RECORD, DNS-Propagation erneut prüfen und dem Operator melden.

CSD muss auf Mandantenebene aktiviert sein. Wenden Sie sich an Ihren F5-XC-Administrator, um die Clientseitige Abwehr für Ihren Mandanten zu aktivieren. Dies ist eine mandantenweite Einstellung, die nicht über die API konfiguriert werden kann.

  1. Sicherstellen, dass CSD auf Mandantenebene aktiviert ist (Phase 1 Schritt 5)
  2. Bestätigen, dass der Load Balancer client_side_defense in der Spezifikation gesetzt hat
  3. Prüfen, ob der JS-Konfigurationsendpunkt ein scriptTag zurückgibt
  4. Die geschützte Domain in einem Browser besuchen und den Seitenquelltext anzeigen, um zu bestätigen, dass das Skript injiziert wird

Registrierung der geschützten Domain gibt 409 zurück

Abschnitt betitelt „Registrierung der geschützten Domain gibt 409 zurück“

Ein 409 mit “domain already exists (in uriList)” bedeutet, dass die Stammdomäne bereits beim Mandanten registriert ist. Geschützte Domains sind mandantenweit — sie gehören zu keinem einzelnen Namespace. Dies ist eine Erfolgsbedingung: Die Domain ist bereits geschützt und es sind keine weiteren Maßnahmen erforderlich. Fahren Sie mit Phase 1 Schritt 7 fort.

Wenn der cert_state des HTTPS-LB AutoCertDomainRateLimited anzeigt, bedeutet dies, dass Let’s Encrypt die Zertifikatsausstellung für diese Domain ratenlimitiert hat. Dies ist in Demo-Umgebungen zu erwarten, in denen Infrastruktur häufig erstellt und zerstört wird.

Auswirkung: Der HTTPS-LB liefert keinen Datenverkehr, bis das Ratenlimit zurückgesetzt wird (typischerweise 1 Stunde). Der HTTP-LB ist vollständig unbeeinträchtigt — der gesamte Demo-Datenverkehr läuft normal über http://.

Lösung: Für den Demo-Fortschritt ist keine Aktion erforderlich. Der HTTP-LB (${F5XC_LB_NAME}-http) ist das primäre Demo-Ziel und hängt nicht von der Zertifikatsbereitstellung ab. Wenn HTTPS gewünscht wird, warten Sie, bis das Ratenlimit zurückgesetzt wird, und das Zertifikat wird automatisch bereitgestellt.

Zertifikat steckt fest — Saubere Neuerstellung (optional)

Abschnitt betitelt „Zertifikat steckt fest — Saubere Neuerstellung (optional)“

Wenn das Zertifikat des HTTPS-LB länger als 15 Minuten in DomainChallengePending oder PreDomainChallengePending verbleibt, ist der schnellste Wiederherstellungspfad das Löschen des HTTPS-LB und dessen Neuerstellung. Mit bereits konfigurierter DNS-Zone (aktivierte verwaltete Einträge) erzeugt die saubere Neuerstellung typischerweise innerhalb von 5–7 Minuten CertificateValid — sofern kein Ratenlimit besteht.

  1. HTTPS-Load-Balancer löschen: DELETE .../http_loadbalancers/${F5XC_LB_NAME}-https
  2. 30 Sekunden auf Plattformbereinigung warten
  3. HTTPS-Load-Balancer neu erstellen (Phase 1 Schritt 3)
  4. Zertifikatsstatus überwachen (Phase 1 Schritt 7) — innerhalb von 5–10 Minuten CertificateValid erwarten

Die kanonische F5 Distributed Cloud API-Spezifikation ist verfügbar unter:

https://docs.cloud.f5.com/docs-v2/downloads/f5-distributed-cloud-open-api.zip

Diese ZIP enthält OpenAPI-3.0-Spezifikationen für alle API-Gruppen, einschließlich ves.io.schema.views.http_loadbalancer, ves.io.schema.healthcheck, ves.io.schema.origin_pool und ves.io.schema.shape.csd. Verwenden Sie diese Spezifikationen zur Validierung von JSON-Nutzlasten und zur Entdeckung zusätzlicher Felder.