تخطَّ إلى المحتوى

عرض توضيحي

يرشدك هذا الدليل عبر تمرين الدفاع من جهة العميل الكامل على F5 Distributed Cloud باستخدام API — مُنظَّمًا في أربع مراحل يمكن لمساعد الذكاء الاصطناعي أو المشغّل البشري تنفيذها من البداية إلى النهاية. تتضمن كل خطوة أمر curl جاهزًا للتشغيل مع قيم نائبة يمكنك تخصيصها باستخدام النموذج أعلى الصفحة، أو ملف .env، أو أي أداة أتمتة.

المرحلةالهدفالخطوات
المرحلة 1 — البناءنشر والتحقق من صحة البنية التحتية الكاملة لـ CSDالخطوات 1–7
المرحلة 2 — الهجومتوليد حركة مرور هجوم محاكاة والتأكد من أن CSD اكتشفهاالخطوات 8–9
المرحلة 3 — التخفيفإثبات ما قبل/بعد التخفيف — تشغيل الهجوم، تطبيق التخفيفات، إعادة تشغيل الهجوم، المقارنةالخطوات 1–6
المرحلة 4 — التفكيكإزالة جميع كائنات النشر بعد التأكيد الصريحالتفكيك

قبل البدء في المرحلة 1، تحقق من أن البيئة نظيفة. قم بتشغيل عمليات فحص API هذه لتحديد ما إذا كانت توجد كائنات متبقية من تشغيل سابق:

Terminal window
# فحص جميع كائنات المرحلة 1 وحساب حالة البيئة
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')
# إذا كان HTTPS LB موجودًا، احضر الجسم للكشف عن حالة skeleton
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
# احسب حالة البيئة الحتمية
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
)
}'

التحقق من التخطي المباشر

Section titled “التحقق من التخطي المباشر”

عندما تكون جميع كائنات المرحلة 1 موجودة (200) وتخطط للتخطي إلى المرحلة 2، قم بتشغيل أوامر التحقق من الخطوة 7 للمرحلة 1 للتأكد من صحة البنية التحتية قبل التخطي. استخدم الأوامر المحددة من المرحلة 1 — الخطوة 7: التحقق:

  1. دقة DNS: dig +short xF5XC_DOMAINNAMEx A
  2. حالة HTTP LB: GET .../http_loadbalancers/xF5XC_LB_NAMEx-http مُمرَّر إلى jq '{state: .spec.state}' — يجب أن يُظهر VIRTUAL_HOST_READY
  3. إعداد CSD JS: GET .../js_configuration — يجب أن يحتوي على scriptTag
  4. حالة CSD: GET .../status مُمرَّر إلى jq '{configured: .isConfigured, enabled: .isEnabled}' — يجب أن يكون كلاهما true

يجب أن تجتاز جميع الفحوصات المطلوبة (DNS-1، LB-1، CSD-1، CSD-2) قبل التخطي إلى المرحلة 2. إذا فشل أي فحص، نفّذ المرحلة 1 بدءًا من الخطوة الفاشلة.

مصفوفة التحقق من الجاهزية

Section titled “مصفوفة التحقق من الجاهزية”

يتحقق الفحص التمهيدي أعلاه من أن البيئة نظيفة. تتحقق مصفوفة الجاهزية أدناه من أن البيئة قادرة — أي أن جميع المتطلبات الأساسية والحصص والاتصالية وخدمات المنصة موجودة لعرض توضيحي ناجح. قم بتشغيل هذه المصفوفة قبل كل اجتماع كجزء من مرحلة الإعداد.

كل فحص يحمل معرّف اختبار، ومستوى (T0–T5)، ومعايير PASS/FAIL/WARN، ومسار معالجة. المستويات متسلسلة — يُعيق الفشل في مستوى سابق تشغيل المستويات اللاحقة.

المستوىالفئةيحجب العرض التوضيحي؟الغرض
T0الاتصال والمصادقةنعمهل يمكننا الوصول إلى المنصة والمصادقة؟
T1الحصص والسعةنعم (إذا كانت عند الحد الأقصى)هل يوجد مجال لإنشاء كائنات العرض التوضيحي؟
T2متطلبات المنصة الأساسيةنعمهل تم تكوين الخدمات على مستوى المستأجر؟
T3صحة المصدرتحذيرهل يستجيب تطبيق الواجهة الخلفية؟
T4البيئة نظيفةمعالجة تلقائيةهل توجد كائنات متبقية من تشغيل سابق؟
T5جاهزية الشهادةمعلوماتيهل سيعمل HTTPS، أم يجب التخطيط لـ HTTP فقط؟

تؤكد هذه الفحوصات أن مضيف التنفيذ يمكنه الوصول إلى F5 XC API وأن بيانات الاعتماد صالحة.

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

PF-T0-2: الوصول إلى مساحة الاسم

Section titled “PF-T0-2: الوصول إلى مساحة الاسم”
Terminal window
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 window
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
)
}'

تختبر المسبارات غير المدمِّرة أذونات القراءة والكتابة لكل نوع كائن يحتاجه العرض التوضيحي. يتم اختبار القراءة عبر GET على نقاط نهاية القوائم. يتم اختبار الكتابة عبر DELETE على كائنات معروفة غير موجودة — تُعيد API القيمة 403 إذا رفض RBAC العملية، أو 404 إذا كانت العملية مسموحًا بها لكن الكائن غير موجود. تتجنب هذه التقنية عديمة الآثار الجانبية إنشاء كائنات مسبار مؤقتة.

Terminal window
PROBE_NAME="rbac-probe-nonexistent"
# مسبارات القراءة
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")
# مسبارات الكتابة (غير مدمِّرة: DELETE/cascade_delete على كائنات غير موجودة)
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")
# احسب مصفوفة الأذونات الحتمية
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("; ")
)
}'

تستعلم هذه الفحوصات عن Quota Usage API الخاص بالمستأجر لتحديد الحدود والاستخدام الحالي والسعة المتبقية لكل نوع كائن يحتاجه العرض التوضيحي. يحل هذا محل اختبار المسبار والحذف باستدعاء API واحد للقراءة فقط يُبلّغ بأرقام دقيقة.

PF-T1-0: بوابة استخدام الحصص

