Atualizações automáticas como vetor de instabilidade
Voltar para blog

Atualizações automáticas como vetor de instabilidade

07/06/2026 · 3 min · Infraestrutura

Por que bloquear a atualização automática?#

Em ambientes de produção com cPanel/WHM, o comportamento padrão do servidor é atualizar-se automaticamente. O cron job do upcp roda diariamente, e o gerenciador de pacotes do SO (yum/dnf) pode ser acionado por qualquer script com privilégios root. O resultado prático em ambientes críticos:

O objetivo desta auditoria: travar completamente a autonomia de atualização do servidor, transferindo o controle exclusivamente ao administrador, sem exceções.

Camada 1 - auditando o upcp: o daemon de atualização do cPanel#

O upcp (cPanel Update CPanel) é o script que o cPanel instala em /usr/local/cpanel/scripts/upcp e registra no cron do root:

# Ver o cron do upcp instalado pelo cPanel
crontab -l | grep upcp
# 0 0 * * * /usr/local/cpanel/scripts/upcp --cron >> /var/log/cpupdate.log 2>&1

# Ver o log das últimas execuções do upcp
tail -50 /var/log/cpupdate.log

Estrutura de execução do upcp:

/etc/cpupdate.conf
    │
    ▼
  upcp --cron (root, 00:00 diário)
    │
    ├── Verifica CPANEL= → se não for 'manual', atualiza o painel
    ├── Verifica RPMUP= → se não for 'manual', atualiza RPMs do SO
    └── Verifica UPDATES= → política geral

Camada 2 - configuração do /etc/cpupdate.conf#

Este é o arquivo central de controle de atualizações do cPanel. Verificando o estado atual antes de qualquer intervenção:

cat /etc/cpupdate.conf

Estado padrão (comportamento de auto-update ativo):

CPANEL=release
RPMUP=daily
SARULESUP=daily
STAGING_DIR=/usr/local/cpanel
UPDATES=daily

Significado de cada diretiva:

DiretivaValor daily/releaseValor manual
CPANELAtualiza o cPanel/WHM automaticamente para a versão mais recente do tier de releaseCongela a versão atual do cPanel - só atualiza via upcp executado manualmente
RPMUPPermite que o cPanel atualize pacotes RPM do sistema (Apache, PHP, etc.)Impede qualquer gerenciamento automático de RPMs pelo cPanel
UPDATESPolítica geral - define o comportamento padrãoModo full manual - nenhuma atualização automática de nenhuma categoria
SARULESUPAtualiza regras de SpamAssassin automaticamenteManter em daily - regras antispam são atualizações de assinatura, não de código

Configuração final aplicada:

# Editar o arquivo de configuração
nano /etc/cpupdate.conf
CPANEL=manual
RPMUP=manual
SARULESUP=daily
STAGING_DIR=/usr/local/cpanel
UPDATES=manual

Verificando que a configuração foi absorvida:

# Testar o upcp em modo dry-run sem aplicar mudanças
/usr/local/cpanel/scripts/upcp --force --noupdate 2>&1 | head -20

# Verificar a versão atual do cPanel (deve permanecer a mesma após o próximo ciclo de cron)
cat /usr/local/cpanel/version
# 116.0.x.x (ou a versão instalada no momento da auditoria)

Verificar que o cron do upcp ainda existe mas está sendo controlado pela conf:

# O cron PERMANECE ativo - ele roda, lê a conf, e não faz nada porque UPDATES=manual
crontab -l | grep upcp
# 0 0 * * * /usr/local/cpanel/scripts/upcp --cron >> /var/log/cpupdate.log 2>&1

Importante: Não remover o cron do upcp. O script faz mais do que apenas atualizar - ele também roda verificações de integridade e gera logs que o suporte da cPanel usa para diagnóstico. A diretiva manual no cpupdate.conf é o mecanismo correto de controle.

Camada 3 - blindando pacotes críticos no yum/dnf#

Mesmo com o cPanel em modo manual, o gerenciador de pacotes nativo do SO permanece funcional e pode atualizar pacotes críticos se outro script, outro administrador ou uma dependência instalada rodar yum update ou dnf upgrade sem filtros.

Identificando o arquivo correto para o SO:

# AlmaLinux 8/9, CentOS 8, CloudLinux 8/9, RHEL 8/9
ls /etc/dnf/dnf.conf
# Se existir, usar este

# CentOS 7, CloudLinux 7
ls /etc/yum.conf
# Se existir, usar este

# Verificar qual gerenciador de pacotes está ativo
which dnf && echo "dnf" || which yum && echo "yum"

Verificando o estado atual antes da alteração:

# AlmaLinux/CloudLinux 8/9
grep "exclude" /etc/dnf/dnf.conf
# → Nenhuma saída = sem exclusões configuradas

# CentOS 7
grep "exclude" /etc/yum.conf
# → Nenhuma saída = sem exclusões configuradas

Adicionando a diretiva exclude na seção [main]:

Para AlmaLinux/CloudLinux 8/9 (/etc/dnf/dnf.conf):

[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
exclude=kernel* httpd* mysql* mariadb* php*

Para CentOS 7 (/etc/yum.conf):

[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=5
bugtracker_url=...
distroverpkg=centos-release
exclude=kernel* httpd* mysql* mariadb* php*

Anatomia da diretiva exclude:

exclude=kernel* httpd* mysql* mariadb* php*
    │       │       │       │        │
    │       │       │       │        └── php, php-fpm, php-common, php-cli, ...
    │       │       │       └─────────── mariadb, mariadb-libs, mariadb-server, ...
    │       │       └─────────────────── mysql, mysql-community-server, ...
    │       └─────────────────────────── httpd, httpd-tools, httpd-devel, ...
    └─────────────────────────────────── kernel, kernel-devel, kernel-headers, ...

O curinga captura todos os subpacotes e variantes. Exemplo: httpd bloqueia tanto httpd quanto httpd-tools, httpd-devel e mod_ssl.

Testando que as exclusões estão ativas:

# Listar o que seria atualizado (sem aplicar)
dnf check-update 2>/dev/null | grep -E "kernel|httpd|mysql|mariadb|php"
# → Nenhuma saída = pacotes excluídos não aparecem como disponíveis para update

# Confirmar que a exclusão está configurada
dnf config-manager --dump | grep exclude
# → exclude = kernel* httpd* mysql* mariadb* php*

Testando instalação manual forçada (para janela de manutenção):

Durante uma janela de manutenção planejada, para aplicar especificamente a atualização de um pacote excluído:

# Forçar atualização de pacote excluído na conf (override da regra de exclusão)
dnf update httpd --disableexcludes=main

# Ou atualizar apenas o kernel com controle total
dnf update kernel --disableexcludes=main

Camada 4 - verificação de integridade da configuração#

Após aplicar ambas as camadas, verificar o estado consolidado:

echo "=== cPanel Update Config ==="
cat /etc/cpupdate.conf

echo ""
echo "=== Yum/DNF Exclude Rules ==="
grep -E "exclude|gpgcheck" /etc/dnf/dnf.conf 2>/dev/null || \
grep -E "exclude|gpgcheck" /etc/yum.conf 2>/dev/null

echo ""
echo "=== cPanel Current Version ==="
cat /usr/local/cpanel/version

echo ""
echo "=== Kernel Current Version ==="
uname -r

echo ""
echo "=== Apache Current Version ==="
httpd -v 2>/dev/null || apachectl -v 2>/dev/null

Saída esperada após a auditoria:

=== cPanel Update Config ===
CPANEL=manual
RPMUP=manual
SARULESUP=daily
STAGING_DIR=/usr/local/cpanel
UPDATES=manual

=== Yum/DNF Exclude Rules ===
exclude=kernel* httpd* mysql* mariadb* php*
gpgcheck=1

=== cPanel Current Version ===
116.0.12.3

=== Kernel Current Version ===
5.14.0-362.8.1.el9_3.x86_64

=== Apache Current Version ===
Server version: Apache/2.4.58 (AlmaLinux)

Procedimento de desbloqueio para janelas de manutenção#

Para garantir que as atualizações sejam controladas (e não bloqueadas permanentemente), o procedimento de aplicação em janela de manutenção é:

# 1. Notificar o usuário / ativar modo de manutenção na aplicação

# 2. Fazer backup completo do servidor via WHM
#    WHM → Backup → Generate Backup

# 3. Atualizar o cPanel manualmente
/usr/local/cpanel/scripts/upcp --force

# 4. Atualizar pacotes do sistema operacional (com exclusões suspensas temporariamente)
dnf update --disableexcludes=main

# 5. Reiniciar serviços se necessário
systemctl restart httpd
systemctl restart mysql

# 6. Reativar as exclusões (já estão ativas - o --disableexcludes é só para o comando)
# Não é necessário nenhuma ação - as exclusões permanecem no dnf.conf

# 7. Verificar que os serviços retornaram saudáveis
systemctl status httpd mysql php-fpm

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários