Salta ai contenuti

Fase 1 — Costruzione

La Fase 1 distribuisce e valida l’infrastruttura CSD completa. Completare tutti i passaggi in ordine — ogni passaggio deve risultare PASS prima di procedere. Tornare all’indice per completare la Configurazione dell’Ambiente e la risoluzione delle variabili prima di eseguire questi comandi.

Passaggio 0: Verifica e Creazione del Namespace (Condizionale)

Sezione intitolata “Passaggio 0: Verifica e Creazione del Namespace (Condizionale)”

Verificare se il namespace di destinazione esiste già sul tenant. Se non esiste, crearlo. Registrare il risultato nella variabile shell NAMESPACE_CREATED — il teardown della Fase 4 utilizza questo valore per decidere se eliminare il 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

Confermare che il namespace esiste e registrare se è stato creato:

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"
CampoAttesoStato
Stato HTTP200PASS se restituito, FAIL se 404 o altro
NAMESPACE_CREATEDtrue (creato) o false (pre-esistente)Informativo — utilizzato dal teardown della Fase 4

Passaggio 1: Creazione dell’Healthcheck (Opzionale)

Sezione intitolata “Passaggio 1: Creazione dell’Healthcheck (Opzionale)”

Creare un healthcheck HTTP che l’origin pool può utilizzare per monitorare lo stato del 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 .

Una risposta 200 con l’oggetto creato conferma che l’healthcheck è stato creato. Se la risposta contiene "code": 8 con un messaggio come "Object kind healthcheck has exhausted limits(150)", il tenant ha raggiunto il limite di healthcheck — passare al Passaggio 2 e omettere il riferimento all’healthcheck. CSD non dipende dal monitoraggio dello stato.

Confermare che l’healthcheck esiste:

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}'
CampoAttesoStato
Stato HTTP200 con oggettoPASS se restituito, FAIL se 404
nameCorrisponde a F5XC_HC_NAMEPASS
path/PASS
Passaggio 1 saltato (codice di errore 8, limite esaurito)PASS (l’healthcheck è opzionale per CSD)

Creare un origin pool che punta al server backend. Se è stato creato un healthcheck nel Passaggio 1, includere il riferimento healthcheck. Se il Passaggio 1 è stato saltato, utilizzare un array vuoto.

Con healthcheck (Passaggio 1 riuscito):

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 .

Senza healthcheck (Passaggio 1 saltato):

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 .

Una risposta 200 conferma che l’origin pool è stato creato.

Se è stato incluso un riferimento all’healthcheck, confermare che sia correttamente collegato:

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'

Un array popolato conferma il collegamento. Un array vuoto [] è atteso se il Passaggio 1 è stato saltato, oppure significa che l’healthcheck non è stato trovato se si intendeva collegarne uno.

Confermare che l’origin pool esiste e ha la configurazione corretta:

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)}'
CampoAttesoStato
Stato HTTP200PASS se restituito, FAIL se 404
nameCorrisponde a F5XC_ORIGIN_POOLPASS
origin_ipCorrisponde a F5XC_ORIGIN_IPPASS
portCorrisponde a F5XC_ORIGIN_PORTPASS
healthcheck_count1 (con HC) o 0 (senza)PASS in entrambi i casi

Passaggio 3: Creazione dei Load Balancer HTTP con CSD

Sezione intitolata “Passaggio 3: Creazione dei Load Balancer HTTP con CSD”

Creare due load balancer con Client-Side Defense abilitato — un LB HTTP (primario, porta 80) e un LB HTTPS (secondario, porta 443 con gestione automatica dei certificati). Il LB HTTP è quello predefinito per tutto il traffico demo. Il LB HTTPS è un elemento aggiuntivo che dipende dal provisioning dei certificati Let’s Encrypt, che può raggiungere i limiti di frequenza negli ambienti demo.

Questo è il load balancer primario per le demo. Utilizza un listener http sulla porta 80 con DNS gestito da F5 XC. Non dipende dal provisioning dei certificati TLS, quindi diventa pronto immediatamente dopo la risoluzione DNS.

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 .

Una risposta 200 conferma che l’HTTP load balancer è stato creato con CSD abilitato.

Questo è il load balancer secondario. Utilizza https_auto_cert sulla porta 443 con provisioning automatico dei certificati Let’s Encrypt. Prima di crearlo, verificare se esiste un LB HTTPS scheletro da un teardown precedente — in tal caso, ripristinarlo tramite PUT invece di POST per preservare il certificato Let’s Encrypt esistente ed evitare i limiti di frequenza (5 certificati duplicati per insieme esatto di identificatori ogni 7 giorni).

Verificare se il LB HTTPS esiste già:

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")

Se HTTPS_CHECK è 200, esiste un LB HTTPS scheletro — utilizzare il Percorso A (PUT). Se 404, utilizzare il Percorso B (POST).

Percorso A: Ripristino dello Scheletro tramite PUT (LB HTTPS esistente)

Sezione intitolata “Percorso A: Ripristino dello Scheletro tramite PUT (LB HTTPS esistente)”

Quando esiste un LB HTTPS scheletro da un teardown precedente, ripristinare la configurazione completa tramite PUT. Questo ricollega l’origin pool e riabilita CSD senza attivare una nuova richiesta di certificato Let’s Encrypt — il certificato esistente rimane valido.

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 .

Una risposta 200 conferma che lo scheletro è stato ripristinato con la configurazione completa. Lo stato del certificato dovrebbe rimanere CertificateValid — nessun nuovo provisioning Let’s Encrypt viene attivato.

Percorso B: Creazione Nuovo tramite POST (LB HTTPS non esistente)

Sezione intitolata “Percorso B: Creazione Nuovo tramite POST (LB HTTPS non esistente)”

Quando non esiste alcun LB HTTPS (prima esecuzione o dopo un teardown completo), crearlo tramite POST. Questo attiva il provisioning del certificato Let’s Encrypt, che può richiedere 5–10 minuti.

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 .

Una risposta 200 conferma che l’HTTPS load balancer è stato creato. Il provisioning del certificato inizia automaticamente.

Confermare che entrambi i load balancer esistono con CSD abilitato. Utilizzare sempre un GET per l’evidenza — la risposta POST restituisce valori di stato transitori che potrebbero non riflettere la configurazione stabilizzata.

LB HTTP (primario):

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}'
CampoAttesoStato
Stato HTTP200PASS se restituito, FAIL se 404
name${F5XC_LB_NAME}-httpPASS
domainsContiene F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD è configurato su questo LB
stateVIRTUAL_HOST_READY o VIRTUAL_HOST_PENDING_A_RECORDAtteso — il LB HTTP passa a READY una volta che il DNS si risolve. Qualsiasi altro stato (es. VIRTUAL_HOST_FAILED) è un FAIL — segnalare all’operatore e non procedere

LB HTTPS (secondario):

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}'
CampoAttesoStato
Stato HTTP200PASS se restituito, FAIL se 404
name${F5XC_LB_NAME}-httpsPASS
domainsContiene F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD è configurato su questo LB
creation_methodPUT (scheletro ripristinato) o POST (nuovo)INFO — PUT preserva il certificato esistente
stateVIRTUAL_HOST_READY (PUT) o VIRTUAL_HOST_PENDING_A_RECORD (POST)Atteso — il percorso PUT potrebbe essere già READY poiché il DNS è persistito dallo scheletro
cert_stateCertificateValid (PUT) o PreDomainChallengePending (POST)PUT preserva il certificato esistente; POST attiva un nuovo provisioning

Dopo la creazione del load balancer, questo entra nello stato VIRTUAL_HOST_PENDING_A_RECORD e il certificato automatico rimane in PreDomainChallengePending. Due record DNS devono esistere prima che il LB diventi pienamente operativo:

  1. Record AxF5XC_DOMAINNAMEx che punta all’indirizzo IP VIP (da dns_info nella risposta del LB)
  2. Record ACME challenge_acme-challenge.xF5XC_DOMAINNAMEx per la validazione del certificato TLS (gestito automaticamente quando si utilizza il DNS F5 XC con record gestiti; CNAME manuale richiesto per DNS esterno)

L’approccio dipende dal fatto che F5 XC sia il provider DNS autoritativo per il proprio dominio.

Verificare i nameserver per il dominio radice:

Terminal window
dig +short NS xF5XC_ROOT_DOMAINx

Se la risposta include ns1.f5clouddns.com e ns2.f5clouddns.com, F5 XC è il provider DNS autoritativo — seguire l’Opzione A. In caso contrario, seguire l’Opzione B per DNS esterno.

Quando F5 XC è il provider DNS autoritativo, la piattaforma può creare automaticamente sia il record A che il CNAME ACME challenge — ma solo quando la zona DNS ha allow_http_lb_managed_records abilitato.

1. Verificare se i record gestiti sono abilitati:

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'

Se la risposta è true, la piattaforma creerà automaticamente i record DNS per i load balancer — passare a 3. Verifica della risoluzione DNS. Se false o null, continuare con il passaggio successivo.

2. Abilitare i record gestiti:

Recuperare la configurazione corrente della zona, abilitare i record gestiti e aggiornare:

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 .

Una risposta 200 (vuota \{\}) conferma che la zona è stata aggiornata. F5 XC creerà il record A e il record ACME challenge nel gruppo di record auto-gestiti della zona. Se i record gestiti non appaiono entro 60 secondi, riapplicare il load balancer per attivare la creazione dei 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 .

Questo GET+PUT di riapplicazione non modifica la configurazione del LB — semplicemente attiva la piattaforma per rivalutare la zona DNS e creare i record gestiti. Se il record A non si risolve ancora entro 60 secondi dopo la riapplicazione, fermarsi e segnalare all’operatore — non riprovare la riapplicazione più di una volta.

3. Verifica della risoluzione DNS:

Terminal window
dig +short xF5XC_DOMAINNAMEx A

La risposta dovrebbe restituire l’indirizzo IP VIP. La propagazione DNS è tipicamente immediata per le zone gestite da F5 XC, ma attendere fino a 60 secondi.

Quando il dominio utilizza un provider DNS esterno, è necessario creare i record manualmente. Estrarre i valori richiesti dal 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
}'

Creare questi record presso il proprio provider DNS:

TipoNomeValore
AxF5XC_DOMAINNAMExIP VIP da dns_info[0].ip_address
CNAME_acme-challenge.xF5XC_DOMAINNAMEx*.autocerts.ves.volterra.io

Dopo aver creato i record, verificare la risoluzione:

Terminal window
dig +short xF5XC_DOMAINNAMEx A
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
TestComandoAttesoStato
DNS-1: Record Adig +short $F5XC_DOMAINNAME AIndirizzo IP VIP restituitoPASS se IP restituito, FAIL se vuoto
DNS-2: CNAME ACMEdig +short _acme-challenge.$F5XC_DOMAINNAME CNAME*.autocerts.ves.volterra.ioPASS se CNAME restituito
Autorità DNSdig +short NS $F5XC_ROOT_DOMAINNameserver F5 XC o esterniInformativo — determina Opzione A vs B

Se DNS-1 restituisce vuoto dopo 60 secondi, vedere Risoluzione dei problemi — LB Bloccato in VIRTUAL_HOST_PENDING_A_RECORD.

Verificare che Client-Side Defense sia abilitato per il tenant. CSD è configurato a livello di tenant — se non è ancora stato abilitato, contattare l’amministratore F5 XC.

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

Una risposta contenente "isConfigured": true e "isEnabled": true conferma che CSD è attivo.

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}'
CampoAttesoStato
configuredtruePASS
enabledtruePASS
Uno dei due è falseFAIL — contattare l’amministratore F5 XC per abilitare CSD a livello di tenant

Registrare il dominio radice che CSD monitorerà. Il campo protected_domain deve essere il dominio radice eTLD+1 (es., f5demos.com), non il FQDN completo.

Prima di creare, verificare se il dominio è già registrato sul tenant. Una risposta 409 al POST significa che il dominio esiste già — questa è una condizione di successo, non un errore.

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 .
RispostaSignificatoAzione
200Dominio registrato con successoContinuare al Passaggio 7
409 (dominio già esistente)Il dominio era precedentemente registrato su questo tenantGià fatto — continuare al Passaggio 7
"code": 8 (limiti esauriti)Quota domini protetti esauritaBloccante — i domini protetti sono obbligatori per CSD. Eliminare i domini protetti inutilizzati o contattare l’amministratore.

La risposta POST stessa è l’evidenza primaria — restituisce l’oggetto dominio registrato con spec.protected_domain corrispondente al dominio radice. In alternativa, elencare tutti i domini protetti per confermare:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq '.items | length'
CampoAttesoStato
POST ha restituito protected_domainCorrisponde a F5XC_ROOT_DOMAINPASS
POST ha restituito 200 o 409Dominio registrato o già esistentePASS
Conteggio elementi lista> 0PASS

Confermare che il record A si sta risolvendo e che il CNAME ACME challenge è in posizione:

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

Il record A dovrebbe restituire l’indirizzo IP VIP. Il CNAME dovrebbe puntare a *.autocerts.ves.volterra.io (o un target autocerts correlato).

Verificare che entrambi i load balancer siano usciti dai loro stati di attesa. Il LB HTTP è il controllo primario — dovrebbe raggiungere VIRTUAL_HOST_READY una volta che il DNS si risolve, senza dipendenza dal certificato. Lo stato del certificato del LB HTTPS è solo informativo.

LB HTTP (primario — deve essere READY per procedere):

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}'
CampoAttesoStati Intermedi
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS non configurato (vedere Passaggio 4)

LB HTTPS (secondario — informativo, non blocca la progressione):

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}'
CampoAttesoStati Intermedi
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS non configurato; VIRTUAL_HOST_DNS_A_RECORD_ADDED — Record A trovato, in attesa del certificato
cert_stateCertificateValidPreDomainChallengePending — in attesa del CNAME ACME; DomainChallengeStarted — ACME challenge in corso; AutoCertDomainRateLimited — limite di frequenza Let’s Encrypt raggiunto (atteso negli ambienti demo, non influisce sul LB HTTP)
Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \
| jq .

La risposta contiene un campo scriptTag con il tag HTML <script> completo che il load balancer inietta nelle risposte delle pagine.

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}'

L’endpoint degli script richiede un intervallo temporale che utilizza timestamp epoch (secondi dall’epoca Unix). L’esempio seguente interroga gli ultimi 7 giorni.

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}]'

L’endpoint dei campi dei form richiede un intervallo temporale che utilizza timestamp epoch, passati come parametri di query.

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'

Dopo aver completato tutti i controlli di verifica, l’assistente AI dovrebbe presentare una tabella di stato consolidata:

ID TestControlloAttesoObbligatorioStato
DNS-1Record A si risolveIP VIP restituitoPASS / FAIL
DNS-2CNAME ACME esiste*.autocerts.ves.volterra.ioNoPASS / PENDING
LB-1Stato LB HTTPVIRTUAL_HOST_READYPASS / PENDING
LB-2Stato LB HTTPSVIRTUAL_HOST_READYNoPASS / PENDING / INFO
TLS-1Stato certificatoCertificateValidNoPASS / PENDING / INFO
CSD-1Configurazione JSscriptTag presentePASS / FAIL
CSD-2Stato CSDisEnabled: truePASS / FAIL
CSD-3Dominio protettoDominio registratoPASS / FAIL

Se LB-1 mostra PENDING, effettuare un polling ogni 30 secondi per un massimo di 4 iterazioni (2 minuti in totale). Se LB-1 non è ancora VIRTUAL_HOST_READY dopo 4 iterazioni, verificare la risoluzione DNS con dig e segnalare all’operatore — non procedere finché LB-1 non raggiunge READY. Per LB-2 e TLS-1, effettuare un polling ogni 60 secondi per un massimo di 10 iterazioni (10 minuti). Se ancora in uno stato intermedio dopo 10 iterazioni, registrare lo stato corrente come INFO e procedere — sono informativi e non bloccano la progressione della demo.


Fase 1 completata. Procedere alla Fase 2 — Attacco per eseguire la simulazione di attacco.