# O que o coletor LayerOps faz

Este documento explica, de forma completa e honesta, o que o agente coletor
do LayerOps faz quando instalado num servidor — o que ele lê, o que ele
envia, como ele se comunica, quais são os riscos reais e o que ele precisa
pra funcionar. Foi escrito pra ser repassado a um cliente ou a uma área de
segurança/infraestrutura que peça esclarecimento antes de autorizar a
instalação.

## Resumo em uma frase

O coletor é um script que roda periodicamente, lê informações de capacidade
e inventário do servidor (nunca o conteúdo de arquivos ou dados de
aplicação), e envia essas informações, assinadas digitalmente, para o painel
do LayerOps — nada além disso.

## O que ele coleta

> **Versões cobertas por este documento:** Hyper-V **0.6.6** · Linux **0.4.8** ·
> FreeBSD/OPNsense **0.4.8**. A lista abaixo é a relação completa do que cada
> versão envia — se um campo não está aqui, o coletor não envia.

### Em todos os coletores (Windows, Linux, FreeBSD)

| Dado enviado | De onde vem |
|---|---|
| Nome do servidor (hostname) | nome do sistema |
| Quantidade de processadores lógicos | Windows: `Get-VMHost` (LogicalProcessorCount) · Linux: `nproc` · FreeBSD: `sysctl hw.ncpu` |
| Memória total (GB) | Windows: `Get-VMHost` (MemoryCapacity) · Linux: `/proc/meminfo` · FreeBSD: `sysctl hw.physmem` |
| Disco total (GB) | Windows: soma dos volumes fixos (`Get-Volume`) · Linux: `lsblk` · FreeBSD: `geom disk list` |
| Quantidade de discos físicos | Windows: `Get-Disk` · Linux: `lsblk` · FreeBSD: `geom disk list` |
| Tempo ligado (uptime) | relógio de boot do SO |
| Versão do kernel | Windows: `Win32_OperatingSystem` · Linux/FreeBSD: `uname -r` |
| Sistema operacional (descrição, distribuição e versão) | Windows: `Win32_OperatingSystem` · Linux: `/etc/os-release` · FreeBSD/OPNsense: `uname` / `opnsense-version` |
| Endereços IPv4 (exceto 127.0.0.1) | Windows: `Get-NetIPAddress` · Linux: `ip addr` · FreeBSD: `ifconfig` |
| Versão do próprio coletor | fixa no script |
| Código de vínculo (só se configurado com `-SetLinkCode`/`--set-link-code`) | arquivo de configuração local do coletor |

### Hosts Hyper-V (coletor Windows 0.6.5)

**Máquinas virtuais** (para cada VM do host):

| Dado enviado | De onde vem |
|---|---|
| Nome da VM, vCPUs, memória atribuída (VM desligada: memória de inicialização), geração (1 ou 2) | `Get-VM` |
| Memória demandada agora (só das VMs ligadas) | `Get-VM` |
| Estado (ligada / desligada / pausada / salva) e o estado original do Hyper-V (ex.: `SavedCritical`) | `Get-VM` |
| Se a memória é dinâmica ou estática | `Get-VM` |
| Tempo ligada (uptime) — só das VMs ligadas | `Get-VM` |
| Se a VM é um recurso do Failover Cluster | `Get-ClusterResource` (só em host de cluster); se não responder, a propriedade `IsClustered` do `Get-VM` |
| Discos da VM: controlador, **nome do arquivo** do VHD/VHDX, **volume onde ele está** (ex.: `C:\ClusterStorage\Volume1`), tipo (fixo/dinâmico/diferencial), tamanho alocado e espaço ocupado de verdade (somando a cadeia de checkpoints) | `Get-VMHardDiskDrive` / `Get-VHD` |
| Checkpoints: quantidade, data do mais antigo e espaço ocupado pelos arquivos .avhdx | `Get-VMSnapshot` / `Get-VHD` |
| Integration Services: estado e versão (só das VMs que **não** estão "Up to date") | `Get-VM` |
| Hyper-V Replica (se configurado): estado, saúde, modo e horário da última replicação | `Get-VMReplication` |

**Armazenamento:**