Section titled “PF-T1-0: بوابة استخدام الحصص”

استعلم عن نقطة نهاية استخدام الحصص على مستوى المستأجر واحسب حالة PASS/WARN/FAIL حتمية لكل نوع كائن يحتاجه العرض التوضيحي. تتطلب هذه النقطة مساحة اسم system. يفحص استدعاء API واحد جميع حصص المنصة دفعةً واحدة.

تُحدد البوابة مصفوفة demo_needs التي تُحدد كمية كل نوع كائن سيستهلكه العرض التوضيحي، وما إذا كان النوع مطلوبًا، والحد الأدنى اللازم للمتابعة. يقارن فلتر jq قيمة remaining مع needed ويحسب حقل status بشكل حتمي — لا يلزم تفسير المشغّل.

Terminal window
# الخطوة 1: جلب بيانات الحصص
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces/system/quota/usage?namespace=system" \
> /tmp/quota.json
# الخطوة 2: حساب حالة البوابة
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 هو الحكم الحتمي الوحيد:

  • PASS — جميع أنواع الكائنات لديها remaining >= needed. يمكن للعرض التوضيحي المتابعة.
  • WARN — على الأقل نوع واحد يمتلك سعة منخفضة لكن الحد الأدنى للمتابعة محقق (مثلاً: فتحة LB واحدة فقط متاحة بدلاً من 2، أو حصة الفحص الصحي منتهية). يمكن للعرض التوضيحي المتابعة مع قيود.
  • FAIL — على الأقل نوع مطلوب واحد لديه remaining < min_proceed. لا يمكن للعرض التوضيحي المتابعة حتى يتم تحرير الحصة.

مثال على المخرجات (WARN — نقطة النهاية عند الحد الأقصى، الفحص الصحي ممتلئ تقريبًا):

{
"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الإجراء
PASSتابع إلى PF-T1-4 (فحص النطاق المحمي)، ثم T2
WARNسجّل القيود في تقرير الجاهزية، تابع بقدرة منخفضة
FAILتوقف — أبلغ عن الأنواع المنتهية وخطوات المعالجة أدناه

المعالجة حسب النوع:

النوعالمعالجة
healthcheckاحذف الفحوصات الصحية غير المستخدمة لتحرير السعة. يتابع العرض التوضيحي بدون فحص صحي (CSD لا يتطلب فحصًا صحيًا).
origin_poolاحذف مجمّعات المصادر غير المستخدمة أو تواصل مع مسؤولك لزيادة حد المستأجر.
endpointاحذف مجمّعات المصادر غير المستخدمة في مساحات الاسم الأخرى لتحرير سعة نقاط النهاية (نقاط النهاية هي كائنات فرعية لمجمّعات المصادر)، أو تواصل مع مسؤولك.
http_loadbalancerاحذف موازنات التحميل غير المستخدمة أو تواصل مع مسؤولك. إذا كانت فتحة واحدة فقط متاحة، سيتم إنشاء HTTP LB (الأساسي) لكن سيتم تخطي HTTPS LB (الثانوي).

لا تظهر النطاقات المحمية لـ CSD في Quota Usage API الخاص بالمنصة. استخدم فحصًا مستندًا إلى المسبار: أنشئ نطاقًا محميًا كمسبار واحذفه فورًا.

Terminal window
# أنشئ المسبار والتقط كود HTTP وجسم الاستجابة
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')
# احسب الحالة
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
)
}'
# احذف المسبار (404 متوقع إذا حدث 409)
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

احتياطي: فحوصات الحصص المستندة إلى المسبار

Section titled “احتياطي: فحوصات الحصص المستندة إلى المسبار”

إذا فشل PF-T1-0 (أعادت Quota Usage API قيمة 403 أو 404 أو تنسيقًا غير متوقع)، ارجع إلى فحوصات المسبار والحذف للفحوصات الصحية ومجمّعات المصادر ونقاط النهاية وحصص موازن التحميل. تُنشئ هذه الفحوصات كائنًا مؤقتًا وتحذفه فورًا — إذا أعادت عملية الإنشاء رمز خطأ 8 مع رسالة “exhausted limits”، فالحصة ممتلئة.

يستخدم كل مسبار احتياطي نفس النمط: أنشئ كائنًا مؤقتًا، واحسب حالة حتمية من الاستجابة، ثم احذف المسبار. حقل status يساوي PASS إذا تم إنشاء الكائن (.metadata.name موجود)، أو WARN أو FAIL إذا كان رمز الخطأ 8 (الحدود منتهية)، اعتمادًا على ما إذا كان النوع مطلوبًا.

مسبار الفحص الصحي (WARN إذا كان منتهيًا — الفحوصات الصحية اختيارية لـ CSD):

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

مسبار مجمّع المصادر ونقطة النهاية (FAIL إذا كانا منتهيَين — كلاهما مطلوبان):

Terminal window
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 (FAIL إذا كان منتهيًا — موازنات التحميل مطلوبة):

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

T2: متطلبات المنصة الأساسية

Section titled “T2: متطلبات المنصة الأساسية”

تتحقق هذه الفحوصات من الخدمات على مستوى المستأجر التي يعتمد عليها العرض التوضيحي.

PF-T2-1: حالة CSD على مستوى المستأجر

Section titled “PF-T2-1: حالة CSD على مستوى المستأجر”
Terminal window
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 window
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
)
}'

PF-T2-3: تفعيل سجلات DNS المُدارة

Section titled “PF-T2-3: تفعيل سجلات DNS المُدارة”

قم بتشغيل هذا فقط إذا أعاد PF-T2-2 قيمة 200 (منطقة DNS الخاصة بـ F5 XC موجودة).

فحص الحالة الحالية:

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

المعالجة التلقائية عند الحاجة: إذا كانت status تساوي WARN وأظهر PF-T2-4 خوادم أسماء F5 XC (ns1.f5clouddns.com، ns2.f5clouddns.com)، مكّن السجلات المُدارة تلقائيًا باستخدام GET+PUT:

