ข้ามไปยังเนื้อหา

Phase 1 — สร้าง

Phase 1 ปรับใช้และตรวจสอบโครงสร้างพื้นฐาน CSD ทั้งหมด ดำเนินการทุกขั้นตอนตามลำดับ — แต่ละขั้นตอนต้องผ่าน (PASS) ก่อนดำเนินการต่อ กลับไปที่ index เพื่อทำการตั้งค่าสภาพแวดล้อมและการกำหนดค่าตัวแปรก่อนรันคำสั่งเหล่านี้

ขั้นตอนที่ 0: ตรวจสอบและสร้าง Namespace (มีเงื่อนไข)

หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 0: ตรวจสอบและสร้าง Namespace (มีเงื่อนไข)”

ตรวจสอบว่า namespace เป้าหมายมีอยู่บน tenant แล้วหรือไม่ หากไม่มี ให้สร้างขึ้นมา บันทึกผลลัพธ์ในตัวแปร shell NAMESPACE_CREATED — Phase 4 teardown จะใช้ตัวแปรนี้เพื่อตัดสินใจว่าจะลบ namespace หรือไม่

Terminal window
NS_CHECK=$(curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces/xF5XC_NAMESPACEx")
NAMESPACE_CREATED="false"
if [ "$NS_CHECK" = "404" ]; then
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{"metadata": {"name": "xF5XC_NAMESPACEx"}, "spec": {}}' \
"xF5XC_API_URLx/api/web/namespaces" | jq .
NAMESPACE_CREATED="true"
fi

ยืนยันว่า namespace มีอยู่และบันทึกว่ามีการสร้างขึ้นหรือไม่:

Terminal window
curl -s -o /dev/null -w '%\{http_code\}' \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/web/namespaces/xF5XC_NAMESPACEx"
echo "NAMESPACE_CREATED=$NAMESPACE_CREATED"
ฟิลด์ที่คาดหวังสถานะ
HTTP Status200PASS หากได้รับ, FAIL หาก 404 หรืออื่นๆ
NAMESPACE_CREATEDtrue (สร้างใหม่) หรือ false (มีอยู่แล้ว)ข้อมูลอ้างอิง — ใช้โดย Phase 4 teardown

สร้าง HTTP healthcheck ที่ origin pool สามารถใช้เพื่อตรวจสอบสุขภาพของ backend

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_HC_NAMEx",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"disable": false
},
"spec": {
"http_health_check": {
"use_origin_server_name": {},
"path": "/",
"use_http2": false,
"headers": {},
"request_headers_to_remove": [],
"expected_status_codes": ["200"]
},
"timeout": 3,
"interval": 15,
"jitter": 0,
"unhealthy_threshold": 1,
"healthy_threshold": 3,
"jitter_percent": 30
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks" \
| jq .

การตอบสนอง 200 พร้อม object ที่สร้างขึ้นยืนยันว่า healthcheck ถูกสร้างแล้ว หากการตอบสนองมี "code": 8 พร้อมข้อความเช่น "Object kind healthcheck has exhausted limits(150)" แสดงว่า tenant ถึงขีดจำกัด healthcheck แล้ว — ข้ามไปขั้นตอนที่ 2 และละเว้นการอ้างอิง healthcheck CSD ไม่ขึ้นอยู่กับการตรวจสอบสุขภาพ

ยืนยันว่า healthcheck มีอยู่:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/healthchecks/xF5XC_HC_NAMEx" \
| jq '{name: .metadata.name, namespace: .metadata.namespace, path: .spec.http_health_check.path, interval: .spec.interval}'
ฟิลด์ที่คาดหวังสถานะ
HTTP Status200 พร้อม objectPASS หากได้รับ, FAIL หาก 404
nameตรงกับ F5XC_HC_NAMEPASS
path/PASS
ข้ามขั้นตอนที่ 1 แล้ว (error code 8, ถึงขีดจำกัด)PASS (healthcheck ไม่บังคับสำหรับ CSD)

สร้าง origin pool ที่ชี้ไปยัง backend server ของคุณ หากคุณสร้าง healthcheck ในขั้นตอนที่ 1 ให้รวมการอ้างอิง healthcheck หากข้ามขั้นตอนที่ 1 ให้ใช้ array ว่าง

พร้อม healthcheck (ขั้นตอนที่ 1 สำเร็จ):

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_ORIGIN_POOLx",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"description": "Origin pool for CSD demo",
"disable": false
},
"spec": {
"origin_servers": [{
"public_ip": { "ip": "xF5XC_ORIGIN_IPx" },
"labels": {}
}],
"no_tls": {},
"port": xF5XC_ORIGIN_PORTx,
"same_as_endpoint_port": {},
"healthcheck": [{
"namespace": "xF5XC_NAMESPACEx",
"name": "xF5XC_HC_NAMEx",
"kind": "healthcheck"
}],
"loadbalancer_algorithm": "LB_OVERRIDE",
"endpoint_selection": "LOCAL_PREFERRED"
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools" \
| jq .

ไม่มี healthcheck (ข้ามขั้นตอนที่ 1):

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_ORIGIN_POOLx",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"description": "Origin pool for CSD demo",
"disable": false
},
"spec": {
"origin_servers": [{
"public_ip": { "ip": "xF5XC_ORIGIN_IPx" },
"labels": {}
}],
"no_tls": {},
"port": xF5XC_ORIGIN_PORTx,
"same_as_endpoint_port": {},
"healthcheck": [],
"loadbalancer_algorithm": "LB_OVERRIDE",
"endpoint_selection": "LOCAL_PREFERRED"
}
}' \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools" \
| jq .

การตอบสนอง 200 ยืนยันว่า origin pool ถูกสร้างแล้ว

หากคุณรวมการอ้างอิง healthcheck ให้ยืนยันว่าเชื่อมโยงอย่างถูกต้อง:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \
| jq '.spec.healthcheck'

Array ที่มีข้อมูลยืนยันการเชื่อมโยง Array ว่าง [] เป็นสิ่งที่คาดหวังหากข้ามขั้นตอนที่ 1 หรือหมายความว่าไม่พบ healthcheck หากคุณตั้งใจจะเชื่อมโยง

ยืนยันว่า origin pool มีอยู่และมีการกำหนดค่าที่ถูกต้อง:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \
| jq '{name: .metadata.name, origin_ip: .spec.origin_servers[0].public_ip.ip, port: .spec.port, healthcheck_count: (.spec.healthcheck | length)}'
ฟิลด์ที่คาดหวังสถานะ
HTTP Status200PASS หากได้รับ, FAIL หาก 404
nameตรงกับ F5XC_ORIGIN_POOLPASS
origin_ipตรงกับ F5XC_ORIGIN_IPPASS
portตรงกับ F5XC_ORIGIN_PORTPASS
healthcheck_count1 (มี HC) หรือ 0 (ไม่มี)PASS ทั้งสองกรณี

สร้าง load balancer สอง ตัวที่เปิดใช้งาน การป้องกันฝั่งไคลเอนต์ — HTTP LB (หลัก, พอร์ต 80) และ HTTPS LB (รอง, พอร์ต 443 พร้อมการจัดการใบรับรองอัตโนมัติ) HTTP LB เป็นค่าเริ่มต้นสำหรับทราฟฟิกการสาธิตทั้งหมด HTTPS LB เป็นสิ่งที่ดีเพิ่มเติมที่ขึ้นอยู่กับการจัดสรรใบรับรอง Let’s Encrypt ซึ่งอาจถึงขีดจำกัด rate limit ในสภาพแวดล้อมสาธิต

นี่คือ load balancer หลัก สำหรับการสาธิต ใช้ http listener บนพอร์ต 80 พร้อม F5 XC managed DNS ไม่ขึ้นอยู่กับการจัดสรรใบรับรอง TLS ดังนั้นจึงพร้อมใช้งานทันทีหลังจาก DNS resolves

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_LB_NAMEx-http",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"description": "HTTP LB with Client-Side Defense enabled (primary demo LB)",
"disable": false
},
"spec": {
"domains": ["xF5XC_DOMAINNAMEx"],
"http": {
"dns_volterra_managed": true,
"port": 80
},
"advertise_on_public_default_vip": {},
"default_route_pools": [{
"pool": {
"namespace": "xF5XC_NAMESPACEx",
"name": "xF5XC_ORIGIN_POOLx",
"kind": "origin_pool"
},
"weight": 1,
"priority": 1
}],
"client_side_defense": {
"policy": {
"js_insert_all_pages": {}
}
},
"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" \
| jq .

การตอบสนอง 200 ยืนยันว่า HTTP load balancer ถูกสร้างพร้อม CSD เปิดใช้งาน

นี่คือ load balancer รอง ใช้ https_auto_cert บนพอร์ต 443 พร้อมการจัดสรรใบรับรอง Let’s Encrypt อัตโนมัติ ก่อนสร้าง ให้ตรวจสอบว่ามี skeleton HTTPS LB จาก teardown ก่อนหน้าอยู่หรือไม่ — หากมี ให้กู้คืนผ่าน PUT แทน POST เพื่อรักษาใบรับรอง Let’s Encrypt ที่มีอยู่และหลีกเลี่ยงขีดจำกัด rate limit (ใบรับรองซ้ำกัน 5 ใบต่อชุด identifier เดียวกันต่อ 7 วัน)

ตรวจสอบว่า HTTPS LB มีอยู่แล้วหรือไม่:

Terminal window
HTTPS_CHECK=$(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")

หาก HTTPS_CHECK เป็น 200 แสดงว่ามี skeleton HTTPS LB อยู่ — ใช้ Path A (PUT) หาก 404 ให้ใช้ Path B (POST)

เมื่อมี skeleton HTTPS LB จาก teardown ก่อนหน้า ให้กู้คืนการกำหนดค่าเต็มรูปแบบผ่าน PUT การดำเนินการนี้จะเชื่อมต่อ origin pool อีกครั้งและเปิดใช้งาน CSD ใหม่ โดยไม่ต้องส่งคำขอใบรับรอง Let’s Encrypt ใหม่ — ใบรับรองที่มีอยู่ยังคงใช้งานได้

Terminal window
curl -s -X PUT \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_LB_NAMEx-https",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"description": "HTTPS LB with Client-Side Defense enabled (secondary, cert-dependent)",
"disable": false
},
"spec": {
"domains": ["xF5XC_DOMAINNAMEx"],
"https_auto_cert": {
"http_redirect": false,
"add_hsts": false,
"port": 443,
"default_header": {},
"enable_path_normalize": {},
"no_mtls": {},
"default_loadbalancer": {}
},
"advertise_on_public_default_vip": {},
"default_route_pools": [{
"pool": {
"namespace": "xF5XC_NAMESPACEx",
"name": "xF5XC_ORIGIN_POOLx",
"kind": "origin_pool"
},
"weight": 1,
"priority": 1
}],
"client_side_defense": {
"policy": {
"js_insert_all_pages": {}
}
},
"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/xF5XC_LB_NAMEx-https" \
| jq .

การตอบสนอง 200 ยืนยันว่า skeleton ถูกกู้คืนพร้อมการกำหนดค่าเต็มรูปแบบ สถานะใบรับรองควรยังคงเป็น CertificateValid — ไม่มีการจัดสรร Let’s Encrypt ใหม่ถูกกระตุ้น

เมื่อไม่มี HTTPS LB อยู่ (ครั้งแรกหรือหลังจาก full teardown) ให้สร้างผ่าน POST การดำเนินการนี้จะเริ่มการจัดสรรใบรับรอง Let’s Encrypt ซึ่งอาจใช้เวลา 5–10 นาที

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_LB_NAMEx-https",
"namespace": "xF5XC_NAMESPACEx",
"labels": {},
"annotations": {},
"description": "HTTPS LB with Client-Side Defense enabled (secondary, cert-dependent)",
"disable": false
},
"spec": {
"domains": ["xF5XC_DOMAINNAMEx"],
"https_auto_cert": {
"http_redirect": false,
"add_hsts": false,
"port": 443,
"default_header": {},
"enable_path_normalize": {},
"no_mtls": {},
"default_loadbalancer": {}
},
"advertise_on_public_default_vip": {},
"default_route_pools": [{
"pool": {
"namespace": "xF5XC_NAMESPACEx",
"name": "xF5XC_ORIGIN_POOLx",
"kind": "origin_pool"
},
"weight": 1,
"priority": 1
}],
"client_side_defense": {
"policy": {
"js_insert_all_pages": {}
}
},
"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" \
| jq .

การตอบสนอง 200 ยืนยันว่า HTTPS load balancer ถูกสร้างแล้ว การจัดสรรใบรับรองเริ่มต้นโดยอัตโนมัติ

ยืนยันว่า load balancer ทั้งสองมีอยู่พร้อม CSD เปิดใช้งาน ควรใช้ GET สำหรับหลักฐานเสมอ — การตอบสนอง POST จะส่งคืนค่าสถานะชั่วคราวที่อาจไม่สะท้อนการกำหนดค่าที่เสถียร

HTTP LB (หลัก):

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \
| jq '{name: .metadata.name, domains: .spec.domains, csd_enabled: (.spec.client_side_defense != null), state: .spec.state}'
ฟิลด์ที่คาดหวังสถานะ
HTTP Status200PASS หากได้รับ, FAIL หาก 404
name${F5XC_LB_NAME}-httpPASS
domainsมี F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD ถูกกำหนดค่าบน LB นี้
stateVIRTUAL_HOST_READY หรือ VIRTUAL_HOST_PENDING_A_RECORDคาดหวัง — HTTP LB จะเปลี่ยนเป็น READY เมื่อ DNS resolves สถานะอื่นๆ (เช่น VIRTUAL_HOST_FAILED) เป็น FAIL — รายงานต่อผู้ดำเนินการและอย่าดำเนินการต่อ

HTTPS LB (รอง):

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \
| jq '{name: .metadata.name, domains: .spec.domains, csd_enabled: (.spec.client_side_defense != null), state: .spec.state, cert_state: .spec.cert_state}'
ฟิลด์ที่คาดหวังสถานะ
HTTP Status200PASS หากได้รับ, FAIL หาก 404
name${F5XC_LB_NAME}-httpsPASS
domainsมี F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD ถูกกำหนดค่าบน LB นี้
creation_methodPUT (กู้คืน skeleton) หรือ POST (สร้างใหม่)INFO — PUT รักษาใบรับรองที่มีอยู่
stateVIRTUAL_HOST_READY (PUT) หรือ VIRTUAL_HOST_PENDING_A_RECORD (POST)คาดหวัง — PUT path อาจเป็น READY แล้วเนื่องจาก DNS ยังคงอยู่จาก skeleton
cert_stateCertificateValid (PUT) หรือ PreDomainChallengePending (POST)PUT รักษาใบรับรองที่มีอยู่; POST กระตุ้นการจัดสรรใหม่

หลังจากสร้าง load balancer แล้ว จะเข้าสู่สถานะ VIRTUAL_HOST_PENDING_A_RECORD และใบรับรองอัตโนมัติจะอยู่ใน PreDomainChallengePending DNS record สองรายการต้องมีอยู่ก่อนที่ LB จะทำงานได้อย่างสมบูรณ์:

  1. A recordxF5XC_DOMAINNAMEx ชี้ไปยัง VIP IP address (จาก dns_info ใน LB response)
  2. ACME challenge record_acme-challenge.xF5XC_DOMAINNAMEx สำหรับการตรวจสอบใบรับรอง TLS (จัดการโดยอัตโนมัติเมื่อใช้ F5 XC DNS พร้อม managed records; ต้องใช้ manual CNAME สำหรับ DNS ภายนอก)

วิธีการขึ้นอยู่กับว่า F5 XC เป็น authoritative DNS provider สำหรับ domain ของคุณหรือไม่

ตรวจสอบ nameserver สำหรับ root domain ของคุณ:

Terminal window
dig +short NS xF5XC_ROOT_DOMAINx

หากการตอบสนองรวมถึง ns1.f5clouddns.com และ ns2.f5clouddns.com F5 XC เป็น authoritative DNS provider — ทำตาม Option A มิฉะนั้น ทำตาม Option B สำหรับ external DNS

เมื่อ F5 XC เป็น authoritative DNS provider แพลตฟอร์มสามารถสร้าง A record และ ACME challenge CNAME ทั้งสองโดยอัตโนมัติ — แต่เฉพาะเมื่อ DNS zone มี allow_http_lb_managed_records เปิดใช้งาน

1. ตรวจสอบว่า 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'

หากการตอบสนองเป็น true แพลตฟอร์มจะสร้าง DNS record โดยอัตโนมัติสำหรับ load balancer — ข้ามไปที่ 3. ตรวจสอบ DNS resolution หากเป็น false หรือ null ให้ดำเนินการขั้นตอนต่อไป

2. เปิดใช้งาน managed records:

ดึงข้อมูลการกำหนดค่า zone ปัจจุบัน เปิดใช้งาน managed records และอัปเดต:

Terminal window
# Get current zone config
ZONE_CONFIG=$(curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/dns/namespaces/system/dns_zones/xF5XC_ROOT_DOMAINx")
# Update with managed records enabled
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 .

การตอบสนอง 200 (ว่าง \{\}) ยืนยันว่า zone ถูกอัปเดตแล้ว F5 XC จะสร้าง A record และ ACME challenge record ในกลุ่ม record ที่จัดการโดยอัตโนมัติของ zone หาก managed records ไม่ปรากฏภายใน 60 วินาที ให้ re-apply load balancer เพื่อกระตุ้นการสร้าง record:

Terminal window
LB_CONFIG=$(curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http")
echo "$LB_CONFIG" | curl -s -X PUT \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d @- \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \
| jq .

GET+PUT re-apply นี้ไม่เปลี่ยนการกำหนดค่า LB — เพียงแต่กระตุ้นให้แพลตฟอร์มประเมิน DNS zone ใหม่และสร้าง managed records หาก A record ยังไม่ resolve ภายใน 60 วินาทีหลัง re-apply ให้หยุดและรายงานต่อผู้ดำเนินการ — อย่าลอง re-apply มากกว่าหนึ่งครั้ง

3. ตรวจสอบ DNS resolution:

Terminal window
dig +short xF5XC_DOMAINNAMEx A

การตอบสนองควรส่งคืน VIP IP address DNS propagation มักจะเกิดขึ้นทันทีสำหรับ F5 XC managed zones แต่ให้รอสูงสุด 60 วินาที

เมื่อ domain ของคุณใช้ external DNS provider คุณต้องสร้าง record ด้วยตนเอง ดึงค่าที่จำเป็นจาก load balancer:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \
| jq '{
vip_ip: .spec.dns_info[0].ip_address,
acme_target: .spec.auto_cert_info.dns_records
}'

สร้าง record เหล่านี้ที่ DNS provider ของคุณ:

ประเภทชื่อค่า
AxF5XC_DOMAINNAMExVIP IP จาก dns_info[0].ip_address
CNAME_acme-challenge.xF5XC_DOMAINNAMEx*.autocerts.ves.volterra.io

หลังจากสร้าง record แล้ว ให้ตรวจสอบ resolution:

Terminal window
dig +short xF5XC_DOMAINNAMEx A
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
การทดสอบคำสั่งที่คาดหวังสถานะ
DNS-1: A Recorddig +short $F5XC_DOMAINNAME Aส่งคืน VIP IP addressPASS หากได้รับ IP, FAIL หากว่าง
DNS-2: ACME CNAMEdig +short _acme-challenge.$F5XC_DOMAINNAME CNAME*.autocerts.ves.volterra.ioPASS หากได้รับ CNAME
DNS authoritydig +short NS $F5XC_ROOT_DOMAINF5 XC หรือ external nameserverข้อมูลอ้างอิง — กำหนด Option A หรือ B

หาก DNS-1 ส่งคืนว่างหลังจาก 60 วินาที ดู Troubleshooting — LB Stuck in VIRTUAL_HOST_PENDING_A_RECORD

ตรวจสอบว่า การป้องกันฝั่งไคลเอนต์ เปิดใช้งานสำหรับ tenant CSD ถูกกำหนดค่าในระดับ tenant — หากยังไม่ได้เปิดใช้งาน ให้ติดต่อผู้ดูแลระบบ F5 XC ของคุณ

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

การตอบสนองที่มี "isConfigured": true และ "isEnabled": true ยืนยันว่า CSD ทำงานอยู่

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \
| jq '{configured: .isConfigured, enabled: .isEnabled}'
ฟิลด์ที่คาดหวังสถานะ
configuredtruePASS
enabledtruePASS
ค่าใดค่าหนึ่งเป็น falseFAIL — ติดต่อผู้ดูแลระบบ F5 XC เพื่อเปิดใช้งาน CSD ในระดับ tenant

ลงทะเบียน root domain ที่ CSD จะตรวจสอบ ฟิลด์ protected_domain ต้องเป็น eTLD+1 root domain (เช่น f5demos.com) ไม่ใช่ FQDN เต็มรูปแบบ

ก่อนสร้าง ให้ตรวจสอบว่า domain ลงทะเบียนบน tenant แล้วหรือไม่ การตอบสนอง 409 ต่อ POST หมายความว่า domain มีอยู่แล้ว — นี่คือเงื่อนไขสำเร็จ ไม่ใช่ข้อผิดพลาด

Terminal window
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "xF5XC_DOMAINNAMEx",
"namespace": "xF5XC_NAMESPACEx"
},
"spec": {
"protected_domain": "xF5XC_ROOT_DOMAINx"
}
}' \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq .
การตอบสนองความหมายการดำเนินการ
200ลงทะเบียน domain สำเร็จดำเนินต่อไปขั้นตอนที่ 7
409 (domain มีอยู่แล้ว)Domain ถูกลงทะเบียนไว้ก่อนหน้าบน tenant นี้ดำเนินการแล้ว — ดำเนินต่อไปขั้นตอนที่ 7
"code": 8 (ถึงขีดจำกัด)โควต้า protected domain เต็มต้องแก้ไข — protected domain จำเป็นสำหรับ CSD ลบ protected domain ที่ไม่ได้ใช้งานหรือติดต่อผู้ดูแลระบบของคุณ

การตอบสนอง POST เองเป็นหลักฐานหลัก — ส่งคืน registered domain object พร้อม spec.protected_domain ที่ตรงกับ root domain ของคุณ หรืออีกทางหนึ่ง แสดงรายการ protected domain ทั้งหมดเพื่อยืนยัน:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq '.items | length'
ฟิลด์ที่คาดหวังสถานะ
POST ส่งคืน protected_domainตรงกับ F5XC_ROOT_DOMAINPASS
POST ส่งคืน 200 หรือ 409Domain ลงทะเบียนแล้วหรือมีอยู่แล้วPASS
จำนวน list items> 0PASS

ยืนยันว่า A record กำลัง resolving และ ACME challenge CNAME อยู่ในที่:

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

A record ควรส่งคืน VIP IP address CNAME ควรชี้ไปที่ *.autocerts.ves.volterra.io (หรือ autocerts target ที่เกี่ยวข้อง)

ตรวจสอบว่า load balancer ทั้งสองเปลี่ยนออกจากสถานะ pending แล้ว HTTP LB เป็นการตรวจสอบหลัก — ควรถึง VIRTUAL_HOST_READY เมื่อ DNS resolves โดยไม่มีการพึ่งพาใบรับรอง สถานะใบรับรอง HTTPS LB เป็นเพียงข้อมูลอ้างอิง

HTTP LB (หลัก — ต้องเป็น READY เพื่อดำเนินต่อ):

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-http" \
| jq '{state: .spec.state}'
ฟิลด์ที่คาดหวังสถานะกลาง
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS ยังไม่ได้กำหนดค่า (ดูขั้นตอนที่ 4)

HTTPS LB (รอง — ข้อมูลอ้างอิง ไม่บล็อกการดำเนินการต่อ):

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/http_loadbalancers/xF5XC_LB_NAMEx-https" \
| jq '{state: .spec.state, cert_state: .spec.cert_state}'
ฟิลด์ที่คาดหวังสถานะกลาง
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS ยังไม่ได้กำหนดค่า; VIRTUAL_HOST_DNS_A_RECORD_ADDED — พบ A record รอใบรับรอง
cert_stateCertificateValidPreDomainChallengePending — รอ ACME CNAME; DomainChallengeStarted — ACME challenge กำลังดำเนินการ; AutoCertDomainRateLimited — ถึงขีดจำกัด Let’s Encrypt rate limit (คาดหวังในสภาพแวดล้อมสาธิต ไม่ส่งผลต่อ HTTP LB)
Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \
| jq .

การตอบสนองมีฟิลด์ scriptTag พร้อม HTML <script> tag เต็มรูปแบบที่ load balancer inject เข้าไปใน page response

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \
| jq '{summary: .domain_summary, domains: .domains_list}'

scripts endpoint ต้องการช่วงเวลาโดยใช้ epoch timestamp (วินาทีนับจาก Unix epoch) ตัวอย่างด้านล่าง query 7 วันที่ผ่านมา

Terminal window
NOW=$(date +%s)
START=$(( NOW - 604800 ))
curl -s -X POST \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
-H "Content-Type: application/json" \
-d "{\"startTime\": \"$START\", \"endTime\": \"$NOW\"}" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \
| jq '[.scripts[]? | {script_name: .script_name, risk_level: .risk_level}]'

form fields endpoint ต้องการช่วงเวลาโดยใช้ epoch timestamp ส่งเป็น query parameter

Terminal window
NOW=$(date +%s)
START=$(( NOW - 604800 ))
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/formFields?startTime=$START&endTime=$NOW" \
| jq '.form_fields'

หลังจากทำการตรวจสอบทั้งหมดเสร็จสิ้น AI assistant ควรนำเสนอตารางสถานะแบบรวม:

Test IDการตรวจสอบที่คาดหวังจำเป็นสถานะ
DNS-1A Record resolvesส่งคืน VIP IPใช่PASS / FAIL
DNS-2ACME CNAME มีอยู่*.autocerts.ves.volterra.ioไม่PASS / PENDING
LB-1สถานะ HTTP LBVIRTUAL_HOST_READYใช่PASS / PENDING
LB-2สถานะ HTTPS LBVIRTUAL_HOST_READYไม่PASS / PENDING / INFO
TLS-1สถานะใบรับรองCertificateValidไม่PASS / PENDING / INFO
CSD-1JS configurationมี scriptTagใช่PASS / FAIL
CSD-2สถานะ CSDisEnabled: trueใช่PASS / FAIL
CSD-3Protected domainDomain ลงทะเบียนแล้วใช่PASS / FAIL

หาก LB-1 แสดง PENDING ให้ poll ทุก 30 วินาที สูงสุด 4 ครั้ง (รวม 2 นาที) หาก LB-1 ยังไม่เป็น VIRTUAL_HOST_READY หลังจาก 4 ครั้ง ให้ตรวจสอบ DNS resolution ด้วย dig และรายงานต่อผู้ดำเนินการ — อย่าดำเนินต่อจนกว่า LB-1 จะถึง READY สำหรับ LB-2 และ TLS-1 ให้ poll ทุก 60 วินาที สูงสุด 10 ครั้ง (10 นาที) หากยังอยู่ในสถานะกลางหลังจาก 10 ครั้ง ให้บันทึกสถานะปัจจุบันเป็น INFO และดำเนินต่อ — สิ่งเหล่านี้เป็นเพียงข้อมูลอ้างอิงและไม่บล็อกการดำเนินการสาธิต


Phase 1 เสร็จสมบูรณ์ ดำเนินต่อไปที่ Phase 2 — Attack เพื่อรันการจำลองการโจมตี