Ir al contenido

Fase 1 — Construcción

La Fase 1 despliega y valida la infraestructura completa de CSD. Complete todos los pasos en orden — cada paso debe superar la verificación (PASS) antes de continuar. Regrese al índice para completar la configuración del entorno y la resolución de variables antes de ejecutar estos comandos.

Paso 0: Verificar y crear el namespace (condicional)

Sección titulada «Paso 0: Verificar y crear el namespace (condicional)»

Compruebe si el namespace de destino ya existe en el tenant. Si no existe, créelo. Registre el resultado en la variable de shell NAMESPACE_CREATED — el proceso de desmontaje de la Fase 4 utiliza este valor para decidir si eliminar el namespace.

Ventana de terminal
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

Confirme que el namespace existe y registre si fue creado:

Ventana de terminal
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"
CampoEsperadoEstado
Estado HTTP200PASS si se devuelve, FAIL si 404 u otro
NAMESPACE_CREATEDtrue (creado) o false (preexistente)Informativo — utilizado por el desmontaje de la Fase 4

Cree un healthcheck HTTP que el grupo de origen pueda utilizar para supervisar el estado del backend.

Ventana de terminal
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 respuesta 200 con el objeto creado confirma que el healthcheck fue creado. Si la respuesta contiene "code": 8 con un mensaje como "Object kind healthcheck has exhausted limits(150)", el tenant ha alcanzado su límite de healthchecks — continúe con el Paso 2 y omita la referencia al healthcheck. CSD no depende de la supervisión del estado.

Confirme que el healthcheck existe:

Ventana de terminal
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}'
CampoEsperadoEstado
Estado HTTP200 con objetoPASS si se devuelve, FAIL si 404
nameCoincide con F5XC_HC_NAMEPASS
path/PASS
Paso 1 omitido (código de error 8, límite agotado)PASS (el healthcheck es opcional para CSD)

Cree un grupo de origen que apunte a su servidor backend. Si creó un healthcheck en el Paso 1, incluya la referencia healthcheck. Si se omitió el Paso 1, utilice un array vacío.

Con healthcheck (Paso 1 exitoso):

Ventana de terminal
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 .

Sin healthcheck (Paso 1 omitido):

Ventana de terminal
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 respuesta 200 confirma que el grupo de origen fue creado.

Verificar que el healthcheck está vinculado

Sección titulada «Verificar que el healthcheck está vinculado»

Si incluyó una referencia al healthcheck, confirme que está correctamente vinculado:

Ventana de terminal
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 con contenido confirma el vínculo. Un array vacío [] es el resultado esperado si se omitió el Paso 1, o indica que el healthcheck no fue encontrado si tenía intención de vincularlo.

Confirme que el grupo de origen existe y tiene la configuración correcta:

Ventana de terminal
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)}'
CampoEsperadoEstado
Estado HTTP200PASS si se devuelve, FAIL si 404
nameCoincide con F5XC_ORIGIN_POOLPASS
origin_ipCoincide con F5XC_ORIGIN_IPPASS
portCoincide con F5XC_ORIGIN_PORTPASS
healthcheck_count1 (con HC) o 0 (sin HC)PASS en ambos casos

Paso 3: Crear balanceadores de carga HTTP con CSD

Sección titulada «Paso 3: Crear balanceadores de carga HTTP con CSD»

Cree dos balanceadores de carga con Defensa del lado del cliente habilitada — un LB HTTP (primario, puerto 80) y un LB HTTPS (secundario, puerto 443 con gestión automática de certificados). El LB HTTP es el predeterminado para todo el tráfico de la demostración. El LB HTTPS es complementario y depende del aprovisionamiento de certificados Let’s Encrypt, que puede alcanzar límites de frecuencia en entornos de demostración.

Este es el balanceador de carga primario para las demostraciones. Utiliza un listener http en el puerto 80 con DNS gestionado por F5 XC. No depende del aprovisionamiento de certificados TLS, por lo que queda listo inmediatamente después de que el DNS se resuelva.

Ventana de terminal
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 respuesta 200 confirma que el balanceador de carga HTTP fue creado con CSD habilitado.