Terminal window
# احصل على إعداد المنطقة الحالية
ZONE_CONFIG=$(curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx")
# حدّث مع تفعيل السجلات المُدارة
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 .

ثم أعد الفحص للتأكد من أن التحديث قد تم:

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'
النتيجةسلطة DNSالحالةالمعالجة
trueأيPASSسيتم إنشاء سجلات DNS المُدارة بواسطة LB تلقائيًا
false/nullF5 XCمعالجة تلقائيةمكّن عبر GET+PUT، تحقق، أبلغ عن النتيجة
false/nullخارجيمعلوماتيالسجلات المُدارة لا تنطبق على DNS الخارجي — الخطوة 4 من المرحلة 1 ستستخدم الخيار B (إنشاء السجل يدويًا)
فشلت المعالجة التلقائيةF5 XCFAILقد يفتقر الرمز إلى صلاحية الكتابة في مساحة الاسم system — تواصل مع مسؤول المستأجر
Terminal window
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
)
}'

تتحقق هذه الفحوصات من إمكانية الوصول إلى تطبيق الواجهة الخلفية.

فحص حالة التخطي: احسب ما إذا كان عنوان IP المصدر هو عنوان TEST-NET وفق RFC 5737 قبل تشغيل اختبارات الاتصالية:

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

إذا كانت status تساوي SKIP، سجّل PF-T3-1 وPF-T3-2 كـ SKIP وانتقل إلى T4. وإلا، قم بتشغيل الفحوصات أدناه.

PF-T3-1: اتصالية خادم المصدر

Section titled “PF-T3-1: اتصالية خادم المصدر”
Terminal window
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
)
}'

PF-T3-2: يقدم المصدر محتوى HTML

Section titled “PF-T3-2: يقدم المصدر محتوى HTML”

قم بالتشغيل فقط إذا أعاد PF-T3-1 حالة HTTP صالحة:

Terminal window
curl -s --max-time 10 "http://xF5XC_ORIGIN_IPx:xF5XC_ORIGIN_PORTx/" \
| grep -qi '</html>' && echo "PASS: HTML content" || echo "WARN: No HTML detected"
النتيجةالحالةالمعالجة
PASS: HTML contentPASSيقدم المصدر صفحات HTML (مطلوب لحقن CSD JS)
WARN: No HTML detectedWARNقد يكون المصدر خدمة API فقط أو يُعيد محتوى غير HTML — يتطلب حقن CSD JS استجابات صفحة HTML

تتحقق هذه الفحوصات من عدم وجود كائنات تكوين F5 XC مُسمّاة متبقية من تشغيل عرض توضيحي سابق — موازنات تحميل HTTP وHTTPS ومجمّعات المصادر والفحوصات الصحية والنطاقات المحمية والنطاقات المخففة. يتعلق T4 بتنظيف الكائنات: ما إذا كانت كائنات API التي ستتعارض مع إنشاء المرحلة 1 لا تزال موجودة. لا يختبر عناوين IP أو اتصالية الشبكة أو صحة المصدر (تلك المخاوف تنتمي إلى T3).

قم بتشغيل الأوامر الستة للفحص التمهيدي من قسم الفحص التمهيدي أعلاه. طبّق منطق القرار لتحديد الخطوات التالية. إذا كانت الكائنات موجودة، يتم إجراء التفكيك التلقائي أثناء مرحلة الإعداد (لا حاجة للتأكيد).

تحقق أيضًا من وجود كائنات مسبار قديمة من تشغيلات فحص تمهيدي سابقة متقطعة واحذفها. تُنشأ هذه المسبارات فقط عندما تكون Quota Usage API غير متاحة وتم استخدام فحوصات المسبار الاحتياطية، أو لمسبار النطاق المحمي (PF-T1-4) الذي يستخدم دائمًا الفحص المستند إلى المسبار:

Terminal window
# تنظيف المسبارات القديمة (احذف بأي ترتيب — المسبارات ليس لها تبعيات)
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

يُعيد كل DELETE قيمة 200 (كائن {} فارغ) إذا كان الكائن موجودًا، أو 404 إذا لم يكن — كلاهما متوقع.

تقيّم هذه الفحوصات ما إذا كان HTTPS سيعمل أو يجب التخطيط للعرض التوضيحي بـ HTTP فقط.

PF-T5-1: سجل إصدار الشهادة الأخير

Section titled “PF-T5-1: سجل إصدار الشهادة الأخير”

تحقق مما إذا كانت شهادة Let’s Encrypt قد صدرت مؤخرًا للنطاق التجريبي. يمكن أن تؤدي دورات الإنشاء/الحذف المتكررة إلى استنفاد حد المعدل الأسبوعي (5 شهادات مكررة في الأسبوع لكل نطاق).

PF-T5-2: حالة شهادة HTTPS LB الحالية

Section titled “PF-T5-2: حالة شهادة HTTPS LB الحالية”

قم بالتشغيل فقط إذا كان HTTPS LB موجودًا من تشغيل سابق (وجد PF-T4 كائنات):

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

بعد تشغيل جميع المستويات، قدّم تقرير جاهزية موحدًا:

## جاهزية العرض التوضيحي: جاهز / غير جاهز / جاهز مع تحذيرات
### T0: الاتصال والمصادقة
| الفحص | النتيجة | الحالة |
|---|---|---|
| PF-T0-1: اتصالية API | 200 | PASS |
| PF-T0-2: الوصول إلى مساحة الاسم | 200 | PASS |
| PF-T0-3: الوصول إلى CSD API | 200 | PASS |
### T1: الحصص والسعة
| الفحص | النوع | الحد | الاستخدام | المتبقي | المطلوب | الحالة |
|---|---|---|---|---|---|---|
| PF-T1-0: بوابة استخدام الحصص | `healthcheck` | 150 | 148 | 2 | 1 | PASS |
| PF-T1-0: بوابة استخدام الحصص | `origin_pool` | unlimited | 420 | unlimited | 1 | PASS |
| PF-T1-0: بوابة استخدام الحصص | `endpoint` | 500 | 498 | 2 | 1 | PASS |
| PF-T1-0: بوابة استخدام الحصص | `http_loadbalancer` | unlimited | 116 | unlimited | 2 | PASS |
| PF-T1-0: بوابة استخدام الحصص | **البوابة** | — | — | — | — | **PASS** |
| PF-T1-4: النطاق المحمي | — | — | — | — | 1 | PASS (مسبار) |
### T2: متطلبات المنصة الأساسية
| الفحص | النتيجة | الحالة |
|---|---|---|
| PF-T2-1: حالة CSD على مستوى المستأجر | مُكوَّن + مُفعَّل | PASS |
| PF-T2-2: وجود منطقة DNS | 200 | PASS |
| PF-T2-3: سجلات DNS المُدارة | true | PASS |
| PF-T2-4: سلطة خادم أسماء DNS | f5clouddns.com | PASS |
### T3: صحة المصدر
| الفحص | النتيجة | الحالة |
|---|---|---|
| PF-T3-1: اتصالية المصدر | عنوان TEST-NET (192.0.2.1) | SKIP |
| PF-T3-2: محتوى HTML | عنوان TEST-NET | SKIP |
### T4: البيئة نظيفة
| الفحص | النتيجة | الحالة |
|---|---|---|
| HTTP LB | 404 | PASS |
| HTTPS LB | 404 | PASS |
| مجمّع المصادر | 404 | PASS |
| الفحص الصحي | 404 | PASS |
| النطاقات المحمية | 0 | PASS |
| النطاقات المخففة | 0 | PASS |
### T5: جاهزية الشهادة
| الفحص | النتيجة | الحالة |
|---|---|---|
| PF-T5-2: حالة الشهادة | SKIP (لا يوجد HTTPS LB) | INFO |
### التحذيرات
- (أدرج أي عناصر WARN أو INFO مع السياق)

قواعد الحالة الإجمالية:

الحالةالحكم
جميع فحوصات T0–T4 PASSجاهز
جميع فحوصات T0–T4 PASS لكن T3 أو T5 لديها WARN/INFOجاهز مع تحذيرات
أي فحص من T0 أو T1 أو T2 FAILغير جاهز — أصلح قبل المتابعة
T4 يحتوي على كائنات متبقيةمعالجة تلقائية (تفكيك)، ثم إعادة الفحص

بروتوكول تنفيذ مساعد الذكاء الاصطناعي

Section titled “بروتوكول تنفيذ مساعد الذكاء الاصطناعي”

يُحدد هذا القسم سير عمل حتمي لمساعدي الذكاء الاصطناعي (Claude Code وCopilot وغيرها) الذين ينفذون خطوات أتمتة API. يُزيل اتباع هذا البروتوكول التخمين — كل نقطة قرار لها مسار حل محدد.

حلّ كل متغير بهذا الترتيب المحدد. توقف عند أول مصدر يوفر قيمة غير نائبة:

  1. افحص ملف .env — ابحث عن .env في جذر المستودع. إذا كان موجودًا، حلّل جميع أزواج KEY=VALUE.
  2. افحص بيئة الشل — شغّل env | grep F5XC_ للعثور على أي قيم تم تصديرها في الجلسة الحالية.
  3. حدد القيم المفقودة — قارن القيم المحلولة مع الجدول المطلوب/الاختياري أدناه. القيمة “مفقودة” إذا كانت غائبة أو فارغة أو لا تزال مضبوطة على افتراضي نائب (مثلاً، example-api-token أو example-tenant أو example-namespace أو app.example.com أو user@example.com).
  4. اطلب من المشغّل البشري — لكل متغير مطلوب مفقود، اطلب من المشغّل توفير القيمة. لا تتابع حتى يتم حل جميع المتغيرات المطلوبة.
  5. طبّق الافتراضيات — لكل متغير اختياري مفقود، استخدم الافتراضي من الجدول أدناه دون المطالبة.

السلسلة الفارغة = مفقود: يُعامَل المتغير المُصدَّر بقيمة فارغة (مثلاً، F5XC_HC_NAME="") بنفس طريقة المتغير غير المُعيَّن — طبّق الافتراضي. استخدم توسيع معامل الشل (${F5XC_HC_NAME:-csd-hc}) لتطبيق الافتراضيات في خطوة واحدة.

  1. عرض التأكيد — اعرض جدول المتغيرات المحلولة النهائي على المشغّل وانتظر الموافقة قبل تنفيذ أي استدعاءات API.

تجاوز مرحلة الإعداد: أثناء المرحلة 1 من الإعداد، تخطَّ الانتظار في الخطوة 6. اعرض جدول المتغيرات المحلولة للسجل، ثم تابع فورًا. لا تزال الخطوات 1–5 تنطبق — إذا كان أي متغير مطلوب مفقودًا بعد فحص .env والشل، توقف وأبلغ عن المتغيرات المفقودة.

المتغيرات المطلوبة مقابل الاختيارية

Section titled “المتغيرات المطلوبة مقابل الاختيارية”
المتغيرمطلوبالافتراضيالنائب (عامله كمفقود)
F5XC_API_TOKENنعمexample-api-token
F5XC_API_URLنعمhttps://example-tenant.console.ves.volterra.io
F5XC_NAMESPACEنعمexample-namespace
F5XC_DOMAINNAMEنعمapp.example.com
F5XC_ROOT_DOMAINنعمexample.com
F5XC_LB_NAMEنعمexample-lb-name، example-lb
F5XC_EMAILنعمuser@example.com
F5XC_HC_NAMEاختياريcsd-hc
F5XC_ORIGIN_IPاختياري44.232.69.192
F5XC_ORIGIN_POOLاختياريcsd-origin
F5XC_ORIGIN_PORTاختياري3000

يعمل مساعد الذكاء الاصطناعي في أحد ثلاثة أوضاع أثناء العرض التوضيحي:

الوضعمتى يكون نشطًاالسلوك
عاديالافتراضي أثناء الإعداد والتنفيذ والتفكيكالأوامر الموثقة حرفيًا فقط
تصحيحيتنشط تلقائيًا عند الفشلاستكشاف أخطاء إبداعي، تحديث المستندات
أسئلة وأجوبةأثناء مرحلة الأسئلة والأجوبةارتجالي — أوامر خصصية مسموح بها للإجابة على أسئلة الجمهور

