De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.


Secure Boot com GRUB no Debian

Colaboração: Jamenson Ferreira Espindula de Almeida Melo

Data de Publicação: 25 de junho de 2022

Problema: o GNU GRUB se recusa a carregar o Linux From Scratch (kernel versão 5.17). Alega que o mencionado kernel tem uma "assinatura inválida".

Observação: a Inicialização Segura ("Secure Boot") está ativada no dispositivo.

Sistema Operacional: Debian GNU/Linux 11 ("bullseye")

Visão geral

  • Tarefa um: identificar qual carregador de inicialização foi executado.
  • Tarefa dois: criar um par de chaves (padrão X.509).
  • Tarefa três: inserir a chave pública na base de dados do aplicativo "shim".
  • Tarefa quatro: assinar eletronicamente o kernel.
  • Tarefa cinco: assinar eletronicamente os módulos do kernel.

Pacotes necessários:

# apt-get install efibootmgr
# apt-get install linux-kbuild-5.10
# apt-get install mokutil
# apt-get install sbsigntool

Versões instaladas dos pacotes:

  • efibootmgr (17-1)
  • linux-image-5.10.0-15-rt-amd64 (5.10.120-1)
  • linux-kbuild-5.10 (5.10.106-1)
  • mokutil (0.3.0+1538710437.fb6250f-1+b1)
  • openssl (1.1.1n-0+deb11u2)
  • sbsigntool (0.9.2-2)
  • shim-signed (1.38+15.4-7)

Siglas:

MOK: Machine Owner Key

Tarefa um: identificar qual carregador de inicialização foi executado.

Problema: qual carregador de inicialização foi executado?

# efibootmgr --verbose
EFI variables are not supported on this system.
echo ${?}
2

Solução: incluído o parâmetro de linha de comando do kernel efi=runtime.

Passo um: na tela inicial do GRUB (aquela para escolha do Sistema Operacional a ser inicializado), posicionar o seletor para carga do Sistema Operacional desejado (no caso, "Debian GNU/Linux") e pressionar a tecla "e" (editar o comando a ser executado);

Passo dois: localizar a linha contendo o comando linux e acrescentar (ao final) o parâmetro efi=runtime.

Exemplo (linha já editada):

linux   /boot/vmlinuz-5.10.0-15-rt-amd64 root=UUID=dd301bab-14f1-44cb-881e-446eb7731abc ro  quiet efi=runtime

Passo três: pressionar a tecla "F10" para o GNU GRUB efetivamente executar comando recém editado.

Observações

  1. O parâmetro efi=runtime habilitará as "variáveis EFI" quando da execução do kernel Linux.

  2. Na Distribuição Debian GNU/Linux 11 ("bullseye"), as "variáveis EFI" ficam desabilitadas quando da operação normal, para aumentar a segurança do Dispositivo e a do Sistema Operacional.

  3. segundo os Mantenedores da Debian, as "variáveis EFI" (quando usadas erroneamente) podem causar dano permanente ao Dispositivo (fenômeno mais conhecido como "bricking").

Após a carga do Sistema Operacional, uma nova execução do aplicativo "efibootmgr" teve a seguinte saída:

# efibootmgr --verbose
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0000
Boot0000* debian       HD(1,GPT,d013099e-c6ee-4772-8076-73dad8a0f300,0x800,0x50000)/File(\EFI\debian\shimx64.efi)

Tarefa dois: criar um par de chaves (padrão X.509).

Passo um: como usuário root, criar o diretório onde o aplicativo "shim" espera encontrar a chave pública a ser inserida.

# mkdir -pv /var/lib/shim-signed/mok/
# cd /var/lib/shim-signed/mok/

**Passo dois*: para gerar um par de chaves (padrão X.509), o seguinte comando foi executado (como usuário root):

# openssl req -new -x509 -newkey rsa:4096 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=My Name/"

Passo três: além da criação do par de chaves, houve a produção de mais um arquivo (no formato PEM), arquivo esse contendo a chave pública. Ainda como usuário root:

# openssl x509 -inform DER -in MOK.der -out MOK.pem

Tarefa três: inserir a chave pública na base de dados do aplicativo "shim".

No aplicativo mokutil, deve-se inserir (to enroll) a chave pública (confeccionada no passo anterior) na base de dados do aplicativo shim. Esse é um minúsculo carregador de inicialização. O detalhe é que esse aplicativo, o shim, é sempre assinado eletronicamente por uma chave privada de propriedade da Microsoft Corporation. No sítio oficial do projeto EFI, é possível encontrar a justificativa para essa situação: em resumo, a Microsoft (até a presente data) foi a única organização empresarial que aceitou tal encargo.

Passo um: verifique se já existe uma chave pública na base de dados. Como usuário root, executar o seguinte comando:

# mokutil --list-new
MokNew is empty

Passo dois: insira a chave pública na base de dados do aplicativo shim. Ainda como usuário root:

# mokutil --import /var/lib/shim-signed/mok/MOK.der
input password:
input password again:

Passo três: verifique se a chave pública foi efetivamente inserida.

# mokutil --list-new

Observações

  1. neste ponto é necessário reiniciar o Sistema Operacional (pois o aplicativo shim será executado mais uma vez na inicialização).

  2. o aplicativo "shim" apresentará uma tela (rotulada de "Perform MOK management", traduzindo "Realizar gerenciamento de MOK") com quatro opções (deve-se escolher a opção "Enroll MOK" para efetivamente se inserir a chave pública na base de dados).

  3. nas próximas telas, deve-se escolher as opções e selecionar a chave pública a ser inserida.

  4. será solicitada a frase senha que dá direito a usar a chave privada.

Tarefa quatro: assinar eletronicamente o kernel.

Problema: assinar eletronicamente um kernel para o Sistema Operacional "Linux From Scratch".

Passo um: montar a partição onde está instalado o Sistema Operacional "Linux From Scratch". Como usuário root, executar:

# mount -v /dev/sda4 /mnt/lfs
# cd /mnt/lfs/boot
# ls -al
total 11348
drwxr-xr-x  2 root root    4096 jun 19 17:18 .
drwxr-xr-x 20 root root    4096 jun 12 02:12 ..
-rw-r--r--  1 root root  125542 abr 23 02:30 config-5.16.9
-rw-r--r--  1 root root 4944948 abr 23 03:17 System.map-5.16.9
-rw-r--r--  1 root root 6533440 abr 23 03:17 vmlinuz-5.16.9-lfs-11.1

Passo dois: efetivamente assinar eletronicamente o kernel. Como usuário root, executar:

# sbsign --key /var/lib/shim-signed/mok/MOK.priv --cert /var/lib/shim-signed/mok/MOK.pem /mnt/lfs/boot/vmlinuz-5.16.9-lfs-11.1 --output /mnt/lfs/boot/vmlinuz-5.16.9-lfs-11.1.tmp
Enter PEM pass phrase:
Signing Unsigned original image

# mv -v /mnt/lfs/boot/vmlinuz-5.16.9-lfs-11.1.tmp /mnt/lfs/boot/vmlinuz-5.16.9-lfs-11.1

Tarefa cinco: assinar eletronicamente os módulos do kernel.

Problema: assinar eletronicamente os módulos de kernel para o Sistema Operacional "Linux From Scratch".

Passo um: criar um arquivo contendo as seguintes linhas

#!/bin/echo Carregar com o comando "source"
echo -n "Frase senha para a chave privada: "
read -s KBUILD_SIGN_PIN
export KBUILD_SIGN_PIN

Observações

  1. esses comandos são para armazenar (na variável de ambiente KBUILD_SIGN_PIN) a frase senha que dá direito a usar a chave privada confeccionada na Tarefa dois.

  2. se o arquivo for salvo com o nome de teste, então o comando para usá-lo será source teste.

  3. essa variável de ambiente (KBUILD_SIGN_PIN) será lida pelo aplicativo sign-file (do pacote linux-kbuild-5.10).

Passo dois: efetivamente assinar os módulos do kernel. Como usuário root, executar:

cd /mnt/lfs/lib/modules/5.16.920220423-jfeam-/
find . -type f -name "*.ko" -exec /usr/lib/linux-kbuild-5.10/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der {} \;

Referências:



Veja a relação completa dos artigos de Jamenson Ferreira Espindula de Almeida Melo