Este es el balanceador de carga secundario. Utiliza https_auto_cert en el puerto 443 con aprovisionamiento automático de certificados Let’s Encrypt. Antes de crearlo, verifique si existe un LB HTTPS esqueleto de un desmontaje anterior — si es así, restáurelo mediante PUT en lugar de POST para preservar el certificado Let’s Encrypt existente y evitar los límites de frecuencia (5 certificados duplicados por conjunto exacto de identificadores cada 7 días).

Verificar si el LB HTTPS ya existe:

Ventana de terminal
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")

Si HTTPS_CHECK es 200, existe un LB HTTPS esqueleto — utilice la Ruta A (PUT). Si es 404, utilice la Ruta B (POST).

Ruta A: Restaurar esqueleto mediante PUT (el LB HTTPS existe)

Sección titulada «Ruta A: Restaurar esqueleto mediante PUT (el LB HTTPS existe)»

Cuando existe un LB HTTPS esqueleto de un desmontaje anterior, restaure la configuración completa mediante PUT. Esto vuelve a conectar el grupo de origen y re-habilita CSD sin activar una nueva solicitud de certificado Let’s Encrypt — el certificado existente permanece válido.

Ventana de terminal
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 respuesta 200 confirma que el esqueleto fue restaurado con la configuración completa. El estado del certificado debería permanecer en CertificateValid — no se activa ningún nuevo aprovisionamiento de Let’s Encrypt.

Ruta B: Crear nuevo mediante POST (el LB HTTPS no existe)

Sección titulada «Ruta B: Crear nuevo mediante POST (el LB HTTPS no existe)»

Cuando no existe un LB HTTPS (primera ejecución o tras un desmontaje completo), créelo mediante POST. Esto activa el aprovisionamiento del certificado Let’s Encrypt, que puede tardar entre 5 y 10 minutos.

Ventana de terminal
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 respuesta 200 confirma que el balanceador de carga HTTPS fue creado. El aprovisionamiento del certificado comienza automáticamente.

Confirme que ambos balanceadores de carga existen con CSD habilitado. Utilice siempre un GET para la evidencia — la respuesta del POST devuelve valores de estado transitorios que pueden no reflejar la configuración establecida.

LB HTTP (primario):

Ventana de terminal
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}'
CampoEsperadoEstado
Estado HTTP200PASS si se devuelve, FAIL si 404
name${F5XC_LB_NAME}-httpPASS
domainsContiene F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD está configurado en este LB
stateVIRTUAL_HOST_READY o VIRTUAL_HOST_PENDING_A_RECORDEsperado — el LB HTTP pasa a READY una vez que el DNS se resuelve. Cualquier otro estado (por ejemplo, VIRTUAL_HOST_FAILED) es un FAIL — informe al operador y no continúe

LB HTTPS (secundario):

Ventana de terminal
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}'
CampoEsperadoEstado
Estado HTTP200PASS si se devuelve, FAIL si 404
name${F5XC_LB_NAME}-httpsPASS
domainsContiene F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD está configurado en este LB
creation_methodPUT (esqueleto restaurado) o POST (nuevo)INFO — PUT preserva el certificado existente
stateVIRTUAL_HOST_READY (PUT) o VIRTUAL_HOST_PENDING_A_RECORD (POST)Esperado — la ruta PUT puede ya estar en READY dado que el DNS persistió desde el esqueleto
cert_stateCertificateValid (PUT) o PreDomainChallengePending (POST)PUT preserva el certificado existente; POST activa nuevo aprovisionamiento

Después de crear el balanceador de carga, este pasa al estado VIRTUAL_HOST_PENDING_A_RECORD y el certificado automático permanece en PreDomainChallengePending. Deben existir dos registros DNS antes de que el LB quede completamente operativo:

  1. Registro AxF5XC_DOMAINNAMEx apuntando a la dirección IP VIP (obtenida de dns_info en la respuesta del LB)
  2. Registro de desafío ACME_acme-challenge.xF5XC_DOMAINNAMEx para la validación del certificado TLS (gestionado automáticamente cuando se utiliza DNS de F5 XC con registros gestionados; se requiere CNAME manual para DNS externo)

El enfoque depende de si F5 XC es el proveedor DNS autoritativo para su dominio.