الوضع العادي (الافتراضي):

  • يجب أن يأتي كل استدعاء API واستعلام تحقق وأمر شل حرفيًا من ملفات المراحل (المراحل 1–4) أو من قسم الفحص التمهيدي أعلاه
  • استبدل فقط عناصر xTOKENx النائبة بقيم المتغيرات المحلولة
  • لا تُنشئ نقاط نهاية API أو فلاتر jq أو أوامر cURL من المعرفة العامة أو الاستنتاج
  • إذا كان أمر مطلوب غير موثق، توقف وأبلغ المشغّل: “هذه الخطوة للتحقق غير مغطاة بتوثيق المرحلة”

وضع التصحيح (يتنشط تلقائيًا عند الفشل):

  • يتنشط تلقائيًا عندما ينتج عن أمر موثق نتيجة غير متوقعة: استجابة HTTP غير 2xx، أو خطأ في تحليل jq، أو مهلة الأمر، أو جسم استجابة يتناقض مع جدول الأدلة
  • في وضع التصحيح، يجوز لمساعد الذكاء الاصطناعي إنشاء أوامر تشخيصية وفحص استجابات API الخام واختبار تنويعات نقاط النهاية واستخدام استكشاف الأخطاء الإبداعي لإيجاد السبب الجذري
  • ضع بادئة [DEBUG] على جميع مخرجات التصحيح حتى يتمكن المشغّل من تمييز النشاط التشخيصي عن التنفيذ العادي
  • وثّق ما تتعلمه: بعد حل المشكلة، حدّث ملف المرحلة أو قسم استكشاف الأخطاء ذي الصلة بما يلي:
    1. سيناريو الفشل (ما الذي حدث خطأ)
    2. ما تم تجربته ولم ينجح (حتى لا تكرر التشغيلات المستقبلية ذلك)
    3. الحل الناجح (الأمر أو الإصلاح الذي حل المشكلة)
  • الهدف من وضع التصحيح هو إلغاء نفسه — يجب أن تُنتج كل جلسة تصحيح تحديثًا للتوثيق يجعل التنفيذ التالي حتميًا بالكامل
  • بمجرد تحديث التوثيق وحل المشكلة، عد إلى الوضع العادي واستأنف من آخر خطوة موثقة ناجحة
  • إذا تعذّر على وضع التصحيح حل المشكلة، أبلغ المشغّل بالنتائج وتوقف — لا تتابع إلى المرحلة التالية

وضع الأسئلة والأجوبة (أثناء مرحلة الأسئلة والأجوبة):

  • نشط فقط أثناء مرحلة الأسئلة والأجوبة في الاجتماع، بعد اختتام العرض التوضيحي
  • يجوز لمساعد الذكاء الاصطناعي إنشاء استدعاءات API خصصية وتشغيل أوامر تشخيصية والانتقال إلى صفحات غير مُكتَبة وتعديل بيئة العرض التوضيحي المباشرة لتوضيح إجابات أسئلة الجمهور
  • لا بادئة [DEBUG] — هذا سلوك ارتجالي مقصود، وليس استرداد خطأ
  • يستخدم قسم خبرة منتج CSD في DEMO_EXECUTOR.md كقاعدة معرفة لأسئلة المنتج

تراكم initScript مصدر شائع لإخفاقات العرض التوضيحي. كل استدعاء navigate_page مع معامل initScript يُضيف السكريبت إلى قائمة دائمة تعمل على كل تحميل مستند لاحق. اتبع هذه القواعد:

  • انتقل دائمًا إلى about:blank قبل أي تنقل بـ initScript لمسح السكريبتات المتراكمة من التشغيلات السابقة
  • استخدم new_page مع isolatedContext عند التبديل بين مراحل العرض التوضيحي (مثلاً، المرحلة 2 → المرحلة 3) لضمان حالة متصفح نظيفة تمامًا
  • الاسترداد من الصفحات غير المستجيبة — إذا حدثت مهلات take_screenshot أو take_snapshot، فالسياق البرمجي استنفد موارده. استخدم new_page مع isolatedContext لإنشاء سياق جديد، ثم أعد المحاولة من خطوة التنقل إلى about:blank
  • راجع تنبيهات محاكاة هجوم المرحلة 2 للحصول على إرشادات تفصيلية حول إخفاقات المصدر العابرة واسترداد استنفاد الموارد

بعد كل استدعاء API، يجب على مساعد الذكاء الاصطناعي تقديم أدلة منظمة للمشغّل البشري بهذا التنسيق:

خطوات الإنشاء (POST):

الحقلالقيمةالحالة
حالة HTTP200PASS
اسم الكائنcsd-origin
الخاصية الرئيسية(مستخرجة عبر jq)

بعد كل خطوة إنشاء، قم بتشغيل GET للتأكد من وجود الكائن وعرض خصائصه الرئيسية. إذا أعاد GET قيمة 404، أبلغ عن FAIL وتوقف.

خطوات التحقق (GET/dig):

الاختبارالنتيجةالحالة
DNS-1: سجل A198.51.100.10PASS
LB-1: حالة HTTP LBVIRTUAL_HOST_READYPASS
LB-2: حالة HTTPS LBVIRTUAL_HOST_READYINFO (اختياري)
TLS-1: حالة الشهادةCertificateValidINFO (اختياري)
CSD-1: علامة JSscriptTag موجودPASS

استرجع معرفات حالات الاختبار من التشخيصات والتحقق (DNS-1، TLS-1، LB-1، CSD-1، إلخ) كمعيار للتحقق لكل طبقة.

تنفيذ المراحل متسلسل ومُبوَّب: يجب أن تصل كل مرحلة إلى PASS في جميع الفحوصات المطلوبة قبل بدء المرحلة التالية. يتبع العرض التوضيحي دورة اجتماع من أربع مراحل — راجع قسم مراحل الاجتماع في DEMO_EXECUTOR.md للعبارات المحفِّزة وقواعد السلوك.

