Skip to content

Sincronização de tempo — TLSStress.Art

Leia no seu idioma: English · Português · Español

Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze. Tempo preciso em todo host do test bed não é opcional. Sem ele, as medições que este produto foi construído para produzir são forensicamente inúteis e enganarão qualquer pessoa que as leia.

Por que NTP é crítico para ESTE produto

Componente O que dá errado se o desvio do clock for > 5 s
TLS handshakes Validações de NotBefore/NotAfter do certificado rejeitam certs válidos → handshakes falham intermitentemente. O TLS Decrypt Probe vê a falha mas não consegue distinguir de "NGFW quebrado"
Métricas Prometheus Timestamps fora de ordem envenenam painéis, cálculos de SLO quebram, warnings de "future timestamp" inundam os logs
Comparação entre engagements Dois engenheiros em geografias diferentes rodando o mesmo plano produzem números com timestamps no momento errado, quebrando o contrato de "comparável entre engagements"
Forense de logs de auditoria Linhas de aceite de licença, eventos de tamper-check de fingerprint, grants do access-broker — todos precisam de created_at preciso para ter valor legal
Tempo de fases do test plan Um plano de 30 min precisa de 30 minutos reais; desvio corta fases curtas demais ou as estende além do timeline
Assinaturas Cosign (Phase 4) Janelas notBefore/notAfter da assinatura dependem de clock preciso
Correlação de syslog do NGFW Engenheiros cruzando observações do test-bed com logs FTD/Palo veem timestamps que não alinham — debug demora 10× mais
Distributed tracing (Tempo/OTel) Timing de spans requer clocks sincronizados; off-by-1s dá spans com duração negativa
Timestamps de aceite de licença Aceite no primeiro login registrado com tempo errado parece backdating

Limiares aceitáveis

Desvio Estado Ação
< 100 ms Ideal Correlação cross-host perfeita
100 ms–1 s OK A maioria das métricas + TLS funciona normalmente
1 s–5 s Degradado TLS pode falhar intermitentemente; correlação de métricas sofre; alerta NodeClockSkewDegraded dispara
> 5 s Inválido Runs são forensicamente inúteis. Alerta NodeClockSkewInvalid dispara; abortar runs ativos; não iniciar novos
Daemon não rodando Crítico Alerta NodeNotSyncedToNTP dispara; clock vai derivar sem limites

Esses limiares estão codificados em k8s/dut/17-time-sync-rules.yaml.

Instalações conectadas — fontes recomendadas

Em ordem aproximada de preferência:

  1. Cisco-internalntp1.cisco.com, ntp2.cisco.com (se acessíveis a partir da sua rede)
  2. Âncoras stratum-1 distintas — pelo menos três de:
  3. time.cloudflare.com (anycast, jitter muito baixo)
  4. time.google.com / time1.google.comtime4.google.com
  5. time.nist.gov
  6. 2.pool.ntp.org (community pool, fallback decente)
  7. Roteador Cisco ou Nexus local — muitos sites já rodam NTP master no próprio equipamento

Configure com chrony (preferido em vez de systemd-timesyncd para produção — melhor visibilidade, resync mais rápido):

# /etc/chrony/chrony.conf
pool time.cloudflare.com iburst minpoll 5 maxpoll 7
pool time.google.com iburst minpoll 5 maxpoll 7
server 2.pool.ntp.org iburst minpoll 6 maxpoll 8

# Allow synchronization with sources that have stratum > 0
makestep 1 3
rtcsync
local stratum 10
sudo systemctl restart chronyd
sudo chronyc tracking
sudo chronyc sources -v

Instalações air-gapped — fonte NTP interna

Em um data center totalmente isolado, o laptop que prepara o bundle tem internet mas o UCS não. Servidores NTP públicos são inalcançáveis a partir do UCS. A cadeia recomendada:

External GPS / atomic clock
        │
        ▼
Site stratum-1 NTP server  (Cisco router, Meinberg, GPS-disciplined NTP appliance)
        │
        ▼
Lab stratum-2  (Nexus 9000 acting as NTP server, OR a dedicated Linux NTP host)
        │
        ▼
UCS host(s)   (chrony pointed at lab stratum-2)

Cisco Nexus 9000 como servidor NTP (caminho mais comum)

! On the Nexus:
configure terminal
ntp server 192.168.10.1 prefer    ! site stratum-1
ntp server 192.168.10.2          ! backup
ntp source-interface mgmt0
ntp authenticate                  ! optional; recommended for compliance
end
write memory
show ntp peer-status
show ntp peers

chrony do UCS apontado para o Nexus

# /etc/chrony/chrony.conf
server <nexus-mgmt-ip> iburst prefer minpoll 4 maxpoll 6
makestep 1 3
rtcsync
sudo systemctl restart chronyd
sudo chronyc waitsync 30 0.05    # wait up to 30 polls for offset < 50 ms

Se o seu site não tem uma âncora stratum-1, a próxima melhor opção é um GPS-disciplined NTP appliance (~US$1500-3000) instalado no lab e apontado para o céu visível. Esse é o padrão para instalações classificadas.

O que você absolutamente não pode fazer em air-gap

  • ❌ Apontar chrony para pool.ntp.org — inalcançável
  • ❌ Usar a config padrão do systemd-timesyncd — também tenta atingir servidores públicos
  • ❌ Rodar sem NTP — o desvio do RTC em x86 commodity fica em torno de 1 s por dia; em hosts KVM virtualizados commodity pode chegar a 1 minuto por dia sob carga. Depois de uma semana, todas as medições estão inválidas.

Deploys multi-node

Em setups dual / tri / multi-node, todo host UCS deve apontar para a mesma fonte stratum-2 para que convirjam ao mesmo tempo. Caso contrário, seus offsets divergem em dezenas de milissegundos.

O alerta MultiHostClockDivergence dispara quando dois hosts quaisquer no cluster diferem em > 1 s, independentemente de cada um estar individualmente sincronizado. A correção é sempre: apontar todos os hosts para o mesmo upstream.

Verificação (manual)

O script empacotado scripts/check-time-sync.sh faz isso por você:

./scripts/check-time-sync.sh
# exit 0 = OK
# exit 1 = degraded (drift 1-5s, or strict mode + drift > 100ms)
# exit 2 = INVALID (drift > 5s, or daemon unsynchronized)
# exit 3 = no time daemon installed

Saída JSON para o dashboard:

./scripts/check-time-sync.sh --json
# {"status":"ok","drift_ms":4,"source":"NEXUS-MGMT","reason":""}

Modo estrito (alerta mesmo em desvios pequenos, útil antes de iniciar um run crítico):

./scripts/check-time-sync.sh --strict

Rode em todo host antes de um run multi-node:

for host in ucs-1 ucs-2 ucs-3; do
  ssh $host "$(< scripts/check-time-sync.sh)" --json
done

Alertas in-cluster

A PrometheusRule time-sync-validity (em k8s/dut/17-time-sync-rules.yaml) emite quatro alertas:

  • NodeClockSkewDegraded — desvio > 1 s, severity warning
  • NodeClockSkewInvalid — desvio > 5 s, severity critical, ABORT runs
  • NodeNotSyncedToNTP — daemon não reporta status de sincronização, severity critical
  • MultiHostClockDivergence — hosts discordam em > 1 s, severity warning

A engine de Test Plan (Phase 3+, melhoria futura) recusará iniciar um run se qualquer um desses alertas estiver disparando.

Checklist de sintomas

Você provavelmente tem um problema de sincronização de tempo se:

  • ✗ O TLS Decrypt Probe alterna aleatoriamente entre active e unknown
  • ✗ Painéis Grafana dizem "no data" mesmo com targets do Prometheus UP
  • ✗ Alguns agentes registram, outros não — logs de register-retry mostram "expired" / "before NotBefore"
  • kubectl get events mostra erros de validação de certificado do nada
  • ✗ A página Runs do Dashboard mostra entradas com started_at no futuro
  • ✗ Spans de tracing no Tempo têm durações negativas
  • ✗ Múltiplos operadores do mesmo UCS reportam resultados inconsistentes

Quando algum desses surgir: pare, rode ./scripts/check-time-sync.sh, depois investigue. Não persiga o sintoma enquanto o clock está errado — você vai perder horas.

Recuperando-se de desvio severo

Se o desvio for > 60 s, o makestep padrão do chrony não se aplica (ele limita aos primeiros 3 updates). Force-step:

sudo chronyc -a 'burst 4/4'
sudo chronyc -a makestep
sudo chronyc tracking

Se o desvio for > 1 hora (ex.: hardware novo com bateria do RTC descarregada + sem NTP), defina o tempo manualmente primeiro e depois deixe o chrony estabilizar:

sudo timedatectl set-time '2026-05-06 14:35:00 UTC'
sudo systemctl restart chronyd

Relacionados