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

Hardening de Linux Servidor: CIS Benchmark Aplicado sem Quebrar Producao

Compartilhar

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 Aplicad
Neste artigo

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.

Compartilhar

Compartilhar

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