A maioria das intrusões bem-sucedidas em servidores não passa por exploits engenhosos mas por uma vulnerabilidade cuja correção saiu há meses. A razão não costuma ser preguiça: atualizar à mão num servidor em produção mete medo, porque o apt upgrade por vezes reinicia o que ninguém lhe pediu. As atualizações automáticas resolvem a questão, mas têm má fama, merecida exatamente na medida em que são configuradas à pressa.
Vejamos uma configuração em que as correções de segurança chegam sozinhas e a versão do PHP não muda de noite.
Instalação
sudo apt install unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades
O diálogo cria o /etc/apt/apt.conf.d/20auto-upgrades. Verifique o que saiu dali:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Os uns significam «diariamente». Tudo isso é lançado por um temporizador do systemd, não pelo cron clássico:
systemctl list-timers | grep apt
O essencial: só segurança
O ficheiro principal é o /etc/apt/apt.conf.d/50unattended-upgrades. Contém uma lista Allowed-Origins (no Debian, Origins-Pattern), e por omissão está lá ativo apenas o repositório de segurança. Deixe assim.
A tentação de descomentar a linha com -updates — «que se atualize tudo» — é forte. Não o faça: o repositório de atualizações traz versões novas e não apenas correções, e é precisamente de lá que vêm as surpresas noturnas. Segurança e novidade são tarefas diferentes, e a segunda faz-se melhor à mão, consigo ao teclado.
Se algum pacote não deve ser atualizado automaticamente, existe uma lista negra:
Unattended-Upgrade::Package-Blacklist {
"mariadb-server";
"php8.3-fpm";
};
Use-a com consciência: cada linha ali significa «este pacote atualizo-o eu», e essa promessa terá de ser cumprida.
Os reinícios
A linha central:
Unattended-Upgrade::Automatic-Reboot "false";
Deixar false é o correto para um servidor com um sítio: um reinício sem aviso às três da manhã é pior do que uma correção adiada um dia. Mas essa decisão tem uma segunda metade obrigatória, e é essa que se esquece.
Quando são atualizados o núcleo, a libc ou o openssl, o sistema cria o ficheiro /var/run/reboot-required. Enquanto não houver reinício, a versão corrigida está no disco enquanto a antiga corre em memória: a vulnerabilidade, portanto, não desapareceu, embora o pacote conste como atualizado. Verifique-o de forma explícita:
ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs
O segundo ficheiro enumera o que tornou o reinício necessário. A regra é simples: assim que vir o indicador, marque uma janela nos próximos um ou dois dias, e não «um dia destes».
As bibliotecas são caso à parte. O openssl é atualizado enquanto o nginx e o PHP-FPM continuam a correr com a versão antiga em memória, e não aparece indicador de reinício nenhum. Quem precisa de ser reiniciado mostra-o o needrestart:
sudo apt install needrestart
sudo needrestart -b
Ponha-o apenas no modo «mostrar, não perguntar»: caso contrário começará a fazer perguntas a meio de uma instalação não interativa e deixá-la-á pendurada. Para isso, coloque em /etc/needrestart/conf.d/ um ficheiro com a linha $nrconf{restart} = 'l';.
Verificar que funciona
Uma passagem de teste sem instalar:
sudo unattended-upgrade --dry-run --debug
A saída mostra que pacotes se enquadram nas regras e quais foram descartados e porquê. O que aconteceu realmente está nos registos:
sudo tail -50 /var/log/unattended-upgrades/unattended-upgrades.log
Quantas atualizações estão à espera neste momento:
apt list --upgradable 2>/dev/null | grep -i security
Este último comando é o mais útil de todos. Atualizações automáticas configuradas têm o hábito de se partir em silêncio: acabou o espaço em /boot, um repositório mudou de chave, o temporizador ficou desativado depois de alguma alteração manual. Por fora está tudo bem, e as correções não são instaladas há meses.
O espaço em /boot
Um clássico: os núcleos antigos não são removidos, a partição /boot enche, a instalação de um núcleo novo falha e as atualizações param em bloco. De poucos em poucos meses vale a pena espreitar:
df -h /boot
sudo apt autoremove --purge
Ou ative a limpeza automática nesse mesmo 50unattended-upgrades: Remove-Unused-Kernel-Packages "true" e Remove-Unused-Dependencies "true".
O que fica para a pessoa
As atualizações automáticas tiram a rotina, não a vigilância. Duas perguntas a que deveria saber responder a qualquer momento: quantas atualizações de segurança estão à espera e se o indicador de reinício está levantado. Ambas as respostas são uma linha numa página, e todo o sentido está em que essa linha lhe salte à vista por si só, e não por sua iniciativa uma vez por trimestre.