Por que o unattended-upgrades não funciona no Debian
O Debian instala o unattended-upgrades desativado. Ative-o, confira o Origins-Pattern, valide os timers apt-daily e confirme que as atualizações automáticas foram aplicadas.
Por que unattended-upgrades não faz nada em uma nova instalação do Debian
No Debian, o unattended-upgrades pode estar instalado e ainda assim nunca executar uma única atualização, porque instalar o pacote e ativá-lo são duas etapas diferentes. O pacote faz uma pergunta do debconf antes de se configurar, e o instalador do Debian armazena a resposta false para essa pergunta. O Ubuntu responde à mesma pergunta de outra forma. Por isso, o mesmo pacote parece funcionar lá e parece estar quebrado aqui.
Nada no sistema indica esse problema. Não há erro durante o boot, aviso no login nem ficheiro de log para consultar, porque o código que escreveria esse log nunca é chamado. Ativá-lo requer um comando. O restante deste guia aborda os quatro fatores que ainda podem impedi-lo de funcionar: de quais repositórios ele pode instalar atualizações, quando os timers do systemd são realmente executados, como verificar se uma execução falhou e se a máquina está autorizada a reiniciar sozinha.
Veja o que o sistema considera antes de alterar qualquer coisa
dpkg -l unattended-upgrades | tail -n 1
sudo apt install -y debconf-utils
sudo debconf-show unattended-upgrades
cat /etc/apt/apt.conf.d/20auto-upgrades
apt-config dump APT::Periodicdebconf-show mostra o valor guardado para unattended-upgrades/enable_auto_updates. Um * no início dessa linha indica que algo definiu o valor, em vez de o deixar no valor predefinido do pacote. Numa máquina instalada pelo instalador do Debian, esse algo é o instalador.
cat pode mostrar cat: /etc/apt/apt.conf.d/20auto-upgrades: No such file or directory. Isso, por si só, explica a ausência de atividade: sem esse ficheiro, não existem chaves periódicas e nada é agendado.
apt-config dump é o comando relevante. O APT lê todos os ficheiros em /etc/apt/apt.conf.d/ pela ordem dos nomes e combina-os. Por isso, um valor simples definido em 99local substitui o mesmo valor em 20auto-upgrades. Ler um ficheiro mostra o que está definido nesse ficheiro. apt-config dump mostra o que o APT irá efetivamente fazer.
Duas chaves determinam se alguma coisa acontece:
APT::Periodic::Update-Package-Listsatualiza as listas de pacotes. Essa é a tarefa queapt updateexecuta manualmente.APT::Periodic::Unattended-Upgradeexecuta a atualização propriamente dita.
Os valores não são verdadeiro e falso. São intervalos em dias. "1" significa "executar se isto não tiver sido feito no último dia", "7" significa semanalmente e "0" significa nunca. APT::Periodic::Unattended-Upgrade "0"; é uma configuração válida que não executa nada, indefinidamente, sem apresentar qualquer aviso. Se o resultado mostrar 0 para essa chave, ou não mostrar essa chave, encontrou a causa.
Ativar: dpkg-reconfigure ou escrever as chaves manualmente
sudo apt update
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades--priority=low não é opcional neste caso. A pergunta tem prioridade baixa, por isso, com a prioridade predefinida, dpkg-reconfigure não mostra nada, não altera nada e termina com o código 0. Isto parece exatamente o comportamento de um comando que funcionou. Responda afirmativamente à caixa de diálogo. Depois, o postinst do pacote escreve /etc/apt/apt.conf.d/20auto-upgrades com base na sua resposta.
Numa máquina criada a partir de um script, não há nenhuma caixa de diálogo para responder. Defina primeiro a resposta:
echo 'unattended-upgrades unattended-upgrades/enable_auto_updates boolean true' \
| sudo debconf-set-selections
sudo dpkg-reconfigure -f noninteractive unattended-upgrades
apt-config dump APT::PeriodicTambém pode escrever as duas chaves diretamente:
printf 'APT::Periodic::Update-Package-Lists "1";\nAPT::Periodic::Unattended-Upgrade "1";\n' \
| sudo tee /etc/apt/apt.conf.d/20auto-upgrades
apt-config dump APT::PeriodicIsto produz efeito imediatamente, mas deixa uma armadilha. A resposta do debconf continua a indicar o valor antigo. Por isso, o próximo dpkg-reconfigure ou uma reinstalação do pacote volta a escrever o ficheiro com base no debconf e desfaz a sua alteração sem apresentar qualquer saída. Defina as duas opções ou configure o debconf e deixe o postinst gerir o ficheiro.
Esta é a única diferença real em relação ao outro lado da família. Nesse caso, o instalador ativa o mesmo pacote por si, por isso a configuração do unattended-upgrades no Ubuntu começa num sistema que já aplica atualizações automaticamente e concentra-se no ajuste da configuração. Tudo o que se segue aplica-se a ambos.
Que atualizações o Debian instala efetivamente?
Ativar o temporizador não é o mesmo que concordar em instalar tudo. Cada fonte de pacotes contém metadados da versão: uma origem, um rótulo, uma suite, um codename e um site. O unattended-upgrades analisa a versão candidata de cada pacote que pode ser atualizado, lê os metadados da fonte de onde essa versão viria e instala-a apenas se essa fonte corresponder a uma entrada em Unattended-Upgrade::Origins-Pattern. Sem correspondência, não há atualização. Isso é intencional.
Imprima os seus padrões e, em seguida, os metadados aos quais eles são comparados:
apt-config dump Unattended-Upgrade::Origins-Pattern
grep -H -E '^(Origin|Label|Suite|Codename|Components):' /var/lib/apt/lists/*Release
apt-cache policygrep -H mantém o nome do ficheiro em cada linha, para mostrar a que fonte pertence cada bloco de metadados. Os valores desses campos são os lados direitos dos seus padrões. ${distro_codename} dentro de um padrão é substituído em tempo de execução pelo codename da versão que está a utilizar, para que um único ficheiro continue a funcionar depois de uma atualização da versão.
Leia os seus próprios padrões com esses metadados ao lado. A resposta à pergunta "estou a receber apenas correções de segurança ou também atualizações da point release" está aí, e em nenhum outro lugar:
- Um padrão que indique
label=Debian-Securitycorresponde ao arquivo de segurança. É aí que são publicadas as advisories de segurança do Debian. - Um padrão que indique a suite
-updatescorresponde a stable-updates, que contém o que o Debian publica entre point releases, como dados de fusos horários. - Um padrão que indique a suite simples da versão inclui as alterações da point release assim que são publicadas. Isso gera mais alterações e exige mais testes da sua parte.
- Um repositório que adicionou manualmente não corresponde a nada até escrever um padrão para ele.
Este último caso surpreende muitas pessoas. Um repositório de terceiros tem a sua própria origem e o seu próprio rótulo. Por isso, o unattended-upgrades vê a versão candidata, verifica que a fonte não corresponde a nada e prossegue. Adicionar um padrão para esse repositório é uma decisão que deve ser tomada com cuidado, porque um repositório de fornecedor pode publicar uma nova versão principal dentro da mesma suite. Nesse caso, terá autorizado atualizações principais automáticas desse software durante a noite.
O unattended-upgrades também nunca o move entre versões do Debian. Ele atualiza pacotes dentro da versão que está a utilizar. A passagem de uma versão stable para a seguinte continua a ser uma tarefa manual que deve agendar.
Quando alterar a lista, lembre-se de que as listas do APT são acumuladas. Um segundo bloco Origins-Pattern noutro ficheiro é adicionado à lista fornecida pelo pacote, em vez de a substituir. Se pretende substituí-la, limpe-a primeiro:
#clear Unattended-Upgrade::Origins-Pattern;
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
};Coloque as alterações locais num novo ficheiro que seja ordenado depois do ficheiro fornecido pelo pacote, por exemplo /etc/apt/apt.conf.d/52unattended-upgrades-local. 50unattended-upgrades é um conffile. Editá-lo faz com que todas as futuras atualizações do pacote parem e perguntem o que fazer com a sua versão. Um ficheiro separado nunca entra em conflito.
Vale a pena imprimir mais duas chaves enquanto está a verificar a configuração. Unattended-Upgrade::Allowed-Origins é a forma mais antiga da mesma ideia, escrita como pares origin:archive, e continua a ser lida. Por isso, uma configuração copiada de um tutorial pode acabar com as duas listas, sem uma resposta clara sobre qual delas correspondeu. Unattended-Upgrade::Package-Blacklist contém expressões regulares comparadas com os nomes dos pacotes. Uma expressão demasiado ampla bloqueia muito mais pacotes do que pretendia. A execução de teste abaixo mostra o que foi efetivamente aplicado.
Por que nada foi executado no horário esperado?
Dois timers do systemd controlam este processo, e eles têm funções diferentes. apt-daily.timer inicia apt-daily.service, que atualiza as listas de pacotes e faz os downloads. apt-daily-upgrade.timer inicia apt-daily-upgrade.service, que é o responsável por chamar unattended-upgrade. Ambos executam /usr/lib/apt/apt.systemd.daily com argumentos diferentes. Se o segundo timer estiver desativado ou mascarado, as duas chaves periódicas podem mostrar 1 e, mesmo assim, nada será instalado.
systemctl list-timers 'apt-daily*' --all
systemctl is-enabled apt-daily.timer apt-daily-upgrade.timer
systemctl cat apt-daily-upgrade.timerlist-timers mostra NEXT, LEFT, LAST e PASSED para cada unidade. Um timer sem NEXT não será executado. Se is-enabled mostrar masked, alguém o desativou de forma forçada, e nada que você escrever em apt.conf.d irá alterar isso.
Agora leia a secção [Timer] que systemctl cat mostrou. OnCalendar é o momento mais cedo em que o timer pode ser executado. RandomizedDelaySec acrescenta uma espera aleatória depois desse momento, para que um conjunto de máquinas Debian não aceda aos mesmos mirrors no mesmo segundo. Por isso, a coluna NEXT mostra um horário diferente de OnCalendar, e a execução de ontem ocorreu num minuto diferente. Esse é o comportamento esperado. Persistent=true significa que uma máquina desligada no horário agendado executa o job pouco depois do próximo boot, em vez de ignorar o dia.
Para alterar a janela, crie uma substituição da unidade em vez de editar a unidade original:
sudo systemctl edit apt-daily-upgrade.timer[Timer]
OnCalendar=
OnCalendar=03:30
RandomizedDelaySec=30mA linha OnCalendar= vazia é necessária porque as definições de unidade que aceitam listas são acumuladas: se a omitir, mantém o agendamento fornecido pelo pacote e acrescenta um segundo agendamento. systemctl edit recarrega o systemd, portanto confirme o resultado com systemctl list-timers 'apt-daily*' e consulte o novo NEXT.
Você não precisa esperar por um timer para testar nada disso:
sudo systemctl start apt-daily-upgrade.service
journalctl -u apt-daily-upgrade.service --since -1hHá um detalhe que confunde quem procura em /etc/cron.daily: o APT ainda fornece /etc/cron.daily/apt-compat para sistemas sem systemd. Leia-o com cat. Num sistema com systemd, ele termina logo no início, portanto o trabalho não é executado duas vezes.
Prove que funciona: unattended-upgrade --dry-run --debug
sudo unattended-upgrade --dry-run --debugO binário está no singular e o nome do pacote está no plural. Executar unattended-upgrades aqui produz command not found, que muitas pessoas interpretam como prova de que o pacote não está instalado.
Este comando responde a quase todas as perguntas sobre o motivo pelo qual um pacote foi ignorado, porque apresenta o próprio raciocínio. Perto do início, mostra as origens que calculou a partir dos seus padrões:
Allowed origins are: ...Depois, apresenta uma linha por cada pacote candidato, com o registo de origem da versão que instalaria:
Checking: curl ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian' site:'deb.debian.org' isTrusted:True>])Em seguida, mostra a lista sobre a qual atuaria ou, num sistema sem nada para fazer:
No packages found that can be upgraded unattended and no pending auto-removalsJunte a primeira e a segunda partes para obter um diagnóstico direto. Procure a linha Checking: correspondente ao pacote que esperava ver atualizado. Compare campo a campo o respetivo registo de origem com as origens permitidas apresentadas acima. Um campo que não corresponda, normalmente label ou archive, é o motivo completo pelo qual o pacote foi ignorado.
--dry-run marca os pacotes em memória e não instala nada, por isso pode executá-lo tantas vezes quanto quiser. Ainda assim, acrescenta informação a /var/log/unattended-upgrades/unattended-upgrades.log.
Se as origens corresponderem e um pacote continuar retido, verifique o seguinte:
apt-mark showholdlista os pacotes fixados por si ou por uma ferramenta. unattended-upgrades não altera um pacote retido.- A atualização teria de remover ou adicionar outro pacote. unattended-upgrades evita isso, exceto quando as chaves relevantes o permitem. Compare com
sudo apt-get -s upgrade, que mostra a mesma decisão sem essas regras de segurança. - O dpkg ficou parcialmente configurado depois de uma execução interrompida. Corrija o estado com
sudo dpkg --configure -ae volte a verificar. /varnão tem espaço livre, por isso nada é transferido nem desempacotado. Verifique comdf -h /var./bootestá cheio de kernels antigos, o que impede a próxima atualização do kernel. Verifiquedf -h /boote executeapt-config dump Unattended-Upgrade::Remove-Unused-Kernel-Packagespara confirmar se a limpeza está ativada.
Se executar apt manualmente enquanto o timer está em execução, verá Could not get lock /var/lib/dpkg/lock-frontend. Esta mensagem significa que unattended-upgrades está a funcionar corretamente. Aguarde até terminar.
Como descobrir quando uma execução falha?
Comece pelos logs, porque eles existem mesmo que não configure mais nada:
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades.log
sudo tail -n 40 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
journalctl -u apt-daily-upgrade.service --since -7dO primeiro ficheiro é o log de decisões: o que foi verificado, o que foi escolhido e o que foi instalado. O segundo contém a saída bruta do dpkg. É aí que aparece um pacote cujo script postinst falhou. Também é criado um log de encerramento separado se as atualizações forem executadas enquanto a máquina está a desligar.
O email é o método habitual de relatório:
Unattended-Upgrade::Mail "you@example.com";
Unattended-Upgrade::MailReport "on-change";MailReport aceita always, on-change e only-on-error. only-on-error parece ser a opção mais disciplinada e normalmente é a escolha errada num servidor em que ninguém inicia sessão, porque uma máquina que deixou completamente de fazer atualizações também deixa de enviar erros. Nesse caso, o silêncio é igual para uma máquina saudável e para uma máquina parada. on-change envia um email sempre que algo é instalado, por isso o email também confirma que o temporizador continua ativo.
O email só sai da máquina se a máquina conseguir enviar email. unattended-upgrades entrega a mensagem ao sistema de email local, por isso precisa de um MTA (mail transfer agent), como postfix, ou de um cliente de relay compatível com sendmail, como msmtp. Verifique com command -v sendmail e command -v mail. Sem nenhum dos dois, o relatório não chega a lado nenhum, a atualização continua a ser concluída e toda a falha fica invisível. Lembre-se também de que um novo endereço IP de VPS não tem reputação de envio. Por isso, o email enviado diretamente para uma caixa de correio pública é frequentemente classificado como spam. Fazer relay através de um fornecedor de email que já utiliza é mais fiável do que executar o seu próprio servidor para este fim.
Se preferir não executar qualquer serviço de email, monitorize o timestamp do log através do sistema de monitorização que utiliza:
stat -c '%y %n' /var/log/unattended-upgrades/unattended-upgrades.logUm timestamp que não mudou durante uma semana significa que o temporizador parou, independentemente do que indica a configuração. Essa verificação deve fazer parte das restantes verificações de rotina da manutenção de servidores Linux.
O sistema deve reiniciar sozinho?
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";Com Automatic-Reboot definido como true, o unattended-upgrades reinicia sem confirmação, mas apenas quando o ficheiro /var/run/reboot-required existe depois de a execução terminar. Esse marcador não é criado pelo unattended-upgrades. Outro pacote tem de o criar e, no Debian, normalmente é o needrestart. Não assuma que o ficheiro existe. Verifique depois da próxima atualização do kernel:
ls -l /var/run/reboot-required /var/run/reboot-required.pkgs
uname -r
dpkg -l 'linux-image-*' | grep '^ii'Se esse ficheiro nunca aparecer na sua máquina, o Automatic-Reboot "true" nunca é acionado. Pode passar meses a acreditar que reinicia para aplicar atualizações do kernel enquanto continua a executar o kernel antigo. Executar uname -r contra o pacote linux-image instalado mais recentemente esclarece a situação.
O Automatic-Reboot-Time agenda o reinício para essa hora, em vez de o executar imediatamente. Definir Automatic-Reboot-WithUsers como false impede o reinício enquanto houver alguém com sessão iniciada. Num servidor que tem sempre uma sessão aberta, isso significa que nunca reinicia.
A decisão diz respeito ao que acontece quando o sistema volta a arrancar, não ao reinício em si. Um serviço iniciado manualmente por alguém não volta a iniciar. Um volume encriptado que exige uma frase-passe durante o arranque não é montado. Duas máquinas que dependem uma da outra podem voltar a arrancar pela ordem errada. Ative o reinício automático num servidor Web sem estado que possa ficar indisponível durante um minuto às 02:00. Mantenha-o desativado quando for necessária a intervenção de uma pessoa e monitorize o ficheiro marcador para que alguém escolha o momento. Entre estas opções está o needrestart, que reinicia os serviços que ainda estão a utilizar uma biblioteca atualizada e, por isso, abrange tudo exceto o kernel. O modo predefinido pede confirmação antes de reiniciar. Leia o /etc/needrestart/needrestart.conf antes de o utilizar numa execução não assistida.
Isto funciona da mesma forma em testing e unstable?
Tudo o que foi descrito acima aplica-se ao Debian stable, onde as correções de segurança chegam a partir de um arquivo separado com um rótulo próprio. É essa estrutura que permite expressar uma configuração de “apenas atualizações de segurança”. As outras suites têm uma estrutura diferente. Por isso, uma configuração copiada de um servidor stable corresponde menos ao que o autor espera, e as atualizações automáticas numa suite com alterações contínuas implicam mudanças automáticas de versão principal. Isso exige uma decisão diferente. Se está a avaliar essa opção, executar Debian stable, testing ou unstable num servidor explica o que cada uma oferece. No lado da Red Hat, a mesma tarefa usa outra ferramenta e outra terminologia. dnf-automatic no Rocky Linux e no AlmaLinux executa-a com o seu próprio temporizador e ficheiro de configuração.
As atualizações automáticas reduzem o intervalo entre a publicação de uma correção e a sua instalação. Não indicam o que continua exposto. Por isso, combine-as com uma verificação de CVEs conhecidas no seu servidor. CVE significa vulnerabilidades e exposições comuns. É o identificador público usado para acompanhar uma correção.
A verificação de cinco minutos
apt-config dump APT::Periodicmostra ambas as chaves com um valor diferente de zero.systemctl list-timers 'apt-daily*'mostra um horárioNEXTpara ambos os temporizadores.sudo unattended-upgrade --dry-run --debugmostra origens permitidas que incluem o arquivo de segurança correspondente ao seu codinome.sudo systemctl start apt-daily-upgrade.servicetermina, e o timestamp de/var/log/unattended-upgrades/unattended-upgrades.logé atualizado.- Uma semana depois, esse mesmo log lista os pacotes que instalou.
Passar nas quatro primeiras verificações significa que a máquina está configurada. Passar na quinta significa que funciona.
FAQ
Por que o Debian instala o unattended-upgrades, mas deixa-o desativado?
O pacote faz uma pergunta ao debconf, unattended-upgrades/enable_auto_updates, e escreve /etc/apt/apt.conf.d/20auto-upgrades com base na resposta. O instalador do Debian armazena false para essa pergunta. Por isso, quando o pacote chega como parte de uma tarefa ou como dependência, fica configurado para não fazer nada. Execute sudo debconf-show unattended-upgrades para ver a resposta armazenada e depois sudo dpkg-reconfigure --priority=low unattended-upgrades para alterá-la. A prioridade baixa é importante, porque, com a prioridade predefinida, o comando termina sem mostrar a pergunta.
Como testar o unattended-upgrades sem esperar pelo temporizador?
Execute sudo unattended-upgrade --dry-run --debug. O comando mostra as origens que serão aceites e uma linha Checking: por pacote que pode ser atualizado, com o registo de origem desse pacote associado. Também mostra a lista de pacotes que instalaria, sem instalar nada. Para testar o fluxo real, execute sudo systemctl start apt-daily-upgrade.service e depois consulte journalctl -u apt-daily-upgrade.service --since -1h juntamente com /var/log/unattended-upgrades/unattended-upgrades.log.
O unattended-upgrades instala atualizações normais além das correções de segurança?
Apenas se um padrão o determinar. Uma atualização de pacote é instalada quando a origem de onde vem corresponde a uma entrada em Unattended-Upgrade::Origins-Pattern. O arquivo de segurança, a suite stable-updates e qualquer repositório adicionado por si são entradas separadas. Mostre apt-config dump Unattended-Upgrade::Origins-Pattern na sua máquina e compare-o com grep -H -E '^(Origin|Label|Suite|Codename):' /var/lib/apt/lists/*Release. O comando também nunca muda a sua versão do Debian para outra versão.
Por que a atualização não é executada no horário definido no temporizador?
apt-daily-upgrade.timer define RandomizedDelaySec além de OnCalendar. Por isso, o systemd escolhe um momento aleatório dentro dessa janela, em vez de executar no horário do calendário. Isto distribui a carga por todas as máquinas Debian que apontam para os mesmos mirrors. systemctl list-timers 'apt-daily*' mostra o momento efetivamente escolhido. Para alterar a janela, execute sudo systemctl edit apt-daily-upgrade.timer e forneça uma linha OnCalendar= vazia, seguida do seu próprio valor.
Devo ativar o reboot automático para atualizações de segurança?
Apenas quando for seguro reiniciar sem planeamento. Unattended-Upgrade::Automatic-Reboot "true" faz reboot sem confirmação sempre que /var/run/reboot-required existir depois de uma execução. Esse marcador é criado por outro pacote, normalmente needrestart, e não pelo unattended-upgrades. Confirme se o ficheiro aparece na sua máquina depois de uma atualização do kernel antes de confiar nessa configuração. Numa máquina que exige uma passphrase durante o boot ou que executa serviços iniciados manualmente por alguém, mantenha a opção como false e configure um alerta para o ficheiro marcador, para que uma pessoa escolha o momento da reinicialização.