APT: mantenimiento avanzado de paquetes en Debian

Cuando llevas tiempo administrando sistemas Debian, el ciclo básico de apt update && apt upgrade se queda corto. Necesitas saber qué tienes instalado y en qué estado, controlar qué se actualiza y cuándo, y asegurarte de que el sistema no acumula basura silenciosa. Todo eso existe en APT, pero requiere conocer las herramientas correctas y entender qué hay debajo.

El inventario: qué tienes y qué puede actualizarse

apt list es la interfaz moderna para consultar el estado de los paquetes. Con --installed consultas la base de datos dpkg y obtienes todo lo que está marcado como instalado, incluyendo dependencias automáticas. Con --upgradable APT cruza el índice local (el resultado del último apt update) contra las versiones instaladas y muestra solo los paquetes para los que existe una versión superior en algún repositorio configurado. Si el índice está desactualizado, --upgradable miente por omisión —no hay ningún error, simplemente no tiene información nueva—, así que siempre ejecuta apt update antes de confiar en esa lista.

Congelar paquetes con apt-mark hold

apt-mark hold modifica la bandera de selección de un paquete en dpkg para marcarlo como hold. APT respeta esa marca y excluye el paquete de cualquier operación de actualización o eliminación automática, incluso cuando hay una versión más nueva disponible. Esto no es un bloqueo criptográfico ni una restricción de versión: es una instrucción en la base de datos de dpkg. Si ejecutas apt install paquete=versión_nueva de forma explícita, dpkg te avisará pero procederá si le confirmas. La utilidad real de hold es protegerte del apt upgrade rutinario mientras investigas por qué la versión nueva rompe algo en producción. apt-mark unhold revierte la marca y devuelve el paquete al ciclo normal de actualizaciones.

Lo que sí rompe el hold mal gestionado es el grafo de dependencias: si otros paquetes evolucionan y empiezan a requerir una versión más nueva del paquete congelado, APT no podrá resolverlo y bloqueará esas actualizaciones también. Un hold que dura semanas en un paquete central como libc6 o linux-image es una deuda técnica que se cobra con intereses.

Limpiar dependencias huérfanas y caché

apt autoremove elimina los paquetes marcados como instalados automáticamente (dependencias) que ya no son necesarios porque el paquete que los requería fue eliminado. APT lleva ese registro internamente: cuando instalas algo manualmente, marca sus dependencias como auto. Si luego eliminas el paquete principal sin --autoremove, esas dependencias quedan huérfanas. apt autoremove las recoge. Revisa siempre la lista antes de confirmar: ocasionalmente APT considera huérfano algo que usas directamente pero que nunca marcaste como instalado manualmente.

Para la caché local, tienes dos herramientas con comportamiento distinto. apt clean vacía completamente /var/cache/apt/archives/, borrando todos los .deb descargados independientemente de si siguen siendo relevantes. apt autoclean es más conservador: solo elimina los .deb que ya no pueden descargarse desde ningún repositorio configurado (versiones antiguas que el repositorio ya no sirve). En servidores con espacio ajustado, apt clean en un cronjob post-actualización es habitual. En estaciones de desarrollo donde reinstalás paquetes frecuentemente, autoclean evita descargas redundantes.

Pinning: mezclar versiones de distintas ramas

El pinning es el mecanismo por el que le dices a APT qué versión preferir cuando un mismo paquete existe en múltiples releases o repositorios. Se configura en /etc/apt/preferences.d/ con archivos de texto plano. APT asigna una prioridad numérica a cada combinación de paquete y origen; gana la prioridad más alta. Los valores de referencia son:

  • Por encima de 1000: instala esa versión incluso si implica un downgrade.
  • Entre 990 y 1000: se prefiere aunque no sea la más nueva.
  • Entre 500 y 989: comportamiento normal, se prefiere si es más nueva.
  • Por debajo de 500: se usa solo si no hay alternativa.
  • Negativo: nunca se instala (equivale a blacklist).

El caso típico en Debian es mezclar stable con backports: quieres la mayoría de paquetes de bookworm pero necesitas una versión más nueva de un paquete específico desde bookworm-backports. Sin pinning, si añades backports al sources.list, APT puede empezar a actualizar paquetes desde backports de forma no intencionada. Con pinning, defines que backports tiene prioridad 100 por defecto y subes solo los paquetes que te interesan.

Actualizaciones de seguridad automáticas y reinicio de servicios

unattended-upgrades es el paquete estándar en Debian para aplicar actualizaciones de seguridad sin intervención manual. En producción, la alternativa —no aplicar parches de seguridad hasta la próxima ventana de mantenimiento— tiene un coste de riesgo que en la mayoría de casos no vale la pena. unattended-upgrades aplica por defecto solo el origen Debian-Security, lo que limita el radio de acción a parches críticos y minimiza el riesgo de que una actualización de funcionalidad rompa algo.

needrestart resuelve un problema real que se ignora frecuentemente: actualizar una librería compartida como libssl o libgnutls no tiene efecto en los procesos que ya la tienen mapeada en memoria hasta que se reinician. needrestart detecta esos procesos comparando las librerías que tienen abiertas con las versiones instaladas en disco. En modo interactivo te muestra la lista; en modo automático puede reiniciar los servicios afectados directamente. Es especialmente útil después de actualizar libssl en un servidor con nginx, sshd y postgresql corriendo: sin needrestart, todos siguen usando la versión vulnerable hasta el próximo reinicio manual.


Ejemplo completo de mantenimiento

El siguiente bloque cubre un ciclo real de mantenimiento: actualizar con cuidado, congelar un paquete problemático, configurar pinning para backports, limpiar huérfanos y caché, e instalar la automatización de seguridad.

# Sincronizar índices
apt update

# Ver qué tiene actualizaciones disponibles antes de tocar nada
apt list --upgradable 2>/dev/null

# Actualizar todo excepto los paquetes que vamos a congelar
apt upgrade

# Congelar postgresql-15: la versión nueva tiene un cambio de comportamiento
# en autovacuum que rompe nuestra configuración personalizada
apt-mark hold postgresql-15

# Verificar el estado: aparecerá como "hold" junto al nombre
apt-mark showhold

# En algún momento decidimos liberar el hold tras validar la nueva versión
# apt-mark unhold postgresql-15

# Eliminar dependencias huérfanas — revisar la lista antes de confirmar
apt autoremove

# Limpiar .deb descargados que el repositorio ya no sirve
apt autoclean

# Vaciar toda la caché si el espacio es crítico
# apt clean

# ── Pinning para backports ─────────────────────────────────────────────

# Añadir bookworm-backports al sources.list si no está
grep -q backports /etc/apt/sources.list.d/*.list 2>/dev/null || \
  echo "deb http://deb.debian.org/debian bookworm-backports main" \
  > /etc/apt/sources.list.d/backports.list

# Crear política de pinning: backports tiene prioridad baja por defecto (100)
# Solo instalaremos desde backports lo que pidamos explícitamente
cat > /etc/apt/preferences.d/backports.pref << 'EOF'
Package: *
Pin: release a=bookworm-backports
Pin-Priority: 100
EOF

# Subir prioridad de wireguard desde backports porque necesitamos la versión nueva
cat > /etc/apt/preferences.d/wireguard-backport.pref << 'EOF'
Package: wireguard wireguard-tools
Pin: release a=bookworm-backports
Pin-Priority: 700
EOF

apt update

# Confirmar desde qué origen instalará APT wireguard ahora
apt policy wireguard

# Instalar wireguard — vendrá de backports por la prioridad que asignamos
apt install wireguard

# ── Automatización de actualizaciones de seguridad ────────────────────

apt install unattended-upgrades needrestart

# Activar y configurar unattended-upgrades
# El archivo de configuración principal está en:
# /etc/apt/apt.conf.d/50unattended-upgrades
# La activación del timer periódico se hace con:
dpkg-reconfigure --priority=low unattended-upgrades

# Verificar que el timer systemd está activo
systemctl status apt-daily-upgrade.timer

# needrestart en modo automático: reinicia servicios sin preguntar
# Cambiar el comportamiento por defecto (interactivo) a automático:
sed -i "s/#\$nrconf{restart} = 'i'/\$nrconf{restart} = 'a'/" \
  /etc/needrestart/needrestart.conf

# Ejecutar needrestart manualmente para ver qué servicios necesitan reinicio
needrestart -r l

Desglose del ejemplo

apt list --upgradable 2>/dev/null: el 2>/dev/null silencia el aviso WARNING: apt does not have a stable CLI interface que APT emite cuando su salida se procesa programáticamente. En uso interactivo es informativo; en scripts es ruido.

apt-mark hold postgresql-15: el nombre debe coincidir exactamente con el paquete en dpkg, incluyendo el sufijo de versión mayor cuando existe (como en PostgreSQL, donde cada major release es un paquete separado). apt-mark showhold muestra todos los paquetes congelados actualmente; es el primer lugar donde mirar cuando APT te dice que no puede resolver una actualización.

El archivo /etc/apt/preferences.d/backports.pref establece la política base: todos los paquetes de backports tienen prioridad 100, por debajo del umbral 500 que APT usa para preferir versiones más nuevas. Esto significa que apt upgrade nunca tocará backports. El segundo archivo sube solo wireguard y wireguard-tools a 700, suficiente para que APT los prefiera sobre stable si hay una versión más nueva en backports.

apt policy wireguard: muestra la tabla de candidatos con sus prioridades calculadas. Es la herramienta de diagnóstico cuando el pinning no hace lo que esperas: ves exactamente qué versión ganará y por qué.

dpkg-reconfigure --priority=low unattended-upgrades: el flag --priority=low muestra todas las preguntas de configuración disponibles, incluyendo si activar el timer automático. Sin ese flag, debconf puede omitir preguntas que considera de baja importancia.

sed -i sobre needrestart.conf: el comportamiento por defecto de needrestart en Debian es i (interactivo), lo que tiene sentido en escritorios pero no en servidores donde nadie está sentado en el terminal esperando. El modo a (automatic) reinicia los servicios afectados sin intervención. El modo l (list) solo informa, útil para auditar sin actuar. El flag -r l que usamos al final ejecuta needrestart en modo lista para hacer un diagnóstico sin tocar nada.

Lo que conecta todas estas herramientas es el modelo de datos de dpkg: APT es una capa de lógica encima de una base de datos que dpkg mantiene en /var/lib/dpkg/. El hold, el estado auto de las dependencias, los paquetes instalados: todo vive ahí. Cuando algo no cuadra, dpkg -l, dpkg --get-selections y apt-cache policy te dan acceso directo a esa base de datos sin pasar por la capa de abstracción de APT.

56

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio