A primeira execução do Lynis num VPS acabado de criar costuma dar qualquer coisa à volta de 60 e uma longa lista de sugestões em que não se sabe por onde começar. A boa notícia: 80 a 85 é o trabalho de uma noite, e a maior parte dos passos não é cosmética mas realmente útil. A má: os últimos quinze pontos são inalcançáveis numa máquina virtual alugada, e persegui-los é um erro.
O que o índice mostra e o que não mostra
O índice de robustez é a proporção ponderada entre testes passados e total, não uma percentagem de segurança. O Lynis executa cerca de trezentos testes e produz duas listas distintas: warnings, que parecem problemas reais, e suggestions, ou seja, o que poderia ser melhorado. Comece sempre pelos avisos; costumam ser poucos.
Cem pontos não existem: algumas recomendações pressupõem decisões tomadas na instalação do sistema (partições separadas para /home, /tmp e /var), outras exigem acesso ao carregador de arranque que um VPS não tem, e outras contradizem-se. E comparar o seu índice com o alheio não serve de nada: o Lynis retira pontos por aquilo que corre na máquina. Cada serviço ativo é mais uma porta aberta, uma configuração própria e uma dúzia de novas sugestões, e por isso os valores altos aparecem sobretudo onde não corre nada além do SSH. Para um servidor de trabalho com sítio, base de dados e correio, 85 é um bom resultado.
Executar como root
sudo lynis audit system
Sem sudo o Lynis salta todos os testes que precisam de ficheiros do sistema e comunica um índice mais baixo, não porque o servidor seja mau mas porque as verificações não foram vistas. O relatório fica em /var/log/lynis-report.dat, o registo legível em /var/log/lynis.log.
Cada linha da saída começa por um identificador de teste como SSH-7408 ou KRNL-6000. É por esse identificador que se encontra tanto a explicação como a forma de desativar um teste: guarde a sua forma, tudo o resto gira à volta dela.
O que mexe mesmo no número
SSH (SSH-7408). O bloco de maior peso: um único teste verifica uma dúzia de parâmetros de uma vez. Não altere todo o sshd_config, deixe um ficheiro à parte para que uma atualização do pacote não apague o seu trabalho:
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
MaxSessions 2
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
LogLevel VERBOSE
TCPKeepAlive no
EOF
sudo sshd -t && sudo systemctl reload ssh
sshd -t antes de recarregar o serviço é obrigatório: um erro na configuração com a sessão aberta deixa-o de fora. E antes de pôr PasswordAuthentication no, garanta que a chave funciona mesmo, a partir de um segundo terminal aberto.
Parâmetros do núcleo (KRNL-6000). O teste verifica cerca de duas dezenas de valores sysctl. Um ficheiro para eles:
sudo tee /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.log_martians = 1
EOF
sudo sysctl --system
Ferramentas em falta. Boa parte das sugestões resume-se a «instale o que não está lá»: auditd (registo de eventos do sistema), aide (integridade de ficheiros), debsums (integridade de pacotes), unattended-upgrades (atualizações de segurança automáticas), sysstat e acct (contabilidade de processos), um antivírus. Cada um fecha uma ou duas recomendações, mas instale-os não pelos pontos: sem eles não reconstruirá nada depois de um incidente.
Pormenores com boa relação esforço/resultado. umask 027 em /etc/login.defs; a validade das palavras-passe no mesmo ficheiro; os avisos /etc/issue e /etc/issue.net; os compiladores legíveis apenas pelo root (chmod 700 /usr/bin/gcc). Sobre os avisos, com franqueza: à segurança não acrescentam nada, são uma formalidade jurídica, mas dão um ponto.
Uma armadilha no login.defs
Alterar o umask por substituição de linha com sed deixa muitas vezes várias linhas UMASK no ficheiro. O Lynis então não conta o valor, e o teste AUTH-9328 fica a vermelho embora a definição pareça feita. Verifique depois de editar:
grep -c '^UMASK' /etc/login.defs
Tem de haver exatamente uma. O mesmo vale para qualquer outro parâmetro desse ficheiro.
Falsos positivos e como silenciá-los como deve ser
Alguns avisos não dizem respeito ao seu servidor. Um exemplo real: no VPS de um grande alojamento o teste PKGS-7388 indica que não foi encontrado repositório de segurança, simplesmente porque os repositórios estão descritos em formato deb822 com referência a um ficheiro de espelhos, enquanto o Lynis procura a linha habitual. As atualizações de segurança, no entanto, chegam perfeitamente.
Isso silencia-se não apagando linhas do relatório mas com um perfil. Os ficheiros de perfil têm extensão .prf (não .prof: aí perde-se meia hora com facilidade), e as suas regras vão para /etc/lynis/custom.prf:
skip-test=PKGS-7388
skip-test=KRNL-5788
Uma regra: ao lado de cada linha tem de haver um comentário sobre a razão de o teste ser saltado. Daqui a meio ano não se lembrará se foi desativado por não se aplicar ou por dar trabalho corrigi-lo, e a diferença entre esses dois casos é a questão toda.
O que não fazer
Não persiga o número. O índice inflaciona-se com facilidade desativando os testes incómodos, e acima de certo nível esse é o único caminho, só que o servidor não fica mais seguro por isso. Outra coisa é útil: fixar o seu próprio valor e vigiar as suas variações. Um índice que cai depois de uma atualização ou de uma alteração de configuração feita por outra pessoa é um sinal muito mais valioso do que a sua grandeza absoluta.
É precisamente por isso que vale a pena correr o Lynis de forma agendada e não uma única vez, guardando os relatórios para ter com que comparar. Como isso fica reunido numa página mostra-o a demonstração abaixo: o índice, a lista de avisos com os respetivos identificadores de teste e o que mudou desde a execução anterior.