- หน้าแรก
- การป้องกันฝั่งไคลเอนต์
- Demo
- Phase 1 — สร้าง
Phase 1 — สร้าง
Phase 1 ปรับใช้และตรวจสอบโครงสร้างพื้นฐาน CSD ทั้งหมด ดำเนินการทุกขั้นตอนตามลำดับ — แต่ละขั้นตอนต้องผ่าน (PASS) ก่อนดำเนินการต่อ กลับไปที่ index เพื่อทำการตั้งค่าสภาพแวดล้อมและการกำหนดค่าตัวแปรก่อนรันคำสั่งเหล่านี้
ขั้นตอนที่ 0: ตรวจสอบและสร้าง Namespace (มีเงื่อนไข)
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 0: ตรวจสอบและสร้าง Namespace (มีเงื่อนไข)”ตรวจสอบว่า namespace เป้าหมายมีอยู่บน tenant แล้วหรือไม่ หากไม่มี ให้สร้างขึ้นมา บันทึกผลลัพธ์ในตัวแปร shell NAMESPACE_CREATED — Phase 4 teardown จะใช้ตัวแปรนี้เพื่อตัดสินใจว่าจะลบ namespace หรือไม่
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 มีอยู่และบันทึกว่ามีการสร้างขึ้นหรือไม่:
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 Status | 200 | PASS หากได้รับ, FAIL หาก 404 หรืออื่นๆ |
NAMESPACE_CREATED | true (สร้างใหม่) หรือ false (มีอยู่แล้ว) | ข้อมูลอ้างอิง — ใช้โดย Phase 4 teardown |
ขั้นตอนที่ 1: สร้าง Healthcheck (ไม่บังคับ)
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 1: สร้าง Healthcheck (ไม่บังคับ)”สร้าง HTTP healthcheck ที่ origin pool สามารถใช้เพื่อตรวจสอบสุขภาพของ backend
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 มีอยู่:
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 Status | 200 พร้อม object | PASS หากได้รับ, FAIL หาก 404 |
name | ตรงกับ F5XC_HC_NAME | PASS |
path | / | PASS |
ข้ามขั้นตอนที่ 1 แล้ว (error code 8, ถึงขีดจำกัด) | — | PASS (healthcheck ไม่บังคับสำหรับ CSD) |
ขั้นตอนที่ 2: สร้าง Origin Pool
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 2: สร้าง Origin Pool”สร้าง origin pool ที่ชี้ไปยัง backend server ของคุณ หากคุณสร้าง healthcheck ในขั้นตอนที่ 1 ให้รวมการอ้างอิง healthcheck หากข้ามขั้นตอนที่ 1 ให้ใช้ array ว่าง
พร้อม healthcheck (ขั้นตอนที่ 1 สำเร็จ):
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):
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 ถูกเชื่อมโยงแล้ว
หัวข้อที่มีชื่อว่า “ตรวจสอบว่า Healthcheck ถูกเชื่อมโยงแล้ว”หากคุณรวมการอ้างอิง healthcheck ให้ยืนยันว่าเชื่อมโยงอย่างถูกต้อง:
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 มีอยู่และมีการกำหนดค่าที่ถูกต้อง:
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 Status | 200 | PASS หากได้รับ, FAIL หาก 404 |
name | ตรงกับ F5XC_ORIGIN_POOL | PASS |
origin_ip | ตรงกับ F5XC_ORIGIN_IP | PASS |
port | ตรงกับ F5XC_ORIGIN_PORT | PASS |
healthcheck_count | 1 (มี HC) หรือ 0 (ไม่มี) | PASS ทั้งสองกรณี |
ขั้นตอนที่ 3: สร้าง HTTP Load Balancer พร้อม CSD
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 3: สร้าง HTTP Load Balancer พร้อม CSD”สร้าง load balancer สอง ตัวที่เปิดใช้งาน การป้องกันฝั่งไคลเอนต์ — HTTP LB (หลัก, พอร์ต 80) และ HTTPS LB (รอง, พอร์ต 443 พร้อมการจัดการใบรับรองอัตโนมัติ) HTTP LB เป็นค่าเริ่มต้นสำหรับทราฟฟิกการสาธิตทั้งหมด HTTPS LB เป็นสิ่งที่ดีเพิ่มเติมที่ขึ้นอยู่กับการจัดสรรใบรับรอง Let’s Encrypt ซึ่งอาจถึงขีดจำกัด rate limit ในสภาพแวดล้อมสาธิต
HTTP Load Balancer (หลัก)
หัวข้อที่มีชื่อว่า “HTTP Load Balancer (หลัก)”นี่คือ load balancer หลัก สำหรับการสาธิต ใช้ http listener บนพอร์ต 80 พร้อม F5 XC managed DNS ไม่ขึ้นอยู่กับการจัดสรรใบรับรอง TLS ดังนั้นจึงพร้อมใช้งานทันทีหลังจาก DNS resolves
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 เปิดใช้งาน
HTTPS Load Balancer (รอง)
หัวข้อที่มีชื่อว่า “HTTPS Load Balancer (รอง)”นี่คือ 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 มีอยู่แล้วหรือไม่:
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)
Path A: กู้คืน Skeleton ผ่าน PUT (HTTPS LB มีอยู่แล้ว)
หัวข้อที่มีชื่อว่า “Path A: กู้คืน Skeleton ผ่าน PUT (HTTPS LB มีอยู่แล้ว)”เมื่อมี skeleton HTTPS LB จาก teardown ก่อนหน้า ให้กู้คืนการกำหนดค่าเต็มรูปแบบผ่าน PUT การดำเนินการนี้จะเชื่อมต่อ origin pool อีกครั้งและเปิดใช้งาน CSD ใหม่ โดยไม่ต้องส่งคำขอใบรับรอง Let’s Encrypt ใหม่ — ใบรับรองที่มีอยู่ยังคงใช้งานได้
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 ใหม่ถูกกระตุ้น
Path B: สร้างใหม่ผ่าน POST (HTTPS LB ไม่มีอยู่)
หัวข้อที่มีชื่อว่า “Path B: สร้างใหม่ผ่าน POST (HTTPS LB ไม่มีอยู่)”เมื่อไม่มี HTTPS LB อยู่ (ครั้งแรกหรือหลังจาก full teardown) ให้สร้างผ่าน POST การดำเนินการนี้จะเริ่มการจัดสรรใบรับรอง Let’s Encrypt ซึ่งอาจใช้เวลา 5–10 นาที
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 (หลัก):
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 Status | 200 | PASS หากได้รับ, FAIL หาก 404 |
name | ${F5XC_LB_NAME}-http | PASS |
domains | มี F5XC_DOMAINNAME | PASS |
csd_enabled | true | PASS — CSD ถูกกำหนดค่าบน LB นี้ |
state | VIRTUAL_HOST_READY หรือ VIRTUAL_HOST_PENDING_A_RECORD | คาดหวัง — HTTP LB จะเปลี่ยนเป็น READY เมื่อ DNS resolves สถานะอื่นๆ (เช่น VIRTUAL_HOST_FAILED) เป็น FAIL — รายงานต่อผู้ดำเนินการและอย่าดำเนินการต่อ |
HTTPS LB (รอง):
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 Status | 200 | PASS หากได้รับ, FAIL หาก 404 |
name | ${F5XC_LB_NAME}-https | PASS |
domains | มี F5XC_DOMAINNAME | PASS |
csd_enabled | true | PASS — CSD ถูกกำหนดค่าบน LB นี้ |
creation_method | PUT (กู้คืน skeleton) หรือ POST (สร้างใหม่) | INFO — PUT รักษาใบรับรองที่มีอยู่ |
state | VIRTUAL_HOST_READY (PUT) หรือ VIRTUAL_HOST_PENDING_A_RECORD (POST) | คาดหวัง — PUT path อาจเป็น READY แล้วเนื่องจาก DNS ยังคงอยู่จาก skeleton |
cert_state | CertificateValid (PUT) หรือ PreDomainChallengePending (POST) | PUT รักษาใบรับรองที่มีอยู่; POST กระตุ้นการจัดสรรใหม่ |
ขั้นตอนที่ 4: กำหนดค่า DNS
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 4: กำหนดค่า DNS”หลังจากสร้าง load balancer แล้ว จะเข้าสู่สถานะ VIRTUAL_HOST_PENDING_A_RECORD และใบรับรองอัตโนมัติจะอยู่ใน PreDomainChallengePending DNS record สองรายการต้องมีอยู่ก่อนที่ LB จะทำงานได้อย่างสมบูรณ์:
- A record —
xF5XC_DOMAINNAMExชี้ไปยัง VIP IP address (จากdns_infoใน LB response) - ACME challenge record —
_acme-challenge.xF5XC_DOMAINNAMExสำหรับการตรวจสอบใบรับรอง TLS (จัดการโดยอัตโนมัติเมื่อใช้ F5 XC DNS พร้อม managed records; ต้องใช้ manual CNAME สำหรับ DNS ภายนอก)
วิธีการขึ้นอยู่กับว่า F5 XC เป็น authoritative DNS provider สำหรับ domain ของคุณหรือไม่
ตรวจหา DNS Authority
หัวข้อที่มีชื่อว่า “ตรวจหา DNS Authority”ตรวจสอบ nameserver สำหรับ root domain ของคุณ:
dig +short NS xF5XC_ROOT_DOMAINxหากการตอบสนองรวมถึง ns1.f5clouddns.com และ ns2.f5clouddns.com F5 XC เป็น authoritative DNS provider — ทำตาม Option A มิฉะนั้น ทำตาม Option B สำหรับ external DNS
Option A: F5 XC Managed DNS
หัวข้อที่มีชื่อว่า “Option A: F5 XC Managed DNS”เมื่อ F5 XC เป็น authoritative DNS provider แพลตฟอร์มสามารถสร้าง A record และ ACME challenge CNAME ทั้งสองโดยอัตโนมัติ — แต่เฉพาะเมื่อ DNS zone มี allow_http_lb_managed_records เปิดใช้งาน
1. ตรวจสอบว่า managed records เปิดใช้งานอยู่หรือไม่:
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 และอัปเดต:
# Get current zone configZONE_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 enabledecho "$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:
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:
dig +short xF5XC_DOMAINNAMEx Aการตอบสนองควรส่งคืน VIP IP address DNS propagation มักจะเกิดขึ้นทันทีสำหรับ F5 XC managed zones แต่ให้รอสูงสุด 60 วินาที
Option B: External DNS Provider
หัวข้อที่มีชื่อว่า “Option B: External DNS Provider”เมื่อ domain ของคุณใช้ external DNS provider คุณต้องสร้าง record ด้วยตนเอง ดึงค่าที่จำเป็นจาก load balancer:
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 ของคุณ:
| ประเภท | ชื่อ | ค่า |
|---|---|---|
| A | xF5XC_DOMAINNAMEx | VIP IP จาก dns_info[0].ip_address |
| CNAME | _acme-challenge.xF5XC_DOMAINNAMEx | *.autocerts.ves.volterra.io |
หลังจากสร้าง record แล้ว ให้ตรวจสอบ resolution:
dig +short xF5XC_DOMAINNAMEx Adig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAMEหลักฐาน
หัวข้อที่มีชื่อว่า “หลักฐาน”| การทดสอบ | คำสั่ง | ที่คาดหวัง | สถานะ |
|---|---|---|---|
| DNS-1: A Record | dig +short $F5XC_DOMAINNAME A | ส่งคืน VIP IP address | PASS หากได้รับ IP, FAIL หากว่าง |
| DNS-2: ACME CNAME | dig +short _acme-challenge.$F5XC_DOMAINNAME CNAME | *.autocerts.ves.volterra.io | PASS หากได้รับ CNAME |
| DNS authority | dig +short NS $F5XC_ROOT_DOMAIN | F5 XC หรือ external nameserver | ข้อมูลอ้างอิง — กำหนด Option A หรือ B |
หาก DNS-1 ส่งคืนว่างหลังจาก 60 วินาที ดู Troubleshooting — LB Stuck in VIRTUAL_HOST_PENDING_A_RECORD
ขั้นตอนที่ 5: ตรวจสอบว่า CSD เปิดใช้งาน
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 5: ตรวจสอบว่า CSD เปิดใช้งาน”ตรวจสอบว่า การป้องกันฝั่งไคลเอนต์ เปิดใช้งานสำหรับ tenant CSD ถูกกำหนดค่าในระดับ tenant — หากยังไม่ได้เปิดใช้งาน ให้ติดต่อผู้ดูแลระบบ F5 XC ของคุณ
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \ | jq .การตอบสนองที่มี "isConfigured": true และ "isEnabled": true ยืนยันว่า CSD ทำงานอยู่
หลักฐาน
หัวข้อที่มีชื่อว่า “หลักฐาน”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \ | jq '{configured: .isConfigured, enabled: .isEnabled}'| ฟิลด์ | ที่คาดหวัง | สถานะ |
|---|---|---|
configured | true | PASS |
enabled | true | PASS |
ค่าใดค่าหนึ่งเป็น false | — | FAIL — ติดต่อผู้ดูแลระบบ F5 XC เพื่อเปิดใช้งาน CSD ในระดับ tenant |
ขั้นตอนที่ 6: ลงทะเบียน Protected Domain
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 6: ลงทะเบียน Protected Domain”ลงทะเบียน root domain ที่ CSD จะตรวจสอบ ฟิลด์ protected_domain ต้องเป็น eTLD+1 root domain (เช่น f5demos.com) ไม่ใช่ FQDN เต็มรูปแบบ
ตรวจสอบว่าลงทะเบียนแล้วหรือไม่
หัวข้อที่มีชื่อว่า “ตรวจสอบว่าลงทะเบียนแล้วหรือไม่”ก่อนสร้าง ให้ตรวจสอบว่า domain ลงทะเบียนบน tenant แล้วหรือไม่ การตอบสนอง 409 ต่อ POST หมายความว่า domain มีอยู่แล้ว — นี่คือเงื่อนไขสำเร็จ ไม่ใช่ข้อผิดพลาด
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 ทั้งหมดเพื่อยืนยัน:
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_DOMAIN | PASS |
POST ส่งคืน 200 หรือ 409 | Domain ลงทะเบียนแล้วหรือมีอยู่แล้ว | PASS |
| จำนวน list items | > 0 | PASS |
ขั้นตอนที่ 7: ตรวจสอบ
หัวข้อที่มีชื่อว่า “ขั้นตอนที่ 7: ตรวจสอบ”DNS Resolution
หัวข้อที่มีชื่อว่า “DNS Resolution”ยืนยันว่า A record กำลัง resolving และ ACME challenge CNAME อยู่ในที่:
dig +short xF5XC_DOMAINNAMEx Adig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAMEA record ควรส่งคืน VIP IP address CNAME ควรชี้ไปที่ *.autocerts.ves.volterra.io (หรือ autocerts target ที่เกี่ยวข้อง)
สถานะ Load Balancer
หัวข้อที่มีชื่อว่า “สถานะ Load Balancer”ตรวจสอบว่า load balancer ทั้งสองเปลี่ยนออกจากสถานะ pending แล้ว HTTP LB เป็นการตรวจสอบหลัก — ควรถึง VIRTUAL_HOST_READY เมื่อ DNS resolves โดยไม่มีการพึ่งพาใบรับรอง สถานะใบรับรอง HTTPS LB เป็นเพียงข้อมูลอ้างอิง
HTTP LB (หลัก — ต้องเป็น READY เพื่อดำเนินต่อ):
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}'| ฟิลด์ | ที่คาดหวัง | สถานะกลาง |
|---|---|---|
state | VIRTUAL_HOST_READY | VIRTUAL_HOST_PENDING_A_RECORD — DNS ยังไม่ได้กำหนดค่า (ดูขั้นตอนที่ 4) |
HTTPS LB (รอง — ข้อมูลอ้างอิง ไม่บล็อกการดำเนินการต่อ):
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}'| ฟิลด์ | ที่คาดหวัง | สถานะกลาง |
|---|---|---|
state | VIRTUAL_HOST_READY | VIRTUAL_HOST_PENDING_A_RECORD — DNS ยังไม่ได้กำหนดค่า; VIRTUAL_HOST_DNS_A_RECORD_ADDED — พบ A record รอใบรับรอง |
cert_state | CertificateValid | PreDomainChallengePending — รอ ACME CNAME; DomainChallengeStarted — ACME challenge กำลังดำเนินการ; AutoCertDomainRateLimited — ถึงขีดจำกัด Let’s Encrypt rate limit (คาดหวังในสภาพแวดล้อมสาธิต ไม่ส่งผลต่อ HTTP LB) |
JS Configuration
หัวข้อที่มีชื่อว่า “JS Configuration”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
Detected Domains
หัวข้อที่มีชื่อว่า “Detected Domains”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}'Detected Scripts
หัวข้อที่มีชื่อว่า “Detected Scripts”scripts endpoint ต้องการช่วงเวลาโดยใช้ epoch timestamp (วินาทีนับจาก Unix epoch) ตัวอย่างด้านล่าง query 7 วันที่ผ่านมา
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
หัวข้อที่มีชื่อว่า “Form Fields”form fields endpoint ต้องการช่วงเวลาโดยใช้ epoch timestamp ส่งเป็น query parameter
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'สรุปหลักฐาน Phase 1
หัวข้อที่มีชื่อว่า “สรุปหลักฐาน Phase 1”หลังจากทำการตรวจสอบทั้งหมดเสร็จสิ้น AI assistant ควรนำเสนอตารางสถานะแบบรวม:
| Test ID | การตรวจสอบ | ที่คาดหวัง | จำเป็น | สถานะ |
|---|---|---|---|---|
| DNS-1 | A Record resolves | ส่งคืน VIP IP | ใช่ | PASS / FAIL |
| DNS-2 | ACME CNAME มีอยู่ | *.autocerts.ves.volterra.io | ไม่ | PASS / PENDING |
| LB-1 | สถานะ HTTP LB | VIRTUAL_HOST_READY | ใช่ | PASS / PENDING |
| LB-2 | สถานะ HTTPS LB | VIRTUAL_HOST_READY | ไม่ | PASS / PENDING / INFO |
| TLS-1 | สถานะใบรับรอง | CertificateValid | ไม่ | PASS / PENDING / INFO |
| CSD-1 | JS configuration | มี scriptTag | ใช่ | PASS / FAIL |
| CSD-2 | สถานะ CSD | isEnabled: true | ใช่ | PASS / FAIL |
| CSD-3 | Protected domain | Domain ลงทะเบียนแล้ว | ใช่ | 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 เพื่อรันการจำลองการโจมตี