¿Qué es UEFI Secure Boot?
UEFI Secure boot es un mecanismo de verificación para asegurar que el código lanzado por el firmware es de confianza.
El uso adecuado y seguro de UEFI Secure Boot requiere que cada binario cargado en el arranque sea validado contra claves conocidas, ubicadas en el firmware, que denotan proveedores y fuentes de confianza para los binarios, o binarios específicos de confianza que pueden ser identificados a través de hash criptográfico.
La mayoría del hardware x86 viene de fábrica precargado con claves de Microsoft. Esto significa que, por lo general, podemos confiar en que el firmware de estos sistemas confíe en los binarios firmados por Microsoft, y la comunidad de Linux se basa en gran medida en esta suposición para que el Secure Boot funcione. Este es el mismo proceso utilizado por Red Hat y SUSE, por ejemplo.
Muchas arquitecturas ARM y otras también soportan UEFI Secure Boot, pero pueden no precargar las claves en el firmware. En estas arquitecturas, puede ser necesario volver a firmar las imágenes de arranque con un certificado que se carga en el firmware por el propietario del hardware.
Plan de implementación inicial: Plan de implementación.
Arquitecturas soportadas
-
amd64: Un binario shim firmado por Microsoft y un binario grub firmado por Canonical se proporcionan en el archivo principal de Ubuntu como shim-signed o grub-efi-amd64-signed.
-
arm64: A partir de la versión 20.04 (‘focal’), se proporciona un binario shim firmado por Microsoft y un binario grub firmado por Canonical en el archivo principal de Ubuntu como shim-signed o grub-efi-arm64-signed. Hay un error en GRUB que se está investigando y que necesita ser resuelto antes de que esto funcione de punta a punta.
Probando UEFI Secure Boot
Si estás interesado en probar Secure Boot en tu sistema, consulta el how-to aquí: UEFI/SecureBoot/Testing.
Cómo funciona el Secure Boot de UEFI en Ubuntu
En Ubuntu, todos los binarios pre-construidos destinados a ser cargados como parte del proceso de arranque, con la excepción de la imagen initrd, están firmados por el certificado UEFI de Canonical, que a su vez es de confianza implícita al estar incrustado en el cargador shim, a su vez firmado por Microsoft.
En arquitecturas o sistemas donde los certificados de firma precargados de Microsoft no están disponibles o cargados en el firmware, los usuarios pueden reemplazar las firmas existentes en shim o grub y cargarlas como deseen, verificando contra sus propios certificados importados en el firmware del sistema.
Cuando el sistema arranca, el firmware carga el binario shim como se especifica en las variables BootEntry del firmware. Ubuntu instala su propio BootEntry en el momento de la instalación y puede actualizarlo cada vez que se actualiza el gestor de arranque GRUB. Como el binario shim está firmado por Microsoft, es validado y aceptado por el firmware cuando se verifica contra los certificados ya presentes en el firmware. Dado que el binario shim incorpora un certificado de Canonical así como su propia base de datos de confianza, otros elementos del entorno de arranque pueden, además de ser firmados por uno de los certificados aceptables precargados en el firmware, ser firmados por la clave UEFI de Canonical.
La siguiente cosa cargada por shim es la imagen de segunda etapa. Esto puede ser una de dos cosas: o GRUB, si el sistema está arrancando normalmente; o MokManager, si se requiere la gestión de claves, según lo configurado por las variables del firmware (por lo general cambiado cuando el sistema se ejecutaba previamente).
Si el arranque es normal, se carga el binario de GRUB (grub*.efi) y se intenta su validación con todas las fuentes de confianza conocidas previamente. El binario GRUB para Ubuntu está firmado por la clave UEFI de Canonical, por lo que se valida con éxito y el proceso de arranque continúa.
Si se arranca para continuar con las tareas de gestión de claves, se carga el binario MokManager (mm*.efi). Este binario es explícitamente confiado por shim al ser firmado por una llave efímera que sólo existe mientras se construye el binario de shim. Esto significa que sólo el binario de MokManager construido con un binario de shim en particular podrá ser ejecutado y limita la posibilidad de compromiso por el uso de herramientas comprometidas. MokManager permite que cualquier usuario presente en la consola del sistema inscriba claves, elimine claves de confianza, inscriba hashes binarios y active la validación de arranque seguro a nivel de shim, pero la mayoría de las tareas requieren que se introduzca una contraseña previamente establecida para confirmar que el usuario en la consola es realmente la persona que solicitó los cambios. Tales contraseñas sólo sobreviven a través de una sola ejecución de shim / MokManager; y se borran tan pronto como el proceso se completa o se cancela. Una vez que la gestión de claves se ha completado, el sistema se reinicia y no continúa simplemente con el arranque, ya que los cambios de gestión de claves pueden ser necesarios para completar con éxito el arranque.
Una vez que el sistema continúa arrancando con GRUB; el proceso de GRUB carga cualquier configuración requerida (usualmente cargando la configuración desde el ESP (Partición del Sistema EFI), apuntando a otro archivo de configuración en la raíz o en la partición de arranque), que le indicará la imagen del kernel a cargar.
Las aplicaciones EFI hasta este punto tienen acceso completo al firmware del sistema, incluyendo el acceso a cambiar las variables del firmware de confianza, el kernel a cargar también debe ser validado contra la base de datos de confianza. Los kernels oficiales de Ubuntu al estar firmados por la clave UEFI de Canonical, son validados con éxito, y el control es entregado al kernel. Las imágenes Initrd no son validadas.
En el caso de los kernels no oficiales, o los kernels construidos por los usuarios, es necesario tomar medidas adicionales si los usuarios desean cargar dichos kernels conservando las capacidades completas de UEFI Secure Boot. Todos los kernels deben estar firmados para poder ser cargados por GRUB cuando el Arranque Seguro UEFI está habilitado, por lo que el usuario deberá proceder a su propia firma. Alternativamente, los usuarios pueden desear deshabilitar la validación en shim mientras se arranca con Secure Boot habilitado en un kernel oficial usando ‘sudo mokutil –disable-validation’, proporcionando una contraseña cuando se le pida, y reiniciando; o para deshabilitar Secure Boot en el firmware por completo.
Hasta este punto, cualquier fallo en la validación de una imagen para cargar se encuentra con un error crítico que detiene el proceso de arranque. El sistema no continuará arrancando, y puede reiniciar automáticamente después de un período de tiempo dado que otras variables BootEntry pueden contener rutas de arranque que son válidas y de confianza.
Una vez cargados, los kernels validados deshabilitarán los Servicios de Arranque del firmware, por lo que perderán privilegios y cambiarán efectivamente al modo de usuario; donde el acceso a las variables de confianza está limitado a sólo lectura. Dados los amplios permisos otorgados a los módulos del kernel, cualquier módulo que no esté integrado en el kernel también tendrá que ser validado al cargarse. Los módulos construidos y enviados por Canonical con los kernels oficiales están firmados por la clave UEFI de Canonical y como tal, son de confianza. Los módulos personalizados requerirán que el usuario tome los pasos necesarios para firmar los módulos antes de que el kernel permita su carga. Esto se puede lograr utilizando el comando ‘kmodsign’ .
Los módulos no firmados son simplemente rechazados por el kernel. Cualquier intento de insertarlos con insmod o modprobe fallará con un mensaje de error.
Dado que muchos usuarios requieren módulos de terceros para que sus sistemas funcionen correctamente o para que algunos dispositivos funcionen; y que estos módulos de terceros requieren ser construidos localmente en el sistema para ser ajustados al kernel en ejecución, Ubuntu proporciona herramientas para automatizar y simplificar el proceso de firma.
¿Cómo puedo hacer una firma no automatizada de los controladores?
Algunos proyectos pueden requerir el uso de controladores de kernel personalizados que no están configurados de manera que funcionen con DKMS. En estos casos, la gente debería hacer uso de las herramientas incluidas en el paquete shim-signed: el script update-secureboot-policy está disponible para generar un nuevo MOK (si no hay módulos construidos con DKMS que hayan activado la generación de uno ya).
Use el siguiente comando para inscribir una clave existente en shim:
sudo update-secureboot-policy --enroll-key
Si no existe ningún MOK, el script saldrá con un mensaje a tal efecto. Si la llave ya está inscrita, el script saldrá sin hacer nada. Si la llave existe pero no se muestra para ser registrada, se le pedirá al usuario una contraseña para usar después de reiniciar, para que la llave pueda ser registrada.
Se puede generar un nuevo MOK utilizando el siguiente comando:
sudo update-secureboot-policy --new-key
Y luego inscribir la llave recién generada en el shim con el comando mencionado anteriormente para esa tarea.
Los módulos del núcleo pueden entonces ser firmados con el comando kmodsign (ver UEFI/SecureBoot/Signing) como parte de su proceso de construcción.
Implicaciones de seguridad en la gestión de la clave del propietario de la máquina
El MOK generado en el momento de la instalación o en la actualización es específico de la máquina, y sólo es permitido por el kernel o shim para firmar los módulos del kernel, mediante el uso de un OID KeyUsage específico (1.3.6.1.4.1.2312.16.1.2) que denota las limitaciones del MOK.
Las versiones recientes del shim incluyen la lógica para seguir las limitaciones de las claves de sólo firma de módulo. A estas claves se les permitirá ser inscritas en el firmware en la base de datos de confianza de shim, pero serán ignoradas cuando shim o GRUB validen imágenes para cargar en el firmware. La función verify() de shim sólo validará con éxito las imágenes firmadas por claves que no incluyan el OID KeyUsage «Module-signing only» (1.3.6.1.4.1.2312.16.1.2). Los núcleos de Ubuntu utilizan la base de datos de confianza global (que incluye tanto la de los shim como la del firmware) y aceptarán cualquiera de las claves incluidas como claves de firma al cargar los módulos del núcleo.
Dadas las limitaciones impuestas al MOK generado automáticamente y el hecho de que los usuarios con acceso de superusuario al sistema y acceso a la consola del sistema para introducir la contraseña requerida al inscribir las claves ya tienen acceso de alto nivel al sistema; la clave MOK generada se mantiene en el sistema de archivos como archivos regulares propiedad de root con permisos de sólo lectura. Esto se considera suficiente para limitar el acceso al MOK para la firma por parte de usuarios o scripts maliciosos, especialmente teniendo en cuenta que no existe ningún MOK en el sistema a menos que requiera controladores de terceros. Esto limita la posibilidad de compromiso por el mal uso de una clave MOK generada para firmar un módulo del kernel malicioso. Esto es equivalente al compromiso de las aplicaciones de tierra de usuario que ya sería posible con el acceso de superusuario al sistema, y asegurar esto está fuera del alcance de UEFI Secure Boot.
Los sistemas anteriores pueden haber tenido la validación de Secure Boot deshabilitada en el shim. Como parte del proceso de actualización, estos sistemas se migrarán para volver a habilitar la validación de Secure Boot en shim e inscribir una nueva clave MOK cuando sea aplicable.
Proceso de generación y firma de MOK
El proceso de generación y firma de la clave es ligeramente diferente en función de si se trata de una instalación completamente nueva o de una actualización de un sistema que previamente ejecutaba Ubuntu; estos dos casos están claramente marcados a continuación.
En todos los casos, si el sistema no está arrancando en modo UEFI, no habrá pasos especiales de firma de módulos del kernel o generación de claves.
Si el Arranque Seguro está deshabilitado, la generación de MOK y la firma siguen ocurriendo, ya que el usuario puede habilitar posteriormente el Arranque Seguro. El sistema debería funcionar correctamente si ese es el caso.
El usuario instala Ubuntu en un nuevo sistema
El usuario pasa por el instalador. Al principio, cuando se prepara la instalación y sólo si el sistema requiere módulos de terceros para funcionar, se le pide al usuario una contraseña del sistema que está claramente marcada como necesaria después de que la instalación esté completa, y mientras el sistema se está instalando, se genera automáticamente un nuevo MOK sin más interacción del usuario.
Los controladores de terceros o los módulos del kernel requeridos por el sistema se construirán automáticamente cuando se instale el paquete, y el proceso de construcción incluye un paso de firma. El paso de firma utiliza automáticamente el MOK generado anteriormente para firmar el módulo, de modo que pueda cargarse inmediatamente una vez que el sistema se reinicie y el MOK se incluya en la base de datos de confianza del sistema.
Una vez completada la instalación y reiniciado el sistema, en el primer arranque se presenta al usuario el programa MokManager (parte del cargador de shim instalado), como un conjunto de paneles en modo texto que permiten al usuario inscribir el MOK generado. El usuario selecciona «Inscribir MOK», se le muestra una huella del certificado a inscribir y se le pide que confirme la inscripción. Una vez confirmado, el nuevo MOK se introducirá en el firmware y se pedirá al usuario que reinicie el sistema.
Cuando el sistema se reinicie, se cargarán los controladores de terceros firmados por el MOK que se acaba de inscribir, según sea necesario.
El usuario actualiza un sistema Ubuntu habilitado para UEFI a una nueva versión en la que el sistema requiere controladores de terceros
Al actualizar, se actualizan los paquetes firmados por shim y shim. Las tareas posteriores a la instalación del paquete firmado por shim proceden a generar un nuevo MOK, y solicitan al usuario una contraseña que se menciona claramente como necesaria una vez que se completa el proceso de actualización y se reinicia el sistema.
Durante la actualización, los paquetes del kernel y los módulos de terceros se actualizan. Los módulos de terceros se reconstruyen para los nuevos kernels y su proceso de post-construcción procede a firmarlos automáticamente con el MOK.
Después de la actualización, se recomienda al usuario reiniciar su sistema.
Al reiniciar, el usuario se encuentra con el programa MokManager (parte del cargador de shim instalado), como un conjunto de paneles en modo texto que todo el usuario para inscribir el MOK generado. El usuario selecciona «Inscribir MOK», se le muestra una huella del certificado a inscribir y se le pide que confirme la inscripción. También se le presenta al usuario un aviso para que vuelva a activar la validación de Secure Boot (en el caso de que se encuentre desactivada); y MokManager vuelve a solicitar la confirmación del usuario. Una vez confirmados todos los pasos, se vuelve a habilitar la validación del shim, se introduce el nuevo MOK en el firmware y se pide al usuario que reinicie el sistema.
Cuando el sistema se reinicie, se cargarán los controladores de terceros firmados por el MOK que se acaba de inscribir, según sea necesario.
En todos los casos, una vez que el sistema se ejecuta con UEFI Secure Boot habilitado y una versión reciente de shim; la instalación de cualquier módulo DKMS nuevo (controlador de terceros) procederá a firmar el módulo construido con el MOK. Esto ocurrirá sin la interacción del usuario si existe una clave MOK válida en el sistema y parece que ya está inscrita.
Si no existe un MOK o el MOK existente no está inscrito, se creará automáticamente una nueva clave justo antes de firmar y se pedirá al usuario que inscriba la clave proporcionando una contraseña que se requerirá al reiniciar.