secure-os.org
Todas las guíasQubes OSTailsWhonixLinux endurecidoCifrado de discoModelo de amenaza
ubuntu

Unattended-upgrades en Ubuntu: qué instala la configuración por defecto y qué deja fuera

secure-os· Actualizado 7 de octubre de 2026· 10 min de lectura #ubuntu#updates#hardening#linux#apt
Dos manos con mangas azul oscuro deslizando una placa de circuito verde, con una fila de puertos de red, dentro de un chasis de equipo naranja y blanco

«Las actualizaciones de seguridad automáticas están activadas» es la frase con la que terminan muchas auditorías de servidores. Es cierta en la mayoría de las máquinas con Ubuntu, y describe menos de lo que parece. El paquete que hace el trabajo, unattended-upgrades, se distribuye con un archivo de configuración cuyos comentarios dicen con precisión qué está activo, qué no lo está y qué nunca formó parte del alcance.

Esta guía lee ese archivo tal como lo publica el proyecto original, opción por opción, y muestra cómo comprobar cada punto en tu propia máquina.

La respuesta corta

Con la configuración de serie, unattended-upgrades:

  • instala paquetes del pocket principal de la versión y del pocket -security, además de los pockets de seguridad de ESM cuando están disponibles en el sistema;
  • no instala nada desde -updates, -proposed ni -backports, que están comentados;
  • no reinicia, porque Automatic-Reboot vale false por defecto;
  • no avisa a nadie, porque Unattended-Upgrade::Mail es una cadena vacía por defecto;
  • no toca los repositorios de terceros, porque solo se permiten los orígenes de la lista.

Cada uno de esos valores es una decisión deliberada, y cada uno se cambia con unas tres líneas.

Dos archivos, dos funciones

El comportamiento se reparte entre dos archivos de /etc/apt/apt.conf.d/.

20auto-upgrades es el interruptor. Tal como lo entrega el proyecto, contiene exactamente dos líneas:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

El README del proyecto describe su significado sin rodeos: el sistema comprueba si hay actualizaciones cada día y las instala, si es posible. Pon cualquiera de los dos valores a "0" y el paso correspondiente se detiene.

50unattended-upgrades es la política: qué paquetes son candidatos y qué ocurre después de instalarlos. Todo lo que sigue procede de ese segundo archivo.

Para ver los valores que tu máquina aplica de verdad, una vez fusionados todos los fragmentos, el README remite a un comando:

apt-config dump | grep -E 'Periodic|Unattended'

Qué permiten realmente los «orígenes permitidos»

El núcleo de la política es una lista. En la variante del archivo para Ubuntu dice así:

Unattended-Upgrade::Allowed-Origins {
	"${distro_id}:${distro_codename}";
	"${distro_id}:${distro_codename}-security";
	"${distro_id}ESMApps:${distro_codename}-apps-security";
	"${distro_id}ESM:${distro_codename}-infra-security";
//	"${distro_id}:${distro_codename}-updates";
//	"${distro_id}:${distro_codename}-proposed";
//	"${distro_id}:${distro_codename}-backports";
};

(Las dos líneas de ESM con legacy-security se omiten aquí por brevedad.) Las líneas que empiezan por // son comentarios, así que -updates no es un origen permitido. Una corrección que llega a tu versión solo a través del pocket -updates espera a un apt upgrade manual.

El comentario situado encima de la lista explica por qué figura el pocket principal: en Ubuntu, las actualizaciones de seguridad pueden arrastrar dependencias nuevas desde fuentes que no son de seguridad (el ejemplo citado es chromium), y al permitir el pocket principal esas dependencias se instalan automáticamente.

El README añade una regla con más consecuencias de las que aparenta: la herramienta no instala paquetes cuyas dependencias no puedan obtenerse de orígenes permitidos. Una actualización de seguridad cuya dependencia vive en un pocket que no has permitido queda retenida, sin ningún error en pantalla.

Los repositorios de terceros quedan fuera de la lista

El repositorio de Docker, un PPA, la fuente apt de un fabricante: ninguno coincide con ${distro_id}:${distro_codename}-security, así que ninguno se actualiza automáticamente. El software instalado desde esas fuentes se queda en la versión que instalaste a mano la última vez.

El README documenta la solución. Cada repositorio tiene un origen y un archivo, visibles en los campos o= y a= de:

apt-cache policy

Añade el par que leas ahí a tu propio archivo de anulación (ver más abajo) en lugar de adivinarlo. El README documenta también Origins-Pattern, que compara patrones de tipo glob como "site=www.example.com,component=main".

Un pasillo de un centro de datos con suelo de hormigón pulido, flanqueado por altos armarios negros con puertas de malla que dejan ver cables azules y rojos, y al fondo un carro con ruedas que lleva un monitor.

El reinicio que nadie programó

Este es el hueco con mayores consecuencias. El archivo dice:

// Automatically reboot *WITHOUT CONFIRMATION* if
//  the file /var/run/reboot-required is found after the upgrade
//Unattended-Upgrade::Automatic-Reboot "false";

El valor por defecto es false. Cuando una actualización necesita un reinicio para surtir efecto, se crea el archivo testigo /var/run/reboot-required y no ocurre nada más. El paquete del kernel corregido queda instalado mientras el kernel antiguo sigue en ejecución: el parche está en el disco, no en la memoria. La frase de la auditoría, «las actualizaciones de seguridad son automáticas», sigue siendo cierta todo ese tiempo.

Comprueba cualquier máquina con una línea:

test -f /var/run/reboot-required && echo "reboot pending"

Si quieres que la máquina se reinicie sola, el archivo ofrece dos ajustes que van juntos:

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

Sin el segundo, el valor por defecto es "now", es decir, inmediatamente después de la actualización. Ten en cuenta también que Automatic-Reboot-WithUsers vale true por defecto: los usuarios con sesión abierta no impiden el reinicio, salvo que lo pongas a false.

En una máquina que no puede reiniciarse sin supervisión (un servidor primario de base de datos, un host con el volumen raíz cifrado que pide una frase de paso en el arranque), deja el reinicio desactivado y resuelve la otra mitad del problema: hacer visible el reinicio pendiente.

El silencio es el valor por defecto

Unattended-Upgrade::Mail viene vacío, y el archivo es explícito sobre la consecuencia: si el valor está vacío o no está definido, no se envía ningún correo. También enuncia el requisito previo: una configuración de correo que funcione, con un paquete que proporcione mailx.

MailReport admite tres valores: "always", "only-on-error" y "on-change". En un servidor aislado, "on-change" te deja constancia de cada paquete que se ha movido. En una flota, "only-on-error" mantiene legible la bandeja de entrada.

Si el correo no es una opción, hay un segundo canal. SyslogEnable vale false por defecto. Ponlo a true y los eventos van a syslog, algo que el README considera útil en entornos donde los mensajes de syslog se envían a un almacén central.

Dónde mirar cuando parece que no pasa nada

El README indica el lugar: todas las operaciones se registran en /var/log/unattended-upgrades/, incluida la salida de dpkg. El archivo principal es /var/log/unattended-upgrades/unattended-upgrades.log.

Para saber qué haría la próxima ejecución sin cambiar nada, usa el comando que el proyecto recomienda para depurar:

sudo unattended-upgrade --debug --dry-run

La salida enumera los orígenes permitidos tal como la herramienta los ha entendido, y después cada paquete candidato con el motivo por el que se ha aceptado o descartado. Es la forma más rápida de confirmar que un repositorio que has añadido se reconoce de verdad.

Tres causas de que un paquete no se actualice están escritas en la propia documentación del proyecto:

  1. El origen no está permitido. Ver la lista de arriba.
  2. Una dependencia procede de un origen no permitido. El paquete queda retenido.
  3. El paquete preguntaría por un archivo de configuración. El README precisa que la herramienta comprueba las preguntas sobre archivos de configuración antes de instalar y retiene cualquier paquete que las requiera.

Cuándo se ejecuta

La planificación no está en los archivos de unattended-upgrades. Procede de dos temporizadores de systemd que entrega apt. En el árbol de fuentes de apt, consultado el día en que se redactó este artículo, apt-daily.timer se dispara a las 6,18:00 con RandomizedDelaySec=12h y se ocupa de las descargas, mientras que apt-daily-upgrade.timer se dispara a las 6:00 con RandomizedDelaySec=60m y se ocupa de la instalación.

Ambos llevan Persistent=true. La documentación de systemd define ese ajuste: el servicio se dispara de inmediato si habría debido dispararse al menos una vez mientras el temporizador estaba inactivo, lo que presenta como útil para recuperar ejecuciones perdidas cuando el sistema estaba apagado. Un portátil que estuvo suspendido durante su franja se actualiza, por tanto, poco después de despertar.

Tu distribución puede entregar otros valores. Lee los tuyos:

systemctl cat apt-daily-upgrade.timer
systemctl list-timers 'apt-daily*'

Por qué el apagado a veces espera

Si un apagado se detiene un momento mientras hay una actualización en curso, es el comportamiento previsto. El comentario de MinimalSteps explica que la actualización se divide en los pasos más pequeños posibles para poder interrumpirla con SIGTERM, y que eso permite apagar durante una actualización con un pequeño retraso. El archivo señala además que unattended-upgrades eleva el InhibitDelayMaxSec de logind a 30 segundos con ese fin.

Cortar la corriente en ese momento es la peor respuesta. Si aun así ocurre, AutoFixInterruptedDpkg, a true por defecto, lanza dpkg --force-confold --configure -a en la siguiente ejecución para terminar el trabajo interrumpido.

Cambiarlo sin editar el archivo entregado

El README es directo en este punto: la anulación debe hacerse en un fragmento de configuración de APT separado, porque las actualizaciones del archivo entregado pueden entrar en conflicto con los cambios locales y bloquear la actualización del propio unattended-upgrades. El archivo nuevo debe ordenarse después de 50unattended-upgrades, y el README sugiere el nombre 52unattended-upgrades-local.

Un punto de partida razonable para un servidor aislado, construido solo con opciones documentadas:

// /etc/apt/apt.conf.d/52unattended-upgrades-local
Unattended-Upgrade::Mail "you@example.com";
Unattended-Upgrade::MailReport "on-change";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

Hay una trampa que afecta a las listas. El README advierte de que, para sustituir una lista como Origins-Pattern, primero hay que vaciar la lista de serie con una directiva #clear antes de insertar la tuya. De lo contrario, tus entradas se permiten además de las de serie, no en su lugar.

Para dejar un paquete fuera de las actualizaciones automáticas, Package-Blacklist admite expresiones regulares de Python. El ejemplo del archivo muestra el error clásico: sin el $ final, "libc6" coincide con todos los paquetes cuyo nombre empieza por esos caracteres. El README añade un efecto secundario que conviene conocer: si el paquete A depende del paquete B incluido en la lista negra, no se actualiza ni A ni B.

Desactivarlo, y por qué rara vez es la decisión correcta

La vía admitida es la que da el README:

sudo dpkg-reconfigure -plow unattended-upgrades

Ajusta los dos valores periódicos por ti. Hay razones legítimas para hacerlo: un sistema de producción sometido a control de cambios, donde cada movimiento de paquetes se planifica, o un host gestionado por una herramienta de configuración que aplica ella misma las actualizaciones.

En cualquier otra máquina, desactivar el mecanismo cambia un riesgo pequeño y acotado (una actualización que se porta mal) por uno sin límite (una vulnerabilidad conocida que sigue abierta hasta que alguien se acuerda). Las herramientas más finas suelen bastar: poner en la lista negra el único paquete que te preocupa, o limitar las ejecuciones a ciertos días con Update-Days, que admite valores como {"Mon";"Fri"}.

Una auditoría de cinco minutos

Ejecuta esto en un servidor que crees que «se actualiza solo»:

  1. apt-config dump | grep -E 'Periodic|Unattended': ¿están los dos valores periódicos a "1", y qué orígenes se permiten?
  2. apt-cache policy: ¿qué repositorios existen en esta máquina que la lista permitida no cubre?
  3. test -f /var/run/reboot-required && echo pending: ¿hay un reinicio pendiente?
  4. tail -n 50 /var/log/unattended-upgrades/unattended-upgrades.log: ¿cuándo fue la última ejecución y qué hizo?
  5. sudo unattended-upgrade --debug --dry-run: ¿qué haría la próxima ejecución y qué retendría?

Si las respuestas son «sí, ninguno, no, anoche, nada retenido», la frase de la auditoría por fin es exacta.

Los nombres de las opciones, los valores por defecto y los comentarios referidos proceden de los archivos 50unattended-upgrades.Ubuntu y 20auto-upgrades y del README del repositorio original de unattended-upgrades. Los valores de los temporizadores proceden del árbol de fuentes de apt, y la definición de Persistent= del manual systemd.timer. Todos se leyeron el 7 de octubre de 2026. Las versiones empaquetadas difieren entre versiones de Ubuntu, así que el archivo de tu propia máquina es la referencia final.

Los parches automáticos son una capa entre varias: la visión de conjunto está en la guía de hardening de Linux, y los controles a nivel de servicio se tratan en hardening de servicios systemd.