- 홈
- 클라이언트 측 방어
- Demo
- 1단계 — 빌드
1단계 — 빌드
1단계에서는 전체 CSD 인프라를 배포하고 검증합니다. 모든 단계를 순서대로 완료하십시오 — 각 단계는 다음 단계로 진행하기 전에 PASS가 되어야 합니다. 이 명령을 실행하기 전에 인덱스로 돌아가서 환경 설정 및 변수 해석을 완료하십시오.
0단계: 네임스페이스 확인 및 생성 (조건부)
섹션 제목: “0단계: 네임스페이스 확인 및 생성 (조건부)”테넌트에 대상 네임스페이스가 이미 존재하는지 확인합니다. 존재하지 않는 경우 생성합니다. NAMESPACE_CREATED 셸 변수에 결과를 기록합니다 — 4단계 정리 시 네임스페이스 삭제 여부를 결정하는 데 사용됩니다.
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네임스페이스가 존재하는지 확인하고 생성 여부를 기록합니다:
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 상태 | 200 | 반환되면 PASS, 404 또는 기타이면 FAIL |
NAMESPACE_CREATED | true (생성됨) 또는 false (기존에 존재) | 정보용 — 4단계 정리에서 사용 |
1단계: 헬스체크 생성 (선택 사항)
섹션 제목: “1단계: 헬스체크 생성 (선택 사항)”오리진 풀이 백엔드 상태를 모니터링하는 데 사용할 수 있는 HTTP 헬스체크를 생성합니다.
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 kind healthcheck has exhausted limits(150)"와 같은 메시지와 함께 "code": 8이 포함된 경우, 테넌트가 헬스체크 한도에 도달한 것입니다 — 2단계로 건너뛰고 헬스체크 참조를 생략하십시오. CSD는 상태 모니터링에 의존하지 않습니다.
헬스체크가 존재하는지 확인합니다:
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 상태 | 객체가 포함된 200 | 반환되면 PASS, 404이면 FAIL |
name | F5XC_HC_NAME과 일치 | PASS |
path | / | PASS |
1단계 건너뜀 (오류 코드 8, 한도 소진) | — | PASS (헬스체크는 CSD에서 선택 사항) |
2단계: 오리진 풀 생성
섹션 제목: “2단계: 오리진 풀 생성”백엔드 서버를 가리키는 오리진 풀을 생성합니다. 1단계에서 헬스체크를 생성한 경우 healthcheck 참조를 포함하십시오. 1단계를 건너뛴 경우 빈 배열을 사용하십시오.
헬스체크 포함 (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 .헬스체크 없음 (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 응답은 오리진 풀이 생성되었음을 확인합니다.
헬스체크 연결 확인
섹션 제목: “헬스체크 연결 확인”헬스체크 참조를 포함한 경우 올바르게 연결되어 있는지 확인합니다:
curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/config/namespaces/xF5XC_NAMESPACEx/origin_pools/xF5XC_ORIGIN_POOLx" \ | jq '.spec.healthcheck'배열이 채워져 있으면 연결이 확인됩니다. 1단계를 건너뛴 경우 빈 배열 []이 예상되며, 연결하려 했으나 헬스체크를 찾지 못한 경우에도 빈 배열이 반환됩니다.
오리진 풀이 존재하고 올바른 구성을 가지고 있는지 확인합니다:
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 상태 | 200 | 반환되면 PASS, 404이면 FAIL |
name | F5XC_ORIGIN_POOL과 일치 | PASS |
origin_ip | F5XC_ORIGIN_IP와 일치 | PASS |
port | F5XC_ORIGIN_PORT와 일치 | PASS |
healthcheck_count | 1 (HC 포함) 또는 0 (HC 없음) | 어느 쪽이든 PASS |
3단계: CSD를 사용한 HTTP 로드 밸런서 생성
섹션 제목: “3단계: CSD를 사용한 HTTP 로드 밸런서 생성”클라이언트 측 방어가 활성화된 두 개의 로드 밸런서를 생성합니다 — HTTP LB (기본, 포트 80)와 HTTPS LB (보조, 포트 443, 자동 인증서 관리). HTTP LB는 모든 데모 트래픽의 기본값입니다. HTTPS LB는 데모 환경에서 속도 제한에 걸릴 수 있는 Let’s Encrypt 인증서 프로비저닝에 의존하는 선택 사항입니다.
HTTP 로드 밸런서 (기본)
섹션 제목: “HTTP 로드 밸런서 (기본)”데모의 기본 로드 밸런서입니다. F5 XC 관리 DNS를 사용하여 포트 80에서 http 리스너를 사용합니다. TLS 인증서 프로비저닝에 의존하지 않으므로 DNS가 해석된 후 즉시 준비됩니다.
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 응답은 CSD가 활성화된 HTTP 로드 밸런서가 생성되었음을 확인합니다.
HTTPS 로드 밸런서 (보조)
섹션 제목: “HTTPS 로드 밸런서 (보조)”보조 로드 밸런서입니다. 자동 Let’s Encrypt 인증서 프로비저닝을 사용하여 포트 443에서 https_auto_cert를 사용합니다. 생성 전에 이전 정리 작업으로 인해 스켈레톤 HTTPS LB가 존재하는지 확인하십시오 — 존재하는 경우 기존 Let’s Encrypt 인증서를 보존하고 속도 제한을 피하기 위해 POST 대신 PUT으로 복원합니다 (동일한 식별자 세트당 7일에 중복 인증서 5개).
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이면 스켈레톤 HTTPS LB가 존재합니다 — **경로 A (PUT)**를 사용하십시오. 404이면 **경로 B (POST)**를 사용하십시오.
경로 A: PUT으로 스켈레톤 복원 (HTTPS LB 존재)
섹션 제목: “경로 A: PUT으로 스켈레톤 복원 (HTTPS LB 존재)”이전 정리 작업으로 스켈레톤 HTTPS LB가 존재하는 경우, PUT으로 전체 구성을 복원합니다. 이렇게 하면 오리진 풀을 다시 연결하고 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 응답은 스켈레톤이 전체 구성으로 복원되었음을 확인합니다. 인증서 상태는 CertificateValid로 유지되어야 합니다 — 새 Let’s Encrypt 프로비저닝이 트리거되지 않습니다.
경로 B: POST로 새로 생성 (HTTPS LB 없음)
섹션 제목: “경로 B: POST로 새로 생성 (HTTPS LB 없음)”HTTPS LB가 존재하지 않는 경우 (최초 실행 또는 전체 정리 후), 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 로드 밸런서가 생성되었음을 확인합니다. 인증서 프로비저닝이 자동으로 시작됩니다.
두 로드 밸런서가 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 상태 | 200 | 반환되면 PASS, 404이면 FAIL |
name | ${F5XC_LB_NAME}-http | PASS |
domains | F5XC_DOMAINNAME 포함 | PASS |
csd_enabled | true | PASS — 이 LB에 CSD가 구성됨 |
state | VIRTUAL_HOST_READY 또는 VIRTUAL_HOST_PENDING_A_RECORD | 예상됨 — HTTP LB는 DNS가 해석되면 READY로 전환됩니다. 다른 상태 (예: 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 상태 | 200 | 반환되면 PASS, 404이면 FAIL |
name | ${F5XC_LB_NAME}-https | PASS |
domains | F5XC_DOMAINNAME 포함 | PASS |
csd_enabled | true | PASS — 이 LB에 CSD가 구성됨 |
creation_method | PUT (스켈레톤 복원) 또는 POST (새로 생성) | INFO — PUT은 기존 인증서를 보존 |
state | VIRTUAL_HOST_READY (PUT) 또는 VIRTUAL_HOST_PENDING_A_RECORD (POST) | 예상됨 — PUT 경로는 스켈레톤에서 DNS가 유지되었으므로 이미 READY일 수 있음 |
cert_state | CertificateValid (PUT) 또는 PreDomainChallengePending (POST) | PUT은 기존 인증서를 보존; POST는 새 프로비저닝을 트리거 |
4단계: DNS 구성
섹션 제목: “4단계: DNS 구성”로드 밸런서를 생성한 후 VIRTUAL_HOST_PENDING_A_RECORD 상태로 진입하고 자동 인증서는 PreDomainChallengePending 상태를 유지합니다. LB가 완전히 운영되기 전에 두 개의 DNS 레코드가 존재해야 합니다:
- A 레코드 — LB 응답의
dns_info에서 VIP IP 주소를 가리키는xF5XC_DOMAINNAMEx - ACME 챌린지 레코드 — TLS 인증서 검증을 위한
_acme-challenge.xF5XC_DOMAINNAMEx(F5 XC DNS와 관리 레코드를 사용할 경우 자동으로 관리되며, 외부 DNS의 경우 수동 CNAME 필요)
접근 방식은 F5 XC가 도메인의 권한 있는 DNS 공급자인지 여부에 따라 달라집니다.
DNS 권한 감지
섹션 제목: “DNS 권한 감지”루트 도메인의 네임서버를 확인합니다:
dig +short NS xF5XC_ROOT_DOMAINx응답에 ns1.f5clouddns.com 및 ns2.f5clouddns.com이 포함된 경우, F5 XC가 권한 있는 DNS 공급자입니다 — 옵션 A를 따르십시오. 그렇지 않으면 외부 DNS의 경우 옵션 B를 따르십시오.
옵션 A: F5 XC 관리 DNS
섹션 제목: “옵션 A: F5 XC 관리 DNS”F5 XC가 권한 있는 DNS 공급자인 경우, 플랫폼이 A 레코드와 ACME 챌린지 CNAME을 모두 자동으로 생성할 수 있습니다 — 단, DNS 존에 allow_http_lb_managed_records가 활성화된 경우에만 가능합니다.
1. 관리 레코드가 활성화되어 있는지 확인:
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 레코드를 자동으로 생성합니다 — 3. DNS 해석 확인으로 건너뛰십시오. false 또는 null이면 다음 단계로 계속하십시오.
2. 관리 레코드 활성화:
현재 존 구성을 검색하고, 관리 레코드를 활성화한 후 업데이트합니다:
# 현재 존 구성 가져오기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 .200 응답 (빈 \{\})은 존이 업데이트되었음을 확인합니다. F5 XC는 존의 자동 관리 레코드 그룹에 A 레코드와 ACME 챌린지 레코드를 생성합니다. 60초 이내에 관리 레코드가 나타나지 않으면 로드 밸런서를 재적용하여 레코드 생성을 트리거하십시오:
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 재적용은 LB 구성을 변경하지 않습니다 — 단순히 플랫폼이 DNS 존을 재평가하고 관리 레코드를 생성하도록 트리거합니다. 재적용 후 60초 이내에 A 레코드가 여전히 해석되지 않으면 중단하고 운영자에게 보고하십시오 — 재적용을 한 번 이상 재시도하지 마십시오.
3. DNS 해석 확인:
dig +short xF5XC_DOMAINNAMEx A응답은 VIP IP 주소를 반환해야 합니다. F5 XC 관리 존의 DNS 전파는 일반적으로 즉각적이지만 최대 60초까지 기다리십시오.
옵션 B: 외부 DNS 공급자
섹션 제목: “옵션 B: 외부 DNS 공급자”도메인이 외부 DNS 공급자를 사용하는 경우, 레코드를 수동으로 생성해야 합니다. 로드 밸런서에서 필요한 값을 추출합니다:
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 }'DNS 공급자에서 다음 레코드를 생성합니다:
| 유형 | 이름 | 값 |
|---|---|---|
| A | xF5XC_DOMAINNAMEx | dns_info[0].ip_address의 VIP IP |
| CNAME | _acme-challenge.xF5XC_DOMAINNAMEx | *.autocerts.ves.volterra.io |
레코드를 생성한 후 해석을 확인합니다:
dig +short xF5XC_DOMAINNAMEx Adig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME| 테스트 | 명령 | 예상값 | 상태 |
|---|---|---|---|
| DNS-1: A 레코드 | dig +short $F5XC_DOMAINNAME A | VIP IP 주소 반환 | IP가 반환되면 PASS, 비어 있으면 FAIL |
| DNS-2: ACME CNAME | dig +short _acme-challenge.$F5XC_DOMAINNAME CNAME | *.autocerts.ves.volterra.io | CNAME이 반환되면 PASS |
| DNS 권한 | dig +short NS $F5XC_ROOT_DOMAIN | F5 XC 또는 외부 네임서버 | 정보용 — 옵션 A 대 B 결정 |
DNS-1이 60초 후에도 빈 값을 반환하면 문제 해결 — LB가 VIRTUAL_HOST_PENDING_A_RECORD에서 멈춤을 참조하십시오.
5단계: CSD 활성화 확인
섹션 제목: “5단계: CSD 활성화 확인”테넌트에 클라이언트 측 방어가 활성화되어 있는지 확인합니다. CSD는 테넌트 수준에서 구성됩니다 — 아직 활성화되지 않은 경우 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 — 테넌트 수준에서 CSD를 활성화하려면 F5 XC 관리자에게 문의하십시오 |
6단계: 보호 도메인 등록
섹션 제목: “6단계: 보호 도메인 등록”CSD가 모니터링할 루트 도메인을 등록합니다. protected_domain 필드는 전체 FQDN이 아닌 eTLD+1 루트 도메인 (예: f5demos.com)이어야 합니다.
이미 등록되어 있는지 확인
섹션 제목: “이미 등록되어 있는지 확인”생성 전에 도메인이 테넌트에 이미 등록되어 있는지 확인하십시오. POST에 대한 409 응답은 도메인이 이미 존재함을 의미합니다 — 이는 오류가 아닌 성공 조건입니다.
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 | 도메인이 성공적으로 등록됨 | 7단계로 계속 |
409 (도메인이 이미 존재) | 도메인이 이 테넌트에 이전에 등록됨 | 이미 완료됨 — 7단계로 계속 |
"code": 8 (한도 소진) | 보호 도메인 할당량 초과 | 차단 — 보호 도메인은 CSD에 필수입니다. 사용하지 않는 보호 도메인을 삭제하거나 관리자에게 문의하십시오. |
POST 응답 자체가 기본 증거입니다 — spec.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 반환 | 도메인이 등록되었거나 이미 존재 | PASS |
| 목록 항목 수 | > 0 | PASS |
7단계: 확인
섹션 제목: “7단계: 확인”DNS 해석
섹션 제목: “DNS 해석”A 레코드가 해석되고 ACME 챌린지 CNAME이 적용되어 있는지 확인합니다:
dig +short xF5XC_DOMAINNAMEx Adig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAMEA 레코드는 VIP IP 주소를 반환해야 합니다. CNAME은 *.autocerts.ves.volterra.io (또는 관련 autocerts 대상)를 가리켜야 합니다.
로드 밸런서 상태
섹션 제목: “로드 밸런서 상태”두 로드 밸런서가 대기 상태에서 전환되었는지 확인합니다. HTTP LB가 기본 확인 대상입니다 — DNS가 해석되면 VIRTUAL_HOST_READY에 도달해야 하며 인증서 의존성이 없습니다. 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 레코드가 발견됨, 인증서 대기 중 |
cert_state | CertificateValid | PreDomainChallengePending — ACME CNAME 대기 중; DomainChallengeStarted — ACME 챌린지 진행 중; AutoCertDomainRateLimited — Let’s Encrypt 속도 제한 도달 (데모 환경에서 예상됨, HTTP LB에 영향 없음) |
JS 구성
섹션 제목: “JS 구성”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \ | jq .응답에는 로드 밸런서가 페이지 응답에 삽입하는 전체 HTML <script> 태그가 포함된 scriptTag 필드가 있습니다.
감지된 도메인
섹션 제목: “감지된 도메인”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}'감지된 스크립트
섹션 제목: “감지된 스크립트”스크립트 엔드포인트는 에포크 타임스탬프 (Unix 에포크 이후의 초)를 사용한 시간 범위가 필요합니다. 아래 예시는 지난 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}]'폼 필드
섹션 제목: “폼 필드”폼 필드 엔드포인트는 쿼리 매개변수로 전달되는 에포크 타임스탬프를 사용한 시간 범위가 필요합니다.
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'1단계 증거 요약
섹션 제목: “1단계 증거 요약”모든 확인 검사를 완료한 후 AI 어시스턴트는 통합 상태 테이블을 제시해야 합니다:
| 테스트 ID | 확인 | 예상값 | 필수 여부 | 상태 |
|---|---|---|---|---|
| DNS-1 | A 레코드 해석 | 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 구성 | scriptTag 존재 | 예 | PASS / FAIL |
| CSD-2 | CSD 상태 | isEnabled: true | 예 | PASS / FAIL |
| CSD-3 | 보호 도메인 | 도메인 등록됨 | 예 | PASS / FAIL |
LB-1이 PENDING을 표시하면 최대 4번 반복 (총 2분) 동안 30초마다 폴링하십시오. 4번 반복 후에도 LB-1이 VIRTUAL_HOST_READY 상태가 아니면 dig으로 DNS 해석을 확인하고 운영자에게 보고하십시오 — LB-1이 READY에 도달할 때까지 진행하지 마십시오. LB-2와 TLS-1의 경우 최대 10번 반복 (10분) 동안 60초마다 폴링하십시오. 10번 반복 후에도 중간 상태이면 현재 상태를 INFO로 기록하고 진행하십시오 — 이는 정보 제공용이며 데모 진행을 차단하지 않습니다.
1단계 완료. 공격 시뮬레이션을 실행하려면 2단계 — 공격으로 진행하십시오.