Pular para o conteúdo

Fase 1 — Construção

A Fase 1 implanta e valida a infraestrutura CSD completa. Conclua todas as etapas em ordem — cada etapa deve receber PASS antes de prosseguir. Retorne ao índice para concluir a Configuração do Ambiente e a resolução de variáveis antes de executar estes comandos.

Etapa 0: Verificar e Criar Namespace (Condicional)

Seção intitulada “Etapa 0: Verificar e Criar Namespace (Condicional)”

Verifique se o namespace de destino já existe no tenant. Se não existir, crie-o. Registre o resultado na variável de shell NAMESPACE_CREATED — o processo de teardown da Fase 4 utiliza isso para decidir se deve excluir o 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

Confirme que o namespace existe e registre se foi criado:

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"
CampoEsperadoStatus
Status HTTP200PASS se retornado, FAIL se 404 ou outro
NAMESPACE_CREATEDtrue (criado) ou false (pré-existente)Informativo — utilizado pelo teardown da Fase 4

Crie um healthcheck HTTP que o origin pool possa usar para monitorar a integridade do 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 .

Uma resposta 200 com o objeto criado confirma que o healthcheck foi criado. Se a resposta contiver "code": 8 com uma mensagem como "Object kind healthcheck has exhausted limits(150)", o tenant atingiu seu limite de healthcheck — pule para a Etapa 2 e omita a referência de healthcheck. O CSD não depende de monitoramento de integridade.

Confirme que o healthcheck existe:

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}'
CampoEsperadoStatus
Status HTTP200 com objetoPASS se retornado, FAIL se 404
nameCorresponde a F5XC_HC_NAMEPASS
path/PASS
Etapa 1 ignorada (código de erro 8, limite esgotado)PASS (healthcheck é opcional para o CSD)

Crie um origin pool apontando para o seu servidor backend. Se você criou um healthcheck na Etapa 1, inclua a referência healthcheck. Se a Etapa 1 foi ignorada, use um array vazio.

Com healthcheck (Etapa 1 bem-sucedida):

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 .

Sem healthcheck (Etapa 1 ignorada):

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 .

Uma resposta 200 confirma que o origin pool foi criado.

Se você incluiu uma referência de healthcheck, confirme que está devidamente vinculado:

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'

Um array preenchido confirma o vínculo. Um array vazio [] é esperado se a Etapa 1 foi ignorada, ou indica que o healthcheck não foi encontrado caso você tenha pretendido vinculá-lo.

Confirme que o origin pool existe e possui a configuração correta:

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)}'
CampoEsperadoStatus
Status HTTP200PASS se retornado, FAIL se 404
nameCorresponde a F5XC_ORIGIN_POOLPASS
origin_ipCorresponde a F5XC_ORIGIN_IPPASS
portCorresponde a F5XC_ORIGIN_PORTPASS
healthcheck_count1 (com HC) ou 0 (sem)PASS em ambos os casos

Crie dois load balancers com Client-Side Defense habilitado — um LB HTTP (principal, porta 80) e um LB HTTPS (secundário, porta 443 com gerenciamento automático de certificados). O LB HTTP é o padrão para todo o tráfego da demonstração. O LB HTTPS é um adicional que depende do provisionamento de certificado Let’s Encrypt, que pode atingir limites de taxa em ambientes de demonstração.

Este é o load balancer principal para demonstrações. Ele usa um listener http na porta 80 com DNS gerenciado pelo F5 XC. Não depende do provisionamento de certificado TLS, portanto fica pronto imediatamente após a resolução do 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 .

Uma resposta 200 confirma que o load balancer HTTP foi criado com o CSD habilitado.

Este é o load balancer secundário. Ele usa https_auto_cert na porta 443 com provisionamento automático de certificado Let’s Encrypt. Antes de criá-lo, verifique se um LB HTTPS esqueleto existe de um teardown anterior — se existir, restaure-o via PUT em vez de POST para preservar o certificado Let’s Encrypt existente e evitar limites de taxa (5 certificados duplicados por conjunto exato de identificadores a cada 7 dias).

Verificar se o LB HTTPS já existe:

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 for 200, existe um LB HTTPS esqueleto — use o Caminho A (PUT). Se for 404, use o Caminho B (POST).

Caminho A: Restaurar Esqueleto via PUT (LB HTTPS existe)

Seção intitulada “Caminho A: Restaurar Esqueleto via PUT (LB HTTPS existe)”

Quando existe um LB HTTPS esqueleto de um teardown anterior, restaure a configuração completa via PUT. Isso reconecta o origin pool e reabilita o CSD sem acionar uma nova requisição de certificado Let’s Encrypt — o certificado existente permanece válido.

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 .

Uma resposta 200 confirma que o esqueleto foi restaurado com a configuração completa. O estado do certificado deve permanecer CertificateValid — nenhum novo provisionamento pelo Let’s Encrypt é acionado.

Caminho B: Criar Novo via POST (LB HTTPS não existe)

Seção intitulada “Caminho B: Criar Novo via POST (LB HTTPS não existe)”

Quando não existe nenhum LB HTTPS (primeira execução ou após um teardown completo), crie-o via POST. Isso aciona o provisionamento de certificado Let’s Encrypt, que pode levar de 5 a 10 minutos.

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 .

Uma resposta 200 confirma que o load balancer HTTPS foi criado. O provisionamento do certificado começa automaticamente.

Confirme que ambos os load balancers existem com o CSD habilitado. Sempre use um GET para evidência — a resposta do POST retorna valores de estado transitórios que podem não refletir a configuração estabilizada.

LB HTTP (principal):

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}'
CampoEsperadoStatus
Status HTTP200PASS se retornado, FAIL se 404
name${F5XC_LB_NAME}-httpPASS
domainsContém F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD está configurado neste LB
stateVIRTUAL_HOST_READY ou VIRTUAL_HOST_PENDING_A_RECORDEsperado — o LB HTTP transita para READY após a resolução do DNS. Qualquer outro estado (ex.: VIRTUAL_HOST_FAILED) é um FAIL — reporte ao operador e não prossiga

LB HTTPS (secundário):

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}'
CampoEsperadoStatus
Status HTTP200PASS se retornado, FAIL se 404
name${F5XC_LB_NAME}-httpsPASS
domainsContém F5XC_DOMAINNAMEPASS
csd_enabledtruePASS — CSD está configurado neste LB
creation_methodPUT (esqueleto restaurado) ou POST (novo)INFO — PUT preserva o certificado existente
stateVIRTUAL_HOST_READY (PUT) ou VIRTUAL_HOST_PENDING_A_RECORD (POST)Esperado — o caminho PUT pode já estar READY pois o DNS persistiu do esqueleto
cert_stateCertificateValid (PUT) ou PreDomainChallengePending (POST)PUT preserva o certificado existente; POST aciona novo provisionamento

Após criar o load balancer, ele entra no status VIRTUAL_HOST_PENDING_A_RECORD e o certificado automático permanece em PreDomainChallengePending. Dois registros DNS devem existir antes que o LB se torne totalmente operacional:

  1. Registro AxF5XC_DOMAINNAMEx apontando para o endereço IP do VIP (de dns_info na resposta do LB)
  2. Registro de desafio ACME_acme-challenge.xF5XC_DOMAINNAMEx para validação do certificado TLS (gerenciado automaticamente quando se usa o DNS do F5 XC com registros gerenciados; CNAME manual necessário para DNS externo)

A abordagem depende de o F5 XC ser ou não o provedor DNS autoritativo para o seu domínio.

Verifique os servidores de nomes do seu domínio raiz:

Terminal window
dig +short NS xF5XC_ROOT_DOMAINx

Se a resposta incluir ns1.f5clouddns.com e ns2.f5clouddns.com, o F5 XC é o provedor DNS autoritativo — siga a Opção A. Caso contrário, siga a Opção B para DNS externo.

Quando o F5 XC é o provedor DNS autoritativo, a plataforma pode criar automaticamente tanto o registro A quanto o CNAME de desafio ACME — mas somente quando a zona DNS tem allow_http_lb_managed_records habilitado.

1. Verificar se os registros gerenciados estão habilitados:

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 a resposta for true, a plataforma criará registros DNS automaticamente para os load balancers — pule para 3. Verificar resolução DNS. Se for false ou null, continue para a próxima etapa.

2. Habilitar registros gerenciados:

Recupere a configuração atual da zona, habilite os registros gerenciados e atualize:

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 .

Uma resposta 200 (vazia \{\}) confirma que a zona foi atualizada. O F5 XC criará o registro A e o registro de desafio ACME no grupo de registros gerenciados automaticamente da zona. Se os registros gerenciados não aparecerem em 60 segundos, reaplicar o load balancer para acionar a criação de registros:

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 .

Esta reaplicação GET+PUT não altera a configuração do LB — ela simplesmente aciona a plataforma para reavaliar a zona DNS e criar os registros gerenciados. Se o registro A ainda não resolver em 60 segundos após a reaplicação, pare e reporte ao operador — não repita a reaplicação mais de uma vez.

3. Verificar resolução DNS:

Terminal window
dig +short xF5XC_DOMAINNAMEx A

A resposta deve retornar o endereço IP do VIP. A propagação do DNS é tipicamente imediata para zonas gerenciadas pelo F5 XC, mas aguarde até 60 segundos.

Quando seu domínio usa um provedor DNS externo, você deve criar os registros manualmente. Extraia os valores necessários do 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
}'

Crie estes registros no seu provedor DNS:

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

Após criar os registros, verifique a resolução:

Terminal window
dig +short xF5XC_DOMAINNAMEx A
dig +short _acme-challenge.xF5XC_DOMAINNAMEx CNAME
TesteComandoEsperadoStatus
DNS-1: Registro Adig +short $F5XC_DOMAINNAME AEndereço IP do VIP retornadoPASS se IP retornado, FAIL se vazio
DNS-2: CNAME ACMEdig +short _acme-challenge.$F5XC_DOMAINNAME CNAME*.autocerts.ves.volterra.ioPASS se CNAME retornado
Autoridade DNSdig +short NS $F5XC_ROOT_DOMAINServidores de nomes F5 XC ou externosInformativo — determina Opção A vs B

Se DNS-1 retornar vazio após 60 segundos, consulte Solução de Problemas — LB Stuck in VIRTUAL_HOST_PENDING_A_RECORD.

Verifique se o Client-Side Defense está habilitado para o tenant. O CSD é configurado no nível do tenant — se ainda não foi habilitado, entre em contato com o administrador do F5 XC.

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

Uma resposta contendo "isConfigured": true e "isEnabled": true confirma que o CSD está ativo.

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}'
CampoEsperadoStatus
configuredtruePASS
enabledtruePASS
Qualquer um for falseFAIL — entre em contato com o administrador do F5 XC para habilitar o CSD no nível do tenant

Registre o domínio raiz que o CSD irá monitorar. O campo protected_domain deve ser o domínio raiz eTLD+1 (ex.: f5demos.com), não o FQDN completo.

Antes de criar, verifique se o domínio já está registrado no tenant. Uma resposta 409 ao POST significa que o domínio já existe — esta é uma condição de sucesso, não um erro.

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 .
RespostaSignificadoAção
200Domínio registrado com sucessoContinuar para a Etapa 7
409 (domínio já existe)Domínio foi registrado anteriormente neste tenantJá concluído — continuar para a Etapa 7
"code": 8 (limites esgotados)Cota de domínio protegido esgotadaBloqueante — domínios protegidos são obrigatórios para o CSD. Exclua domínios protegidos não utilizados ou entre em contato com o administrador.

A resposta do POST em si é a evidência principal — ela retorna o objeto de domínio registrado com spec.protected_domain correspondendo ao seu domínio raiz. Alternativamente, liste todos os domínios protegidos para confirmar:

Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/protected_domains" \
| jq '.items | length'
CampoEsperadoStatus
POST retornou protected_domainCorresponde a F5XC_ROOT_DOMAINPASS
POST retornou 200 ou 409Domínio registrado ou já existePASS
Contagem de itens na lista> 0PASS

Confirme que o registro A está resolvendo e que o CNAME de desafio ACME está configurado:

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

O registro A deve retornar o endereço IP do VIP. O CNAME deve apontar para *.autocerts.ves.volterra.io (ou um destino autocerts relacionado).

Verifique se ambos os load balancers saíram de seus estados pendentes. O LB HTTP é a verificação principal — ele deve atingir VIRTUAL_HOST_READY após a resolução do DNS, sem dependência de certificado. O estado do certificado do LB HTTPS é apenas informativo.

LB HTTP (principal — deve estar READY para prosseguir):

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}'
CampoEsperadoEstados Intermediários
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS não configurado (consulte a Etapa 4)

LB HTTPS (secundário — informativo, não bloqueia a progressão):

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}'
CampoEsperadoEstados Intermediários
stateVIRTUAL_HOST_READYVIRTUAL_HOST_PENDING_A_RECORD — DNS não configurado; VIRTUAL_HOST_DNS_A_RECORD_ADDED — registro A encontrado, aguardando certificado
cert_stateCertificateValidPreDomainChallengePending — aguardando CNAME ACME; DomainChallengeStarted — desafio ACME em andamento; AutoCertDomainRateLimited — limite de taxa do Let’s Encrypt atingido (esperado em ambientes de demonstração, não afeta o LB HTTP)
Terminal window
curl -s \
-H "Authorization: APIToken xF5XC_API_TOKENx" \
"xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/js_configuration" \
| jq .

A resposta contém um campo scriptTag com a tag HTML <script> completa que o load balancer injeta nas respostas das páginas.

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

O endpoint de scripts requer um intervalo de tempo usando timestamps epoch (segundos desde a época Unix). O exemplo abaixo consulta os últimos 7 dias.

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

O endpoint de campos de formulário requer um intervalo de tempo usando timestamps epoch, passados como parâmetros de consulta.

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'

Após concluir todas as verificações, o assistente de IA deve apresentar uma tabela de status consolidada:

ID do TesteVerificaçãoEsperadoObrigatórioStatus
DNS-1Registro A resolveIP do VIP retornadoSimPASS / FAIL
DNS-2CNAME ACME existe*.autocerts.ves.volterra.ioNãoPASS / PENDING
LB-1Estado do LB HTTPVIRTUAL_HOST_READYSimPASS / PENDING
LB-2Estado do LB HTTPSVIRTUAL_HOST_READYNãoPASS / PENDING / INFO
TLS-1Estado do certificadoCertificateValidNãoPASS / PENDING / INFO
CSD-1Configuração JSscriptTag presenteSimPASS / FAIL
CSD-2Status do CSDisEnabled: trueSimPASS / FAIL
CSD-3Domínio protegidoDomínio registradoSimPASS / FAIL

Se LB-1 mostrar PENDING, consulte a cada 30 segundos por até 4 iterações (2 minutos no total). Se LB-1 ainda não estiver VIRTUAL_HOST_READY após 4 iterações, verifique a resolução DNS com dig e reporte ao operador — não prossiga até que LB-1 atinja READY. Para LB-2 e TLS-1, consulte a cada 60 segundos por até 10 iterações (10 minutos). Se ainda estiver em estado intermediário após 10 iterações, registre o estado atual como INFO e prossiga — estes são informativos e não bloqueiam a progressão da demonstração.


Fase 1 concluída. Prossiga para a Fase 2 — Ataque para executar a simulação de ataque.