يتبع مساعد الذكاء الاصطناعي هذا التسلسل:

  1. الإعداد — حلّ المتغيرات، وشغّل الفحوصات التمهيدية، وأكد البيئة النظيفة (يمكن تشغيله بشكل منفصل قبل الاجتماع)
  2. المقدمة — يُقدم المهندس نفسه ويُحدد أهداف النتائج (رؤية التهديدات من جهة العميل، ومتطلبات PCI، والكشف في الوقت الفعلي)
  3. تنفيذ المرحلة 1 (الخطوات 1–7) — إنشاء البنية التحتية والتحقق منها؛ يجب أن تجتاز جميع فحوصات المرحلة 1 قبل المتابعة
  4. تنفيذ المرحلة 2 (الخطوات 8–9) — محاكاة الهجوم والتحقق من الكشف عبر API؛ يُنفّذ مساعدو الذكاء الاصطناعي الذين يمتلكون أتمتة المتصفح خطوات المتصفح مباشرةً، بينما ينفّذ المشغّلون الذين لا يمتلكون أدوات المتصفح هذه الخطوات يدويًا
  5. تنفيذ المرحلة 3 — تطبيق التخفيف لجميع النطاقات المكتشفة، وإعادة تشغيل الهجوم، والتحقق من فعالية الحجب
  6. الاختتام — إعادة صياغة أهداف النتائج، وتلخيص الأدلة من كل مرحلة، وإبراز الاكتشافات والتخفيفات الرئيسية
  7. الأسئلة والأجوبة — مرحلة ارتجالية، يبقى العرض التوضيحي مباشرًا، يُجيب المهندس على أسئلة الجمهور ويطرح أسئلة مُعادِلة
  8. التفكيك (بعد الاجتماع) — المرحلة 4، يلزم تأكيد صريح من المشغّل، احذف جميع الكائنات بترتيب عكسي للتبعية، أكد نظافة البيئة

إذا أعادت أي خطوة FAIL، توقف وأبلغ عن الفشل مع رابط قسم استكشاف الأخطاء ذي الصلة قبل المتابعة.

  • رمز F5 XC API — أنشئه تحت الإدارةبيانات الاعتمادبيانات اعتماد API
  • curl وjq مُثبَّتان محليًا
  • مساحة اسم مع أذونات لإنشاء فحوصات صحية ومجمّعات مصادر وموازنات تحميل HTTP

أنشئ ملف .env بقيم بيئتك. يُوفَّر نموذج في المستودع:

Terminal window
cp .env.example .env

حرّر .env بقيمك الفعلية:

.env
# مطلوب — بيئتك
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
# اختياري — يُستخدم افتراضي عرض Juice Shop التوضيحي عند عدم التحديد
# F5XC_HC_NAME=csd-hc
# F5XC_ORIGIN_IP=44.232.69.192
# F5XC_ORIGIN_POOL=csd-origin
# F5XC_ORIGIN_PORT=3000

شغّل الملف لتحميل المتغيرات في جلسة الشل الخاصة بك:

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

كل عنصر نائب xTOKENx في أوامر curl يرتبط مباشرةً بمتغير بيئة — على سبيل المثال، xF5XC_API_TOKENx يقابل $F5XC_API_TOKEN. يمكنك استبدال هذه القيم باستخدام النموذج التفاعلي أعلى الصفحة، أو السماح لمساعد الذكاء الاصطناعي مثل Claude Code بقراءة ملف .env الخاص بك وبناء الأوامر لك.

الرمزالافتراضيالوصف
xF5XC_API_URLxhttps://example-tenant.console.ves.volterra.ioعنوان URL لـ XC Console API
xF5XC_API_TOKENxexample-api-tokenرمز بيانات اعتماد API
xF5XC_EMAILxuser@example.comعنوان البريد الإلكتروني لإشعارات CSD
xF5XC_NAMESPACExexample-namespaceمساحة الاسم
xF5XC_LB_NAMExexample-lbالاسم الأساسي لموازن تحميل HTTP (يُنشئ ${name}-http و${name}-https)
xF5XC_DOMAINNAMExapp.example.comFQDN للحماية
xF5XC_ROOT_DOMAINxexample.comالنطاق الجذري (eTLD+1) لنطاق CSD المحمي
xF5XC_ORIGIN_POOLxcsd-originاسم مجمّع المصادر
xF5XC_ORIGIN_IPx44.232.69.192عنوان IP لخادم المصدر
xF5XC_ORIGIN_PORTx3000منفذ خادم المصدر
xF5XC_HC_NAMExcsd-hcاسم الفحص الصحي

يلخص هذا القسم سير عمل التمرين الكامل للبرمجة النصية أو الأتمتة.

  1. انسخ المستودع وانسخ نموذج البيئة: cp .env.example .env
  2. حرّر .env بعنوان URL للمستأجر ورمز API ومساحة الاسم وقيم النطاق الخاصة بك
  3. شغّل البيئة: set -a && source .env && set +a
  4. نفّذ كل مرحلة بالترتيب، مع التحقق من PASS في كل كتلة أدلة قبل الانتقال إلى المرحلة التالية

يتم حل القيم باستخدام البروتوكول الحتمي المحدد في بروتوكول تنفيذ مساعد الذكاء الاصطناعي:

  1. ملف .env — حلّل أزواج KEY=VALUE من جذر المستودع
  2. بيئة الشل — افحص env | grep F5XC_ للقيم المُصدَّرة
  3. كشف العناصر النائبة — ضع علامة على أي قيمة تطابق افتراضيًا نائبًا (مثلاً، example-api-token، example-namespace) كمفقودة
  4. اطلب من المشغّل — اطلب كل متغير مطلوب مفقود
  5. طبّق الافتراضيات — استخدم الافتراضيات المضمّنة للمتغيرات الاختيارية المفقودة
  6. أكّد — اعرض جدول المتغيرات المحلولة وانتظر موافقة المشغّل
  1. المرحلة 1 — البناء: نشر البنية التحتية (الفحص الصحي، مجمّع المصادر، HTTP LB + HTTPS LB)، وتكوين DNS، وتفعيل CSD، وتسجيل النطاق المحمي، والتحقق من جميع المكونات. HTTP LB هو الهدف الأساسي للعرض التوضيحي؛ HTTPS LB اختياري.
  2. المرحلة 2 — الهجوم: شغّل محاكاة الهجوم في متصفح باستخدام عناوين URL بـhttp://، وانتظر 5–10 دقائق، وتحقق من الكشف عبر API (/scripts، /detected_domains، /formFields)
  3. المرحلة 3 — التخفيف: أكد خط الأساس النظيف، وشغّل الهجوم (إثبات ما قبل)، وانشر POST لكل نطاق إلى /mitigated_domains، وتحقق من تطبيق التخفيفات، وأعد تشغيل الهجوم باستخدام عناوين URL بـhttp:// (إثبات ما بعد)، وقدّم مقارنة ما قبل/بعد
  4. المرحلة 4 — التفكيك (يتطلب تأكيدًا بشريًا صريحًا): احذف HTTPS LB → HTTP LB → مجمّع المصادر → تنظيف منطقة DNS (السجلات اليدوية فقط) → الفحص الصحي → النطاق المحمي. لا تحذف منطقة DNS.
الرمزالوصفالافتراضي
xF5XC_API_URLxعنوان URL لـ XC Console APIhttps://example-tenant.console.ves.volterra.io
xF5XC_API_TOKENxرمز بيانات اعتماد API(يوفره المستخدم)
xF5XC_EMAILxبريد إلكتروني لإشعارات CSDuser@example.com
xF5XC_NAMESPACExمساحة الاسمexample-namespace
xF5XC_LB_NAMExالاسم الأساسي لموازن تحميل HTTP (يُنشئ ${name}-http و${name}-https)example-lb
xF5XC_DOMAINNAMExFQDN للحمايةapp.example.com
xF5XC_ROOT_DOMAINxالنطاق الجذري (eTLD+1)example.com
xF5XC_ORIGIN_POOLxاسم مجمّع المصادرcsd-origin
xF5XC_ORIGIN_IPxعنوان IP لخادم المصدر44.232.69.192
xF5XC_ORIGIN_PORTxمنفذ خادم المصدر3000
xF5XC_HC_NAMExاسم الفحص الصحيcsd-hc

تستخدم مواصفة موازن تحميل HTTP مجموعات اختيار oneOf حيث يجب ضبط خيار واحد بالضبط لكل مجموعة. ضبط صفر أو أكثر من خيار في مجموعة يُسبب خطأ 422.

خيارات رئيسية مرتبطة بـ CSD:

مجموعة الاختيارالخياراتالافتراضي لـ CSD
client_side_defense_choiceclient_side_defense، disable_client_side_defenseclient_side_defense
java_script_choice (مدمجة في CSD)disable_js_insert، js_insert_all_pages، js_insert_all_pages_except، js_insertion_rulesjs_insert_all_pages

اختيار نوع المُستمِع (HTTP مقابل HTTPS):

يُنشئ العرض التوضيحي موازنَي تحميل بإعدادات مُستمِع مختلفة:

موازن التحميلاختيار المُستمِعالتكوين
${F5XC_LB_NAME}-http (أساسي)http"http": { "dns_volterra_managed": true, "port": 80 }
${F5XC_LB_NAME}-https (ثانوي)https_auto_cert"https_auto_cert": { "http_redirect": true, "port": 443, ... }

مفتاحا http وhttps_auto_cert متنافيان — يستخدم كل موازن تحميل مفتاحًا واحدًا بالضبط.

خيارات HTTPS auto-cert المدمجة (موازن التحميل الثانوي فقط):

مجموعة الاختيارالخياراتالافتراضي
المنفذport (رقم)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

الخيارات المدمجة في single_lb_app (إعداد ML):

يمتلك كائن single_lb_app مجموعات oneOf مطلوبة خاصة به. ضبط single_lb_app: \{\} بدون هذه الخيارات المدمجة يُسبب خطأ 400.

مجموعة الاختيارالخياراتالافتراضي
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

خيارات أخرى على مستوى LB (جميعها مضبوطة على تعطيل/افتراضي):

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 غير صالح أو منتهي الصلاحية. أعد التوليد تحت الإدارةبيانات الاعتماد.
  • 403 Forbidden — الرمز يفتقر إلى أذونات مساحة الاسم. افحص روابط الأدوار.
  • 404 Not Found — اسم مساحة الاسم أو الكائن غير صحيح. أدرج الكائنات بـGET /api/config/namespaces/\{namespace\}/\{object_type\}.
  • 409 Conflict — الكائن موجود بالفعل. للنطاقات المحمية، تعني 409 مع رسالة “domain already exists (in uriList)” أن النطاق الجذري مسجل بالفعل على المستأجر — هذا شرط نجاح وليس خطأ. بالنسبة للكائنات الأخرى، احذف أولاً أو استخدم PUT للتحديث.
  • 422 Unprocessable Entity — فشل التحقق من مخطط JSON. الأسباب الشائعة: اختيار oneOf مفقود، أو تعيين خيارات متعددة في نفس المجموعة، أو نوع حقل خاطئ. افحص رسالة الخطأ للحقل المحدد.
  • الحد الأقصى للكائنات منتهٍ (رمز الخطأ 8، رسالة "Object kind {kind} has exhausted limits({N})") — وصل المستأجر إلى حد حصة الكائنات. تُعيد API قيمة HTTP 200 مع جسم JSON للخطأ يحتوي على "code": 8، وليس HTTP 429. يمكنك التحقق بشكل استباقي من سعة الحصة قبل مواجهة هذا الخطأ باستخدام Quota Usage API (GET /api/web/namespaces/system/quota/usage?namespace=system). يعتمد السلوك على نوع الكائن:
    • Healthcheck (الحد ~150): غير مانع — تخطَّ خطوة 1 من المرحلة 1 وأنشئ مجمّع المصادر بدون مرجع للفحص الصحي. CSD لا يعتمد على مراقبة الصحة.
    • Endpoint (الحد ~500): مانع — نقاط النهاية هي كائنات فرعية تُنشأ داخل مجمّعات المصادر. إذا تم الوصول إلى هذا الحد، يفشل إنشاء مجمّع المصادر. احذف مجمّعات المصادر غير المستخدمة في مساحات الاسم الأخرى (مما يُحرر كائنات نقطة النهاية الفرعية) أو تواصل مع مسؤولك لزيادة حد المستأجر.
    • Origin pool: مانع — احذف مجمّعات المصادر غير المستخدمة أو تواصل مع مسؤولك.
    • HTTP load balancer: مانع — احذف موازنات التحميل غير المستخدمة أو تواصل مع مسؤولك.
    • Protected domain: مانع — احذف النطاقات المحمية غير المستخدمة أو تواصل مع مسؤولك.

استكشاف الأخطاء وإصلاحها

Section titled “استكشاف الأخطاء وإصلاحها”

الفحص الصحي غير مرتبط بمجمّع المصادر

Section titled “الفحص الصحي غير مرتبط بمجمّع المصادر”

إذا أظهرت الخطوة 2 من المرحلة 1 (التحقق من ربط الفحص الصحي) مصفوفة فارغة []:

  1. احذف مجمّع المصادر: DELETE /api/config/namespaces/{namespace}/origin_pools/{pool_name}
  2. تحقق من وجود الفحص الصحي: GET /api/config/namespaces/{namespace}/healthchecks/{hc_name}
  3. أعد إنشاء مجمّع المصادر مع مرجع الفحص الصحي الصحيح

موازن التحميل عالق في VIRTUAL_HOST_PENDING_A_RECORD

Section titled “موازن التحميل عالق في VIRTUAL_HOST_PENDING_A_RECORD”

إذا ظلت state لموازن التحميل VIRTUAL_HOST_PENDING_A_RECORD بعد الخطوة 4 من المرحلة 1:

  1. تحقق من وجود منطقة DNS (DNS المُدار بواسطة F5 XC فقط):

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

    قيمة 404 تعني أن منطقة DNS لم يتم إنشاؤها في F5 XC.

  2. افحص allow_http_lb_managed_records — إذا كانت المنطقة موجودة لكن موازن التحميل معلق، فقد تكون السجلات المُدارة معطّلة:

    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'

    إذا كانت false أو null، فعّلها باستخدام أمر PUT في الخيار A من الخطوة 4 للمرحلة 1.

  3. DNS الخارجي — إذا لم يكن F5 XC هو المرجعية، أنشئ سجلات A وACME CNAME يدويًا في مزوّد DNS الخاص بك (راجع الخيار B من الخطوة 4 للمرحلة 1).

  4. تحقق من الدقة — بعد إصلاح DNS، أكّد:

    Terminal window
    dig +short xF5XC_DOMAINNAMEx A

    إذا تم حل سجل A، ينتقل موازن التحميل إلى VIRTUAL_HOST_READY. استطلع كل 30 ثانية، حتى 4 تكرارات (دقيقتان إجمالاً). إذا لا يزال VIRTUAL_HOST_PENDING_A_RECORD بعد دقيقتين، أعد فحص انتشار DNS وأبلغ المشغّل.

حالة CSD تُظهر isConfigured: false

Section titled “حالة CSD تُظهر isConfigured: false”

يجب تفعيل CSD على مستوى المستأجر. تواصل مع مسؤول F5 XC الخاص بك لتفعيل الدفاع من جهة العميل لمستأجرك. هذا إعداد على مستوى المستأجر لا يمكن تكوينه عبر API.

  1. تحقق من تفعيل CSD على مستوى المستأجر (الخطوة 5 من المرحلة 1)
  2. أكّد أن موازن التحميل لديه client_side_defense مُعيَّن في المواصفة
  3. افحص أن نقطة نهاية إعداد JS تُعيد scriptTag
  4. زر النطاق المحمي في متصفح واعرض مصدر الصفحة للتأكد من حقن السكريبت

تسجيل النطاق المحمي يُعيد 409

Section titled “تسجيل النطاق المحمي يُعيد 409”

قيمة 409 مع رسالة “domain already exists (in uriList)” تعني أن النطاق الجذري مسجل بالفعل على المستأجر. النطاقات المحمية بنطاق المستأجر — لا تنتمي إلى أي مساحة اسم واحدة. هذا شرط نجاح: النطاق محمي بالفعل ولا حاجة لمزيد من الإجراءات. تابع إلى الخطوة 7 من المرحلة 1.

إذا أظهرت cert_state لـ HTTPS LB قيمة AutoCertDomainRateLimited، فهذا يعني أن Let’s Encrypt قد حدّد معدل إصدار الشهادات لهذا النطاق. هذا متوقع في بيئات العرض التوضيحي حيث يتم إنشاء البنية التحتية وتدميرها بشكل متكرر.

التأثير: لن يخدّم HTTPS LB حركة المرور حتى يتم إعادة تعيين حد المعدل (عادةً ساعة واحدة). HTTP LB غير متأثر تمامًا — تستمر جميع حركة مرور العرض التوضيحي بشكل طبيعي عبر http://.

الحل: لا يلزم اتخاذ أي إجراء لتقدم العرض التوضيحي. HTTP LB (${F5XC_LB_NAME}-http) هو الهدف الأساسي للعرض التوضيحي ولا يعتمد على توفير الشهادات. إذا كان HTTPS مطلوبًا، انتظر إعادة تعيين حد المعدل وسيتم توفير الشهادة تلقائيًا.

الشهادة عالقة — إعادة الإنشاء النظيف (اختياري)

Section titled “الشهادة عالقة — إعادة الإنشاء النظيف (اختياري)”

عندما تكون شهادة HTTPS LB عالقة في DomainChallengePending أو PreDomainChallengePending لأكثر من 15 دقيقة، فإن أسرع مسار للاسترداد هو حذف HTTPS LB وإعادة إنشائه. مع تكوين منطقة DNS مسبقًا (السجلات المُدارة مفعّلة)، تُنتج إعادة الإنشاء النظيف عادةً CertificateValid في غضون 5–7 دقائق — ما لم تكن مُقيَّدة بحد المعدل.

  1. احذف موازن تحميل HTTPS: DELETE .../http_loadbalancers/${F5XC_LB_NAME}-https
  2. انتظر 30 ثانية لتنظيف المنصة
  3. أعد إنشاء موازن تحميل HTTPS (الخطوة 3 من المرحلة 1)
  4. راقب حالة الشهادة (الخطوة 7 من المرحلة 1) — توقع CertificateValid خلال 5–10 دقائق

تتوفر مواصفة F5 Distributed Cloud API الرسمية على:

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

يحتوي هذا الملف المضغوط على مواصفات OpenAPI 3.0 لجميع مجموعات API بما فيها ves.io.schema.views.http_loadbalancer وves.io.schema.healthcheck وves.io.schema.origin_pool وves.io.schema.shape.csd. استخدم هذه المواصفات للتحقق من صحة حمولات JSON واكتشاف حقول إضافية.