Pular para o conteúdo
Categoria: Hardening10 min de leitura

Hardening de Linux Servidor: CIS Benchmark Aplicado sem Quebrar Producao

Por Lucas Andrade ·

Como aplicar o CIS Benchmark em Debian e Ubuntu de producao validando cada controle, medindo impacto e mantendo SLA sem virar a noite no rollback.

Hardening de Linux Servidor: CIS Benchmark Aplicado sem Quebrar Producao

Aplicar o CIS Benchmark inteiro de uma vez em um servidor Debian 12 que atende 40 mil requisicoes por minuto e a forma mais rapida de transformar uma sexta-feira em um incidente de severidade 1. A gente do time Basilisk ja viu mais de uma equipe rodar o script ansible-lockdown puro em producao e descobrir, as 3h da manha, que o controle 5.2.16 desativou o login do usuario que orquestrava o backup do Postgres. Hardening serio nao e copiar 380 controles do PDF: e escolher os 60 que valem o risco, testar em staging com a mesma carga, e ter telemetria pra saber em quanto tempo voce reverte se algo quebrar. Este post e o runbook que usamos em engajamentos reais.

Por que <em>tudo de uma vez</em> falha

Um PDF de CIS Benchmark lista Level 1 (conservador) e Level 2 (agressivo) separadamente, mas a maioria das equipes achata os dois em uma unica lista de tarefas e aplica em uma unica rodada de gestao de configuracao. O problema nao e nenhum controle individual, e a combinatoria: 380 mudancas simultaneas significam que quando uma regressao aparece voce nao consegue mais bisecar. Voce sabe que algo quebrou, mas nao qual das 380 linhas. E assim que voce termina as 3h da manha rodando git revert no playbook inteiro em vez de um fix cirurgico.

A segunda armadilha e a falacia da idempotencia. Muitas remediations do CIS nao sao realmente idempotentes quando o estado inicial difere do que a task assume. Uma task que reescreve /etc/pam.d/common-auth assume um stack default especifico. Se o host ja tem um modulo SSSD ou Kerberos, a linha nova cai na ordem errada e voce bloqueia todo login federado. O conserto e sempre o mesmo: batches pequenos, validacao entre cada batch, e um caminho de rollback documentado antes de escrever a primeira linha.

Os quatro buckets

O ponto de partida correto e separar os controles em quatro buckets antes de tocar em qualquer servidor. Bucket 1: kernel e boot (sysctl, GRUB, modulos), baixo risco de quebrar app, alto ganho. Bucket 2: rede e firewall (nftables, IPv6, ICMP), risco medio se voce nao mapeou todas as portas. Bucket 3: autenticacao, PAM e SSH, onde mora a maior parte dos incidentes pos-hardening. Bucket 4: auditd, syslog e integridade (AIDE), praticamente zero risco operacional.

A ordem e deliberadamente contraintuitiva: comece pelo bucket 4, depois 1, depois 2, e deixe SSH e PAM por ultimo. Voce comeca onde nada pode quebrar (auditoria), junta telemetria do comportamento normal, depois endurece o kernel, depois a rede, e so toca na camada de auth quando verificou um segundo canal de acesso (console, gestao out-of-band, uma segunda chave SSH numa porta separada). Se voce ja esta refazendo o SSH, leia Hardening de SSH 2026: Algoritmos, Certificados e Bastion Hosts antes de mexer no sshd_config porque os algoritmos mudaram em 2026.

Inventariar o estado atual com OpenSCAP

Para inventariar o estado atual, use o openscap-scanner com o profile xccdf_org.ssgproject.content_profile_cis_level2_server do projeto ComplianceAsCode. Uma invocacao real e oscap xccdf eval --profile cis_level2_server --results scan.xml --report scan.html /usr/share/xml/scap/ssg/content/ssg-ubuntu2404-ds.xml. Em um Ubuntu 24.04 limpo voce vai ver entre 110 e 140 controles em estado fail, o que e normal e nao motivo de panico.

Exporte o relatorio HTML, importe no Jira como uma epica por bucket, e estime esforco em pontos de risco e nao em horas. O segredo aqui e nunca aplicar uma remediation sem ler o rationale, porque metade das recomendacoes do CIS Level 2 quebra workloads modernos: desabilitar usb-storage faz sentido em um bastion, nao em um host que escreve dump em pendrive criptografado para air gap. Trate o scan como documento vivo: rode depois de cada batch e acompanhe o progresso como curva, nao como foto fixa.

Camada de kernel e sysctl

A camada de kernel rende um ganho enorme com pouco risco se voce souber o que esta tunando. kernel.kptr_restrict=2, kernel.dmesg_restrict=1, kernel.yama.ptrace_scope=2 e fs.protected_hardlinks=1 sao gratuitos contra vazamento local de informacao e races de symlink. Some net.ipv4.conf.all.rp_filter=1, net.ipv4.tcp_syncookies=1 e kernel.randomize_va_space=2, e coloque tudo em um /etc/sysctl.d/60-cis.conf versionado em vez do sysctl.conf principal para que um upgrade de pacote nao sobrescreva suas mudancas.

Ja kernel.unprivileged_userns_clone=0 quebra Docker rootless, Podman, Bubblewrap e qualquer sandbox de aplicacao, entao se voce roda containers ou usa as tecnicas de Sandbox de Aplicacoes no Linux com Bubblewrap, Firejail e Flatpak, deixe esse em 1 e documente o desvio formalmente. No boot, adicione GRUB com senha (CIS 1.4.x), Secure Boot com modulos assinados e blacklist de modulos de filesystem nao usados (cramfs, udf, usb-storage). Para servicos com perfil de ataque alto considere SELinux em modo enforcing com politica targeted customizada, conforme detalhamos em SELinux sem Medo: Politicas Customizadas para Servicos Criticos com exemplo completo para um Nginx exposto.

Rede e firewall com nftables

Antes de escrever uma unica regra de firewall, mapeie cada porta em escuta com ss -tulpen e reconcilie com o servico esperado. Um ruleset nftables alinhado ao CIS trabalha com default drop em input e forward mais uma allowlist explicita. O auto-bloqueio mais comum acontece quando voce esquece o trafego de loopback: sem iif lo accept, os sockets locais, os health checks e o loopback do banco colapsam, e a app cospe timeouts opacos.

IPv6 e a armadilha silenciosa. Muitas equipes endurecem o IPv4 direitinho e deixam a stack IPv6 inteira aberta, assumindo que nao esta roteada. Ou voce desabilita IPv6 de forma consistente (net.ipv6.conf.all.disable_ipv6=1 mais o bootloader) ou espelha cada regra IPv4 na familia inet do nftables. Cobertura pela metade e pior que nenhuma porque cria falsa sensacao de seguranca. Teste cada mudanca de regra com uma segunda sessao aberta como corda de seguranca.

Auditd sem a enxurrada de logs

Auditd quase sempre vira gargalo se voce copiar o ruleset do CIS sem pensar. As regras default geram entre 8 e 15 mil eventos por minuto em um host medio, enchem /var/log em 6 horas e fazem o journald comecar a descartar. A receita que usamos no Basilisk e cortar as regras de execve por usuarios de servico conhecidos (postgres, nginx, app) e manter monitoramento agressivo so para uid 0, sudo e shells interativas.

Configure -b 8192 para o backlog, --backlog_wait_time 0 contra stalls do kernel, e encaminhe via audisp-remote ou um plugin do auditd para um pipeline Sigma como mostramos em Threat Hunting com Sigma e Elastic: Do Indicador a Regra de Deteccao. Senao voce ta gerando ruido caro sem nenhuma deteccao acionavel do outro lado. Coloque -e 2 (regras imutaveis) so bem no final, porque trava toda mudanca de regra ate o proximo reboot.

Um ponto que passa batido: auditd e o logging completo de execve custam CPU mensuravel em servicos pesados em syscalls. Em um reverse proxy que faz dezenas de connect e openat por request, um ruleset amplo demais pode somar 5 a 10 por cento de latencia p95. Meca isso explicitamente no teste de carga de staging e trate as regras de audit como parte do orcamento de performance, nao como brinde. A metrica certa nao e o numero de regras, e eventos por segundo em operacao normal.

Validacao sob carga real