| Dado enviado | De onde vem |
|---|---|
| Volumes onde ficam os discos das VMs: **caminho** (ex.: `C:\ClusterStorage\Volume1`, `D:`), nome, se é compartilhado, tamanho total, espaço livre, quanto as VMs deste host alocam e ocupam ali | `Get-ClusterSharedVolume` (CSV) / informações do volume do Windows. Se a lista de CSVs não responder, disco em `C:\ClusterStorage\<volume>` vai para esse volume sem tamanho/livre |
| Estado de cada CSV visto por este nó (acesso direto ou redirecionado, e o motivo) | `Get-ClusterSharedVolumeState` |
| Discos físicos: nome do modelo, **identificador único e número de série** (pra reconhecer o mesmo disco visto por mais de um nó do cluster), tipo de mídia e barramento, tamanho, saúde, estado operacional | `Get-PhysicalDisk` |
| Desgaste (%), temperatura e erros de leitura/escrita não corrigidos (quando o disco expõe) | `Get-StorageReliabilityCounter` |
| Storage Spaces / S2D (se existir): pools e discos virtuais com saúde, estado, tamanho e resiliência; quantidade de reparos em andamento | `Get-StoragePool` / `Get-VirtualDisk` / `Get-StorageJob` |
| MPIO (se instalado): quantidade de caminhos por LUN | WMI `MPIO_DISK_INFO` |

**Failover Cluster** (só se o host for membro de um cluster):

| Dado enviado | De onde vem |
|---|---|
| Nome do cluster | `Get-Cluster`; se não responder, o registro do Windows (`HKLM:\Cluster`, valor `ClusterName`) |
| Nós e estado de cada um (Up/Down/Paused) | `Get-ClusterNode` |
| Tipo de quórum, testemunha e estado da testemunha | `Get-ClusterQuorum` |
| Redes do cluster: nome, função e estado | `Get-ClusterNetwork` |
| Recursos fora do ar (nome, tipo, estado, grupo, nó) — VM desligada não entra | `Get-ClusterResource` |
| Regras de anti-afinidade: grupo, nó atual e classes | `Get-ClusterGroup` |

**Desempenho** (10 amostras de 1 segundo a cada execução — média, pico e mínimo):

| Dado enviado | Contador do Windows (`Get-Counter`) |
|---|---|
| Uso real de CPU pelo hypervisor (todas as VMs somadas) | `Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time` |
| Memória livre do host | `Memory\Available MBytes` |
| Pressão de memória dinâmica | `Hyper-V Dynamic Memory Balancer\Average Pressure` |
| Latência de leitura/escrita e IOPS de disco | `PhysicalDisk(_Total)\Avg. Disk sec/Read`, `Avg. Disk sec/Write`, `Disk Transfers/sec` |
| Latência e IOPS de cada CSV | `Cluster CSV File System(*)\Read Latency`, `Write Latency`, `Reads/sec`, `Writes/sec` |

**Eventos do Windows** (trechos de até 500 caracteres da mensagem):

| Dado enviado | De onde vem |
|---|---|
| Eventos dos últimos ~20 min dos logs administrativos do Hyper-V — usados só para explicar mudanças de estado/host de uma VM | `Microsoft-Windows-Hyper-V-Worker-Admin`, `Microsoft-Windows-Hyper-V-VMMS-Admin` |
| Eventos críticos dos últimos ~35 min: recurso do cluster falhou (1069), nó removido (1135), falhas do serviço de cluster/quórum (1146, 1177, 1205, 1254), CSV pausado/inacessível (5120, 5142), live migration falhou (21502) | Log `System` (FailoverClustering) e `Microsoft-Windows-Hyper-V-High-Availability-Admin` |

### Hosts Linux com KVM/libvirt (coletor Linux 0.4.8)

| Dado enviado | De onde vem |
|---|---|
| Nome da VM, vCPUs, memória, disco total | `virsh dominfo` / `virsh domblkinfo` |
| Estado (ligada / desligada / pausada) | `virsh domstate` |
| Discos da VM: dispositivo, **caminho do arquivo**, tamanho | `virsh domblklist` / `virsh domblkinfo` |

Linux sem libvirt e FreeBSD/OPNsense enviam só os dados da seção "Em todos
os coletores" — a própria máquina se reportando, sem VMs.

**O que ele NUNCA lê ou envia:** conteúdo de arquivos (inclusive de dentro
dos discos das VMs), dados de bancos de dados, senhas ou credenciais de
outros sistemas, tráfego de rede, logs de aplicação, lista de usuários ou
processos, ou qualquer informação fora das tabelas acima. Nomes de VMs, de
arquivos de disco, de volumes, de nós e de recursos do cluster são enviados
porque identificam o que está sendo medido.

## Como ele coleta

- Para coletar, usa exclusivamente comandos de **leitura** (`Get-*` no
  PowerShell, `virsh list`/`dominfo`, `lsblk`, `sysctl`, `geom disk list`,
  etc.). Ele nunca cria, altera, liga, desliga ou apaga nada nas VMs, no
  cluster ou no armazenamento.
- As únicas escritas que ele faz são nos **próprios arquivos e no próprio
  agendamento**: grava log e fila de reenvio na sua pasta de dados, ajusta
  o intervalo da sua tarefa agendada/timer quando uma versão nova muda o
  padrão, e troca o próprio script ao ser atualizado.
- Roda como uma tarefa agendada (Tarefa Agendada do Windows, rodando como
  `SYSTEM`) ou um cron job (rodando como `root`) — precisa desse nível de
  privilégio porque é o único jeito de ler certas informações de hardware e
  do hypervisor, não porque precisa alterar algo.
- Frequência padrão: a cada 30 minutos (configurável na instalação).
  Capacidade só vira registro novo no painel quando algo mudou desde a
  última coleta; desempenho (Hyper-V) é registrado a cada execução.
- Cada execução no Hyper-V leva cerca de 10 segundos a mais por causa das
  amostras de desempenho.

## Como ele se comunica

- **Só conexões de saída** (outbound), sempre HTTPS, sempre iniciadas pelo
  coletor — ele nunca abre uma porta de entrada nem escuta nada na rede.
  Não precisa de nenhuma regra de firewall inbound.
- Cada instalação recebe uma credencial própria (um `agentId` + um segredo
  aleatório de 32 bytes), gerada uma única vez durante a instalação e nunca
  reaproveitada entre clientes ou servidores.
- **O segredo em si nunca trafega pela rede.** Cada envio é assinado com
  HMAC-SHA256 usando o segredo local; o servidor recalcula a assinatura e
  compara — se não bater, a requisição é rejeitada.
- Proteção contra reenvio (replay): cada requisição carrega um identificador
  único (nonce) que só pode ser usado uma vez, e um timestamp que precisa
  estar a no máximo 5 minutos do horário do servidor.
- Se a rede cair ou o servidor de destino ficar indisponível, o envio fica
  numa fila local em disco e é reenviado nas próximas execuções, sem perder
  nem duplicar dado.

## Como rodar manualmente, ver o log, atualizar e desinstalar

### Rodar manualmente

Windows/Hyper-V:

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Program Files\LayerOps\LayerOpsCollector.ps1"
```

Linux:

```bash
sudo /opt/layerops/layerops-collector.sh
```

FreeBSD/OPNsense:

```sh
/usr/local/layerops/layerops-collector.sh
```

### Ver o log

Windows:

```powershell
Get-Content "$env:ProgramData\LayerOps\collector.log" -Tail 50
```

Linux:

```bash
sudo tail -n 50 /var/lib/layerops/collector.log
```

FreeBSD/OPNsense:

```sh
tail -n 50 /var/db/layerops/collector.log
```

### Atualizar

Windows:

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Program Files\LayerOps\LayerOpsCollector.ps1" -Update
```

Linux:

```bash
sudo /opt/layerops/layerops-collector.sh --update
```

FreeBSD/OPNsense:

```sh
/usr/local/layerops/layerops-collector.sh --update
```

Em todos os casos, a atualização baixa a versão atual do script, troca o
arquivo local e dispara a primeira coleta imediatamente.

### Desinstalar

Windows:

```powershell
Unregister-ScheduledTask -TaskName "LayerOps Collector" -Confirm:$false
Remove-Item "$env:ProgramFiles\LayerOps" -Recurse -Force
Remove-Item "$env:ProgramData\LayerOps" -Recurse -Force
```

Linux:

```bash
systemctl disable --now layerops-collector.timer 2>/dev/null
rm -f /etc/systemd/system/layerops-collector.{service,timer}
rm -f /etc/cron.d/layerops-collector
systemctl daemon-reload 2>/dev/null
rm -rf /opt/layerops /etc/layerops /var/lib/layerops
```

FreeBSD/OPNsense:

```sh
crontab -l | grep -v '# layerops-collector' | crontab -
rm -rf /usr/local/layerops /usr/local/etc/layerops /var/db/layerops
```

Depois disso, revogue o agente no painel do LayerOps para que a credencial
não continue validando.

## Onde os dados ficam

Os dados coletados vão para o banco de dados do LayerOps (Postgres,
hospedado na infraestrutura do LayerOps), isolados por cliente através de
controle de acesso em nível de linha (Row Level Security) — um cliente
nunca consegue enxergar dados de outro, nem por bug de aplicação, porque o
isolamento é garantido na camada mais baixa do banco.

## Riscos — de forma honesta

- **O segredo da credencial fica salvo em texto simples no disco local**
  (`config.json`), protegido pelas permissões do próprio sistema
  operacional (no Windows, a pasta só é acessível por administradores/
  `SYSTEM`; no Linux/FreeBSD, o arquivo é `chmod 600` e o diretório
  `chmod 700`, só root). Quem tiver acesso de administrador/root àquele
  servidor específico consegue ler esse segredo — mas mesmo de posse dele,
  só consegue enviar dados de capacidade em nome daquele agente específico
  (não dá acesso a nenhum outro sistema, nem lê nada de volta).
- **O agente roda com privilégio alto** (`SYSTEM`/`root`) porque precisa
  desse nível pra ler informações de hardware/hypervisor — mas o script em
  si só executa comandos de leitura (auditável: o código é aberto e pode
  ser revisado antes de instalar).
- **Se a credencial vazar**, alguém poderia enviar dados falsos em nome
  daquele servidor (poluindo o histórico de capacidade dele) — não dá
  acesso a executar comandos, ler arquivos, nem a nenhum outro servidor.
  A credencial pode ser revogada a qualquer momento pelo painel do
  LayerOps, sem precisar de acesso ao servidor.
- **Atualizações do coletor** só acontecem por comando explícito rodado no
  próprio servidor, ou — se um administrador do LayerOps ligar essa opção
  especificamente pra aquele servidor — automaticamente no próximo
  check-in; em ambos os casos, o coletor baixa a versão atual do script
  (sempre da mesma URL oficial do LayerOps) e substitui o arquivo local.

## O que ele precisa pra funcionar

- **Rede:** acesso de saída HTTPS (porta 443) para
  `layerops.moreapps.com.br`. Nenhuma porta de entrada.
- **Windows/Hyper-V:** PowerShell 5.1+ e o módulo `Hyper-V` já presente no
  host; se o host for membro de um Failover Cluster, o módulo
  `FailoverClusters` (já vem quando o cluster está configurado). Os dados
  de Storage Spaces/S2D, MPIO e Hyper-V Replica só aparecem quando esses
  recursos existem no host — sem eles, o coletor segue normalmente.
- **Linux:** `bash`, `curl`, `openssl`; opcionalmente `virsh` (pacote
  `libvirt-clients`) se o host tiver KVM.
- **FreeBSD/OPNsense:** `sh` (já vem no sistema base), `curl`, `openssl`.
- Um código de instalação gerado no painel do LayerOps (`/app/agents`). Por
  padrão ele expira e tem número limitado de usos; o administrador pode
  gerar um código sem expiração/usos ilimitados para automações (ex.:
  imagem de VM), e revogá-lo quando quiser.

## Desinstalação

Remover a tarefa agendada (Windows) ou a entrada de cron/timer
(Linux/FreeBSD), apagar a pasta de instalação e revogar o agente no painel
do LayerOps (ou pedir pro administrador do cliente que use o LayerOps fazer
isso) — nenhum resquício continua rodando ou reportando depois disso.

---

> **Manutenção deste documento:** toda alteração no que um coletor coleta
> (campo novo, campo removido, comando novo, mudança de frequência ou de
> comportamento) precisa atualizar este documento **no mesmo commit**,
> junto com a versão do coletor no topo da seção "O que ele coleta".
> Este texto é o que se entrega ao cliente para aprovar a instalação — ele
> não pode ficar desatualizado em relação ao script.
