OpenCyber Academy
Engenharia · Capítulo 47 · Português
Código do curso: OCA-137Capítulo 47: OCA-137-C047

Capítulo 47 — Ensaio de falha e recuperação

Ensino gratuito e aberto para quem deseja proteger pessoas e tecnologias. Não é preciso criar uma conta para estudar ou consultar as respostas.

Mapa da aula

Aula 47 publicada. Mapa, exemplo, EX139.

flowchart TD
  N0["47.1 Roteiro"]
  N1["47.2 Medidas"]
  N2["47.3 Ações corretivas"]
  N3["Nota prática"]
  N4["47.1b Correção sem culpa e recorrência"]
  N5["Nota de campo — o mau sinal dos zero tickets"]
  N6["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6
  N6 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX139"]

Desenho lógico

flowchart LR
  N0["47.1 Roteiro"]
  N1["47.2 Medidas"]
  N2["47.3 Ações corretivas"]
  N3["Nota prática"]
  N4["47.1b Correção sem culpa e recorrência"]
  N5["Nota de campo — o mau sinal dos zero tickets"]
  N6["Síntese"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> Q["EX139"]
[47.1 Roteiro]
    |
    v
[47.2 Medidas]
    |
    v
[47.3 Ações corretivas]
    |
    v
[Nota prática]
    |
    v
[47.1b Correção sem culpa e recorrência]
    |
    v
[Nota de campo — o mau sinal dos zero tickets]
    |
    v
[Síntese]
    |
    v
[Exemplo resolvido] --> [Exercício EX139]

Objetivos de aprendizagem

Você vai (1) conduzir um ensaio de falha roteirizado; (2) medir o tempo de recuperação; (3) registrar ações corretivas.

47.1 Roteiro

Injetar: arquivo da lista de permissões apagado; repositório de constatações derrubado; defasagem de relógio; reprodução de eventos duplicados; grafo plano no lugar do zoneado. Observar negações, filas, alertas, reprovação da alcançabilidade.

No ensaio de falha na bancada da ABP, a equipe de Lena apagou o arquivo da lista de permissões enquanto o tráfego reproduzido rodava, depois derrubou o repositório de constatações, defasou o relógio na cópia de bancada do PLC-A e reproduziu eventos duplicados. Por fim, substituiu o grafo zoneado por um plano. Os observadores registraram se as escritas foram negadas, se as constatações foram enfileiradas, se os alertas dispararam e se a verificação de alcançabilidade reprovou o grafo plano. Cada injeção foi executada separadamente antes de qualquer combinação ser tentada.

47.2 Medidas

Tempo até negar todas as escritas depois da perda da política; tempo até o alerta; tempo até a restauração; constatações perdidas (deveria ser 0 com a fila); a verificação de alcançabilidade do SIS continua falhando de forma fechada com um grafo ruim.

Na ABP, o ensaio mediu 45 segundos até negar todas as escritas depois que a lista de permissões foi apagada, contra uma meta de 30 segundos. Os alertas dispararam dentro da meta, e nenhuma constatação se perdeu, porque os rascunhos foram enfileirados enquanto o repositório de constatações estava fora do ar. A verificação de alcançabilidade reprovou corretamente quando o grafo plano foi substituído, mostrando o SIS-B como alcançável. Cada medida foi registrada por um observador com cronômetro e conferida contra os logs, então os números não dependeram da memória de ninguém.

47.3 Ações corretivas

Cada falha num exercício do CNHP vira um ticket com dono e prazo — não apenas um slide de lições aprendidas.

# Lab 27 - residual CUSUM vs band on batch reactor level (synthetic)
import random
def run(seed, atk, det, k=0.8, h=6.0):
    rng=random.Random(seed); true=est=50.0; s=0.0; alarm=None
    for t in range(500):
        inflow=1.0+rng.gauss(0,0.05)+(0.08 if atk and t>=250 else 0)
        true+=inflow-0.02*true
        lvl=true+rng.gauss(0,0.3); fm=inflow+rng.gauss(0,0.02)
        if atk and t>=250: lvl=50+rng.gauss(0,0.3)
        if atk=="B" and t>=250: fm=1.0+rng.gauss(0,0.02)
        est+=fm-0.02*est
        hit=abs(lvl-50)>2.0 if det=="band" else False
        if det=="cusum":
            s=max(0.0,s+abs(lvl-est)-k); hit=s>h
        if hit and alarm is None: alarm=t
    return alarm
for det in ("band","cusum"):
    fa=sum(run(i,None,det) is not None for i in range(60))
    for atk in ("A","B"):
        hits=[a-250 for a in (run(i,atk,det) for i in range(60)) if a is not None and a>=250]
        print(f"{det} class{atk} FA={fa}/60 det={len(hits)}/60 mean_delay={sum(hits)/len(hits) if hits else float('nan'):.1f}")

Saída esperada:

band classA FA=0/60 det=0/60 mean_delay=nan
band classB FA=0/60 det=0/60 mean_delay=nan
cusum classA FA=0/60 det=60/60 mean_delay=24.8
cusum classB FA=0/60 det=0/60 mean_delay=nan

Caso sintético — Ashford Batch Plant. O ensaio mostrou 45 s até negar todas as escritas; meta de 30 s — o intervalo de consulta foi apertado.

Na ABP, o tempo de negação de 45 segundos virou um ticket para o dono do monitor, com prazo. A correção encurtou o intervalo de verificação da política, e a injeção foi repetida até atingir a meta duas vezes. O ticket só foi encerrado depois da segunda execução aprovada, e a data do ensaio seguinte foi reservada antes que os observadores saíssem da sala.

47.4 Erros e limites

Ensaios em janelas de produção são proibidos; use ambientes sintéticos.

Os ensaios de Lena na ABP rodam no ambiente de bancada, com tráfego sintético, nunca durante uma janela de produção. Apagar a lista de permissões no monitor em operação testaria o mesmo caminho de código, mas poderia interromper as escritas de engenharia enquanto um lote rodava no R-101. A cópia de bancada do PLC-A e o tráfego reproduzido do tronco dão a evidência de temporização necessária. As verificações em produção depois de uma correção são somente de leitura, como confirmar que a versão implantada é a que foi testada na bancada.

Nota prática

Comemore os tickets registrados — eles são o produto. Um ensaio com zero tickets geralmente pulou as injeções difíceis.

47.1b Correção sem culpa e recorrência

Os tickets corretivos nomeiam o monitor, o conduto ou o runbook com defeito, não o operador que seguiu um procedimento ruim. Depois de uma correção, repita a injeção que encontrou a lacuna. Encerre o ticket apenas quando a medida cumprir o SLO duas vezes. Os observadores fazem rodízio, para que ninguém fique permanentemente isento. Um ticket que nomeia uma pessoa em vez de um componente volta ao autor para ser reescrito antes de ser aceito.

Os observadores anotam tempos e desvios — eles não consertam nada ao vivo. Os seus tempos são conferidos contra os logs antes que o placar seja fotografado. As fotos do placar vão para o dossiê.

Nota de campo — o mau sinal dos zero tickets

Um ensaio que produziu zero tickets tinha pulado a injeção do grafo plano. Repeti-lo com a injeção difícil gerou três tickets e apertou a barreira de alcançabilidade do SIS. A injeção do grafo plano agora é obrigatória em todo ensaio.

Cada ticket corretivo se liga ao script da injeção e ao valor medido que o disparou.

Os observadores em rodízio recebem as instruções sobre as medidas antes do ensaio, não durante ele.

47.5 Exemplo resolvido — ensaio de recuperação na bancada (ABP sintética)

O cenário do ensaio: a lógica do PLC-A é corrompida (simulada carregando um programa errado no controlador de bancada) durante um lote. Medidas: tempo até detectar (alerta de mudança de programa, 35 s), tempo até decidir (o líder de turno escolhe a parada segura, 4 min), tempo até restaurar a lógica verificada a partir do backup offline (22 min) e tempo até retomar (41 min no total). O ensaio revela que o hash do backup nunca tinha sido registrado, então a verificação dependeu de uma comparação manual. As ações corretivas recebem donos e datas: registrar os hashes dos backups, acrescentar um exercício de restauração ao calendário trimestral e acompanhar a recorrência.

Exercícios

Síntese

Quebre de propósito; meça; abra tickets para as lacunas.

Respostas comentadas

EX139. Injeção: apagar o arquivo da lista de permissões. Esperado: DENY das escritas em até 30 s, alerta, nenhum ALLOW.

EX140. Segundos desde a injeção até a primeira decisão de negar todas as escritas (e o disparo do alerta).

EX141. Apertar a consulta da política do otmon de 15 s para 5 s — o "negar tudo" do ensaio levou 45 s > SLO de 30 s.