Validacao e a parte que ninguem faz direito. Suba um ambiente espelho em LXD ou Proxmox com o mesmo kernel, o mesmo glibc e a mesma versao dos servicos, e rode um perfil de carga com k6 ou wrk replicando 30 minutos de trafego real capturado via tcpdump. Aplique os controles em batches de 10, rode o teste, compare p95 de latencia e taxa de erro. Se a regressao for maior que 3% voce isolou qual controle e o culpado por bisecao.

Tambem rode atomic-red-team com tecnicas mapeadas ao MITRE ATT&CK pra confirmar que o hardening realmente reduz a superficie: a logica e a mesma de Adversary Emulation com Caldera e MITRE ATT&CK em Lab Corporativo, so que focada em pos-exploracao no host endurecido. Se uma tecnica ainda tem sucesso depois do hardening, voce tem uma lacuna mensuravel em vez de um palpite.

Cripto de disco e acesso fisico

Para servidores que tocam dados sensiveis ou que voce nao consegue acessar fisicamente, complemente o hardening com cripto de disco resiliente a coercao e backup verificado, seguindo o que discutimos em Cripto de Disco e Backups: Veracrypt, LUKS e Estrategia 3-2-1 Resiliente. LUKS2 com Argon2id, chave em TPM2 selada com PCR0+PCR7, e snapshot encriptado em storage offsite resolvem o caso de roubo fisico do datacenter.

Combinado com Secure Boot, modulos assinados e GRUB com senha (controles CIS 1.4.x), voce eleva o custo de um ataque presencial para algo que so vale a pena contra alvos muito especificos. Um aviso: uma chave selada no TPM sem passphrase de recuperacao testada e uma bomba-relogio. No dia em que um update de firmware muda os valores PCR, a maquina nao da boot, e sem passphrase guardada o disco e lixo de dados.

Checklist pratico

Antes de declarar um host endurecido como pronto: (1) score do OpenSCAP documentado antes e depois; (2) um segundo caminho de acesso (console/OOB) verificado antes de tocar no SSH; (3) todas as mudancas de sysctl versionadas em /etc/sysctl.d/; (4) nftables com iif lo accept e comportamento IPv6 testado; (5) auditd abaixo de 3000 eventos por minuto em repouso; (6) teste de carga em staging com menos de 3% de regressao p95; (7) uma rodada de atomic-red-team que comprova as tecnicas fechadas; (8) um caminho de rollback documentado e ensaiado uma vez.

FAQ: Level 1 ou Level 2?

Para servidores expostos a internet sem mandato estrito de compliance, Level 1 completo mais controles selecionados de Level 2 dos buckets 1 e 4 e o melhor ponto custo-beneficio. Level 2 completo faz sentido para workloads regulados (PCI-DSS, exigencias de governo), mas so com um registro de excecoes documentado para os controles que quebram seu workload especifico. Level 2 as cegas em um host de containers e uma queda com certificado anexado.

FAQ: com que frequencia re-escanear? A cada release maior do SO (Debian point release, LTS upgrade) e no minimo trimestralmente como scan automatico por cron cujo resultado flui para os mesmos dashboards das suas metricas. O drift e inevitavel porque upgrades de pacote resetam defaults de sysctl e servicos novos abrem portas novas.

FAQ: Ansible, script Bash ou baking de imagem? Para uma frota, uma golden image endurecida (Packer mais a lista de controles revisada, entao entregue de forma imutavel) e mais robusta que uma rodada de Ansible contra hosts vivos, porque o drift praticamente some. Ansible continua bom para o primeiro ciclo iterativo e para hosts que voce nao consegue reconstruir. Um script Bash puro sem idempotencia e a pior opcao: nao da pra repetir limpo nem reverter com confianca. O que quer que voce escolha, a lista de controles em si precisa estar versionada e revisavel, nao enterrada numa wiki de runbook.

Takeaway pratico: monte uma planilha com cada controle CIS que voce aplicou, a versao do pacote no momento, o resultado do openscap pre e pos, e o delta de latencia medido em staging. Rode essa planilha a cada release maior do SO porque sysctls mudam de default e auditd ganha campos novos. Hardening nao e projeto, e processo: se em 6 meses voce nao conseguir provar via scan automatizado que os 60 controles continuam ativos no host, voce nao tem hardening, voce tem fe.

Leituras relacionadas

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly