Cómo bloquear las actualizaciones de paquetes y del núcleo en Debian / Ubuntu

APT es probablemente la herramienta más útil para un usuario de Linux. Puedes instalar, actualizar y eliminar cualquier software/paquete de tu sistema Linux con un solo comando. Pero a veces, necesitas un control granular sobre qué paquete quieres instalar o actualizar y qué paquete bloquear para que no se actualice automáticamente. ¿Por qué quieres hacer esto? A veces descubres que la versión actualizada de un paquete tiene errores. No quieres que ese paquete se actualice la próxima vez que ejecutes sudo apt upgrade. Y es un engorro actualizar cada paquete individualmente.

Este tutorial cubrirá cómo bloquear la instalación o actualización de determinados paquetes y cómo bloquear la instalación de versiones específicas de paquetes o núcleos.

Nota: Es fácil olvidar qué paquetes has retenido después de algún tiempo, incluso cuando ya han salido sus versiones libres de errores. Así que mantente alerta, ya que retener paquetes durante mucho tiempo puede introducir problemas de seguridad.

Aquí trataremos dos métodos. El primer método bloqueará todas las instalaciones y actualizaciones de un determinado paquete. El segundo método ofrece un control más granular, permitiéndote bloquear versiones específicas de un paquete.

Requisitos previos

  • Un servidor con sistema operativo Ubuntu o Debian. Para este tutorial se ha utilizado Ubuntu 22.04, pero los comandos que aquí se indican también deberían funcionar correctamente con otros sistemas operativos basados en Debian y versiones anteriores.
  • Un usuario no root con privilegios sudo.

Método 1 (apt-mark)

Para bloquear un paquete y evitar que se instale, actualice o elimine, podemos utilizar el comando apt-mark.

Si quieres impedir que se instale, actualice o elimine un paquete, por ejemplo, htop, utiliza el siguiente comando.

$ sudo apt-mark hold htop

Deberías ver la siguiente salida.

htop set on hold.

El paquete bloqueado permanecerá en la misma versión aunque actualices tu sistema. Esto es especialmente útil para retener controladores gráficos.

Para eliminar la retención del paquete, emite el siguiente comando.

$ sudo apt-mark unhold htop

Deberías ver la siguiente salida.

Canceled hold on htop.

Hay una advertencia importante. Aunque el paquete no se actualizará automáticamente al utilizar el comando sudo apt upgrade o al actualizar el sistema, puedes eliminar el paquete manualmente. sudo apt remove <package> seguirá funcionando con los paquetes retenidos.

Este método sólo impide que se modifiquen automáticamente. Mantenerlos retenidos los mantendrá en sus versiones actuales pase lo que pase, a menos que decidas eliminarlos manualmente.

Método 2 (/etc/apt/preferences)

Este método implica editar el archivo /etc/apt/preferences, donde puedes especificar exactamente qué versión de qué paquete y de qué repositorio se instala.

Cada paquete recibe una prioridad numérica en función de la cual APT decide si lo instala o no y, en caso afirmativo, de qué repositorio debe recogerlo.

Por ejemplo, vamos a comprobar algunos detalles sobre el paquete nginx. Ejecuta el siguiente comando.

$ apt-cache policy nginx

Deberías ver una salida similar.

nginx:
  Installed: (none)
  Candidate: 1.22.1-1~jammy
  Version table:
     1.22.1-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.22.0-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.20.2-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.18.0-6ubuntu14.3 500
        500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages
     1.18.0-6ubuntu14 500
        500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages

Verás que hay dos repositorios desde los que se instala nginx. El primero es el repositorio de Ubuntu y el segundo es el repositorio de nginx.

Puedes ver escrito 500 en todos los repositorios. Este número especifica la prioridad del paquete. Como es el mismo para todos los repositorios, las probabilidades de que nginx provenga de cualquiera de los repositorios son las mismas. Entonces, ¿cómo decidirá el sistema qué paquete elegir? Elegirá la versión más alta que haya. En este caso, es la 1.22.1. Para Ubuntu, el número de versión completo es 1.22.1-1~jammy.

Si no quieres actualizar a la versión 1.22.1 y quieres bloquearla, tienes que editar el archivo /etc/apt/preferences.

Abre el archivo en el editor nano.

$ sudo nano /etc/apt/preferences

Este comando también te ayudará a crear el archivo si no existía previamente en el sistema.

Pega el siguiente código en el archivo.

Package: nginx
Pin: version 1.22.1-1~jammy
Pin-Priority: -1

Establecer la prioridad a un valor inferior a 0 significa que el paquete no se instalará. Si quieres que un paquete se instale siempre, establece su prioridad en 1000 o superior.

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Comprobemos de nuevo el paquete.

$ apt-cache policy nginx

Verás el siguiente resultado.

nginx:
  Installed: (none)
  Candidate: 1.22.0-1~jammy
  Version table:
     1.22.1-1~jammy -1
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.22.0-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.20.2-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.18.0-6ubuntu14.3 500
        500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages
     1.18.0-6ubuntu14 500
        500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages

¿Notas alguna diferencia? La versión Candidate release ha bajado de 1.22.1 a 1.22.0. Esto significa que la siguiente versión superior que instalará ahora el sistema es la 1.22.0. También observarás que se ha escrito -1 contra la última versión, lo que significa que el sistema debe omitir esa versión.

Omitir una versión pero permitir la otra

Puedes añadir varias entradas para el mismo paquete en el archivo. Por ejemplo, añade el siguiente código al archivo.

Package: nginx
Pin: version 1.22.1-1~jammy
Pin-Priority: -1

Package: nginx
Pin: version 1.20.2-1~jammy
Pin-Priority: 1000

Aquí le estamos diciendo al sistema que omita la versión 1.22.1 pero que instale siempre la versión 1.20.2.

Comprobémoslo de nuevo utilizando el comando apt-cache policy.

nginx:
  Installed: (none)
  Candidate: 1.20.2-1~jammy
  Version table:
     1.22.1-1~jammy -1
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.22.0-1~jammy 500
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.20.2-1~jammy 1000
        500 http://nginx.org/packages/ubuntu jammy/nginx amd64 Packages
     1.18.0-6ubuntu14.3 500
        500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages
     1.18.0-6ubuntu14 500
        500 http://us.archive.ubuntu.com/ubuntu jammy/main amd64 Packages

Ahora la versión candidata ha pasado a ser 1.20.2 en lugar de 1.22.0.

Cambiar la preferencia de repositorio

Consideremos un caso más. ¿Qué pasa si queremos bloquear la instalación de Nginx desde su repositorio y elegir en su lugar el repositorio de Ubuntu? Una forma sería eliminar el repositorio de Nginx, pero puedes volver a utilizar el archivo de preferencias para que elija el repositorio por ti.

Introduce el siguiente código en el archivo.

Package: nginx
Pin: release o=nginx
Pin-Priority: -1

La palabra clave release sólo especifica la versión inmediatamente superior. o=nginx se refiere al origen del paquete. Aquí es nginx. Esto significa que el sistema no debe instalar el paquete nginx desde su repositorio. Otra forma de conseguir el mismo resultado es utilizar el siguiente código.

Package: nginx
Pin: release o=jammy
Pin-Priority: 1000

Esta vez hemos establecido la prioridad 1000 del paquete del repositorio de Ubuntu (jammy). Esto garantizará que Nginx se instale siempre desde el repositorio de Ubuntu y no desde ningún otro sitio.

No sólo puedes especificar el origen del paquete, sino que también puedes añadir el archivo, el componente, la etiqueta y la arquitectura del paquete que el sistema debe elegir utilizando las siguientes palabras clave en la sección Pin.

  • c -> Componente
  • a -> Archivo
  • o -> Origen
  • l -> Etiqueta
  • n -> Arquitectura

Bloquear actualizaciones específicas del núcleo

Veamos cómo podemos bloquear actualizaciones específicas del kernel. Lista todos los paquetes relacionados con el kernel en tu sistema.

$ dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'

Verás una salida similar.

linux-headers-5.15.0-33-generic
linux-image-5.15.0-33-generic
linux-modules-5.15.0-33-generic
linux-modules-extra-5.15.0-33-generic

Tendrás que repetir los siguientes métodos para todos los paquetes obtenidos aquí.

Método 1 (apt-mark)

En primer lugar, vamos a comprobar qué versión del núcleo está activa. Para ello, ejecuta el siguiente comando.

$ uname -r

Deberías ver una salida similar.

5.15.0-53-generic

Para evitar que el kernel se siga actualizando, podemos utilizar simplemente el comando apt-mark.

$ sudo apt-mark hold linux-image-$(uname -r)

Deberías ver una salida similar.

linux-image-5.15.0-53-generic set on hold.

Puedes seguir el mismo método para bloquear las cabeceras del núcleo bloqueando el paquete linux-headers-$(uname -r).

Método 2 (/etc/apt/apt.conf.d/50unattended-upgrades)

El segundo método implica el archivo /etc/apt/apt.conf.d/50unattended-upgrades.

Ábrelo para editarlo.

$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Desplázate hasta la sección Unattended-Upgrade::Package-Blacklist y edítalo como se indica a continuación.

Unattended-Upgrade::Package-Blacklist {
"linux-generic";
"linux-image-generic";
"linux-headers-generic";
"linux-modules-generic";
"linux-modules-extra-generic";
};

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Método 3 (dpkg)

Para realizar la actualización del núcleo utilizando dpkg, ejecuta el siguiente comando. Este comando retendrá todos los paquetes relacionados con el núcleo al mismo tiempo.

$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i hold | dpkg --set-selections; done

Para eliminar la retención, utiliza el siguiente comando.

$ for i in $(dpkg -l "*$(uname -r)*" | grep kernel | awk '{print $2}'); do echo $i install | dpkg --set-selections; done

Método 4 (/etc/apt/preferences)

Comprobemos primero los detalles relativos a la versión actual del núcleo.

$ apt-cache policy linux-image-$(uname -r)

Deberías ver la siguiente salida.

linux-image-5.15.0-53-generic:
  Installed: 5.15.0-53.59
  Candidate: 5.15.0-53.59
  Version table:
 *** 5.15.0-53.59 500
        500 http://us.archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://us.archive.ubuntu.com/ubuntu jammy-security/main amd64 Packages
        100 /var/lib/dpkg/status

Aunque el kernel 5.15.0.53 está en su última versión en el momento de escribir este tutorial, suponemos que la siguiente versión ya ha salido (5.15.0.56 es la versión estable actual del kernel Linux).

Para bloquear la siguiente versión del kernel, introduce el siguiente código en el archivo /etc/apt/preferences.`

Package: linux-image-5.15.0-53-generic linux-headers-5.15.0-33-generic linux-modules-5.15.0-33-generic linux-modules-extra-5.15.0-33-generic
Pin: version 5.15.0-53.59
Pin-Priority: -1

El código anterior bloqueará Ubuntu para que no instale ninguna o ninguna de las actualizaciones del núcleo.

Puedes seguir los métodos 2 y 3 para cualquier paquete normal, no sólo para el núcleo.

Conclusión

Eso es todo para este tutorial. Ahora deberías ser capaz de bloquear cualquier versión o versiones específicas de cualquier paquete que no quieras que se instale o actualice en tu sistema Ubuntu o Debian. Si tienes alguna pregunta, publícala en los comentarios a continuación.

También te podría gustar...