Compruebe los servidores de nombres para su dominio raíz:

Ventana de terminal
dig +short NS xF5XC_ROOT_DOMAINx

Si la respuesta incluye ns1.f5clouddns.com y ns2.f5clouddns.com, F5 XC es el proveedor DNS autoritativo — siga la Opción A. De lo contrario, siga la Opción B para DNS externo.

Cuando F5 XC es el proveedor DNS autoritativo, la plataforma puede crear automáticamente tanto el registro A como el CNAME del desafío ACME — pero solo cuando la zona DNS tiene habilitado allow_http_lb_managed_records.

1. Verificar si los registros gestionados están habilitados:

Ventana de terminal
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'

Si la respuesta es true, la plataforma creará automáticamente los registros DNS para los balanceadores de carga — continúe en 3. Verificar la resolución DNS. Si es false o null, continúe con el paso siguiente.

2. Habilitar los registros gestionados:

Recupere la configuración actual de la zona, habilite los registros gestionados y actualice:

Ventana de terminal
# 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 respuesta 200 (vacía \{\}) confirma que la zona fue actualizada. F5 XC creará el registro A y el registro del desafío ACME en el grupo de registros gestionados automáticamente de la zona. Si los registros gestionados no aparecen en 60 segundos, vuelva a aplicar el balanceador de carga para activar la creación de registros:

Ventana de terminal
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 .

Esta reaplicación GET+PUT no modifica la configuración del LB — simplemente indica a la plataforma que vuelva a evaluar la zona DNS y cree los registros gestionados. Si el registro A aún no se resuelve en los 60 segundos posteriores a la reaplicación, deténgase e informe al operador — no reintente la reaplicación más de una vez.

3. Verificar la resolución DNS:

Ventana de terminal
dig +short xF5XC_DOMAINNAMEx A

La respuesta debería devolver la dirección IP VIP. La propagación DNS suele ser inmediata para las zonas gestionadas por F5 XC, pero espere hasta 60 segundos.

Cuando su dominio utiliza un proveedor DNS externo, debe crear los registros manualmente. Extraiga los valores requeridos del balanceador de carga:

Ventana de terminal
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
}'

Cree estos registros en su proveedor DNS:

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

Después de crear los registros, verifique la resolución:

Ventana de terminal
dig +short xF5XC_DOMAINNAMEx A
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
PruebaComandoEsperadoEstado
DNS-1: Registro Adig +short $F5XC_DOMAINNAME ADirección IP VIP devueltaPASS si se devuelve IP, FAIL si está vacío
DNS-2: CNAME ACMEdig +short _acme-challenge.$F5XC_DOMAINNAME CNAME*.autocerts.ves.volterra.ioPASS si se devuelve CNAME
Autoridad DNSdig +short NS $F5XC_ROOT_DOMAINServidores de nombres de F5 XC o externosInformativo — determina Opción A vs B

Si DNS-1 devuelve vacío después de 60 segundos, consulte Solución de problemas — LB bloqueado en VIRTUAL_HOST_PENDING_A_RECORD.

Compruebe que la Defensa del lado del cliente está habilitada para el tenant. CSD se configura a nivel de tenant — si aún no se ha habilitado, contacte a su administrador de F5 XC.

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

Una respuesta que contiene "isConfigured": true e "isEnabled": true confirma que CSD está activo.

Ventana de terminal
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/status" \
| jq '{configured: .isConfigured, enabled: .isEnabled}'
CampoEsperadoEstado
configuredtruePASS
enabledtruePASS
Alguno es falseFAIL — contacte al administrador de F5 XC para habilitar CSD a nivel de tenant

Registre el dominio raíz que CSD supervisará. El campo protected_domain debe ser el dominio raíz eTLD+1 (por ejemplo, f5demos.com), no el FQDN completo.

Antes de crear, compruebe si el dominio ya está registrado en el tenant. Una respuesta 409 al POST significa que el dominio ya existe — esta es una condición de éxito, no un error.

Ventana de terminal
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 .
RespuestaSignificadoAcción
200Dominio registrado correctamenteContinúe con el Paso 7
409 (el dominio ya existe)El dominio fue registrado anteriormente en este tenantYa realizado — continúe con el Paso 7
"code": 8 (límite agotado)Cuota de dominios protegidos llenaBloqueante — los dominios protegidos son obligatorios para CSD. Elimine dominios protegidos no utilizados o contacte a su administrador.

La respuesta del POST en sí es la evidencia principal — devuelve el objeto del dominio registrado con spec.protected_domain coincidiendo con su dominio raíz. Alternativamente, liste todos los dominios protegidos para confirmar:

Ventana de terminal
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq '.items | length'
CampoEsperadoEstado
POST devolvió protected_domainCoincide con F5XC_ROOT_DOMAINPASS
POST devolvió 200 o 409Dominio registrado o ya existePASS
Recuento de elementos en la lista> 0PASS

Confirme que el registro A se está resolviendo y que el CNAME del desafío ACME está en su lugar:

Ventana de terminal
dig +short xF5XC_DOMAINNAMEx A
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME

El registro A debería devolver la dirección IP VIP. El CNAME debería apuntar a *.autocerts.ves.volterra.io (o un destino autocerts relacionado).

Compruebe que ambos balanceadores de carga han salido de sus estados pendientes. El LB HTTP es la verificación principal — debería alcanzar VIRTUAL_HOST_READY una vez que el DNS se resuelva, sin dependencia de certificados. El estado del certificado del LB HTTPS es solo informativo.

LB HTTP (primario — debe estar en READY para continuar):

Ventana de terminal
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}'
CampoEsperadoEstados intermedios
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS no configurado (consulte el Paso 4)

LB HTTPS (secundario — informativo, no bloquea la progresión):

Ventana de terminal
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}'
CampoEsperadoEstados intermedios
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS no configurado; VIRTUAL_HOST_DNS_A_RECORD_ADDED — registro A encontrado, esperando certificado
cert_stateCertificateValidPreDomainChallengePending — esperando CNAME ACME; DomainChallengeStarted — desafío ACME en progreso; AutoCertDomainRateLimited — límite de frecuencia de Let’s Encrypt alcanzado (esperado en entornos de demostración, no afecta al LB HTTP)
Ventana de terminal
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \
| jq .

La respuesta contiene un campo scriptTag con la etiqueta HTML <script> completa que el balanceador de carga inyecta en las respuestas de página.

Ventana de terminal
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}'

El endpoint de scripts requiere un rango de tiempo usando marcas de tiempo epoch (segundos desde el epoch Unix). El ejemplo siguiente consulta los últimos 7 días.

Ventana de terminal
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}]'

El endpoint de campos de formulario requiere un rango de tiempo usando marcas de tiempo epoch, pasadas como parámetros de consulta.

Ventana de terminal
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'

Después de completar todas las verificaciones, el asistente de IA debe presentar una tabla de estado consolidada:

ID de pruebaVerificaciónEsperadoObligatorioEstado
DNS-1Registro A resuelveIP VIP devueltaPASS / FAIL
DNS-2CNAME ACME existe*.autocerts.ves.volterra.ioNoPASS / PENDING
LB-1Estado del LB HTTPVIRTUAL_HOST_READYPASS / PENDING
LB-2Estado del LB HTTPSVIRTUAL_HOST_READYNoPASS / PENDING / INFO
TLS-1Estado del certificadoCertificateValidNoPASS / PENDING / INFO
CSD-1Configuración de JSscriptTag presentePASS / FAIL
CSD-2Estado de CSDisEnabled: truePASS / FAIL
CSD-3Dominio protegidoDominio registradoPASS / FAIL

Si LB-1 muestra PENDING, sondee cada 30 segundos hasta 4 iteraciones (2 minutos en total). Si LB-1 sigue sin estar en VIRTUAL_HOST_READY después de 4 iteraciones, verifique la resolución DNS con dig e informe al operador — no continúe hasta que LB-1 alcance READY. Para LB-2 y TLS-1, sondee cada 60 segundos hasta 10 iteraciones (10 minutos). Si aún se encuentra en un estado intermedio después de 10 iteraciones, registre el estado actual como INFO y continúe — estos son informativos y no bloquean la progresión de la demostración.


Fase 1 completada. Continúe con la Fase 2 — Ataque para ejecutar la simulación de ataque.