Remarque :

Modules de noyau de signature à utiliser avec l'initialisation sécurisée UEFI

Ce tutoriel explique comment signer vos propres modules à utiliser avec UEFI Secure Boot sur Oracle Linux avec Unbreakable Enterprise Kernel installé. Le tutoriel explique également comment ajouter votre propre certificat au trousseau de clés de certificat sécurisé du noyau si vous utilisez un noyau UEK R6 avant UEK R6U3 ; et aussi comment utiliser l'utilitaire mokutil pour mettre à jour le shim d'initialisation UEFI avec le certificat de signature.

Avertissement
Ce tutoriel est destiné aux développeurs qui effectuent des tests logiciels. N'utilisez pas les procédures de ce tutoriel sur les systèmes de production pris en charge par Oracle.

Prérequis

Objectifs

A la fin de ce tutoriel, vous pourrez effectuer les opérations suivantes :

Installation des packages requis

  1. Exécutez les commandes suivantes en fonction de votre système Oracle Linux.

    • Oracle Linux 8 :

      sudo dnf update
      sudo dnf group install "Development Tools"
      sudo dnf install kernel-uek kernel-uek-devel keyutils mokutil pesign
      
    • Oracle Linux 7

      sudo yum-config-manager --enable ol7_optional_latest
      sudo yum update
      sudo yum group install "Development Tools"
      sudo yum-config-manager --enable ol7_UEKR6 && yum-config-manager --disable ol7_UEKR5
      
  2. Redémarrez le système.

Création d'un exemple de module de noyau personnalisé

Dans le cadre de ce tutoriel, nous créons et construisons un exemple de module de noyau personnalisé. Dans la plupart des cas, le module est déjà fourni par un fournisseur externe et cette étape n'est pas nécessaire. Le procédé décrit ici est à titre d'illustration.

  1. Créez un répertoire ~/hello.

  2. Créez le fichier ~/hello/hello.c avec les entrées suivantes :

    #include <linux/module.h>  
    #include <linux/kernel.h>  
    #include <linux/init.h>
    
    MODULE_LICENSE("GPL");  
    MODULE_AUTHOR("A.Developer");  
    MODULE_DESCRIPTION("Hello World Linux Kernel Module");
    
    static int __init hello_init(void)
    {  
      printk(KERN_INFO "Hello world!\n");  
      return 0;
    }
    
    static void __exit hello_exit(void)  
    {  
      printk(KERN_INFO "Unloading Hello world.\n");  
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    
  3. Créez le fichier ~/hello/Makefile avec les entrées suivantes :

    obj-m += hello.o
    
    all:  
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    
    clean:  
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
    install:  
      cp hello.ko  /lib/modules/$(shell uname -r)/extra  
      depmod
    
  4. Créez puis installez le module.

    cd ~/hello
    make && sudo make install
    
  5. Testez le module.

    sudo modprobe hello
    
    modprobe: ERROR: could not insert 'hello': Operation not permitted
    

    Si le système s'exécute en mode d'initialisation sécurisée, modprobe échoue car le module n'est pas encore valide.

Création de certificats locaux et signature du module

  1. Créez un fichier de configuration OpenSSL pour créer un certificat de signature local.

    Type :

    cat >>/tmp/x509.conf <<EOF
    [ req ]
    default_bits = 4096
    distinguished_name = req_distinguished_name
    prompt = no
    string_mask = utf8only
    x509_extensions = extensions
    
    [ req_distinguished_name ]
    O = Module Signing Example
    CN = Module Signing Example Key
    emailAddress = first.last@example.com
    
    [ extensions ]
    basicConstraints=critical,CA:FALSE
    keyUsage=digitalSignature
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid
    EOF
    

    Pour les champs O, CN et emailAddress, entrez des valeurs plus appropriées.

  2. Générez une nouvelle paire clé publique/privée en fonction de la nouvelle configuration.

    Notez que le certificat est valable pendant 10 ans (3 650 jours).

    mkdir ~/certs
    cd ~/certs
    openssl req -x509 -new -nodes -utf8 -sha512 -days 3650 -batch -config /tmp/x509.conf -outform DER -out pubkey.der -keyout priv.key
    
    Generating a RSA private key
    ........................................................
    ............................++++
    writing new private key to 'priv.key'
    -----
    
  3. Exportez le certificat au format PEM.

    openssl x509 -inform DER -in pubkey.der -out pubkey.pem
    
  4. Créez une version PKCS#12 du certificat.

    Indiquez le mot de passe d'export lorsque vous y êtes invité.

    openssl pkcs12 -export -inkey priv.key -in pubkey.pem -name cert -out cert.p12
    
    Enter Export Password:
    Verifying - Enter Export Password:
    
  5. Signez le module à l'aide de la clé que vous venez de générer.

    cd ~/certs
    sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha512 priv.key pubkey.der /lib/modules/$(uname -r)/extra/hello.ko
    
  6. A l'aide de la commande modinfo, vérifiez que le module est signé avec la clé que vous avez créée.

    modinfo hello
    
    filename:       /lib/modules/5.4.17-2036.103.3.1.el8uek.x86_64/extra/hello.ko
    description:    Hello World Linux Kernel Module
    author:         A.Developer
    license:        GPL
    srcversion:     D51FB4CF0B86314953EE797
    depends:        
    retpoline:      Y
    name:           hello
    vermagic:       5.4.17-2036.103.3.1.el8uek.x86_64 SMP mod_unload modversions 
    sig_id:         PKCS#7
    signer:         Module Signing Example Key
    sig_key:        AB:2C:E3:AB:87:D9:9C:6A:31:B8:80:20:D4:92:25:F3:9A:26:DC
    sig_hashalgo:   sha512
    signature:      9F:B0:25:CB:14:C1:C7:10:7F:60:1E:E6:66:82:64:58:91:1F:01:A5:
                    D9:03:1B:9C:2D:42:00:45:78:2B:FA:70:F8:C7:3B:1A:A2:42:00:09:
                    33:E0:81:1D:C6:E6:46:A5:FE:8B:9F:8C:3D:4E:A1:3A:05:52:ED:F6:
                    25:F9:88:98:D3:70:78:1D:7E:63:F3:73:C8:C8:14:C2:3A:52:B4:8F: 
                    ...
    

Ajout du certificat au trousseau de clés sécurisé du noyau (UEK R6U2 et versions antérieures)

Remarque :
Vous n'avez pas besoin d'effectuer cette étape si vous exécutez UEK R6U3 ou une version ultérieure. L'implémentation Secure Boot dans UEK R6U3 est mise à jour pour permettre le chargement de modules pour les modules signés avec des clés figurant dans la base de données MOK. Pour les versions UEK R6 antérieures à UEK R6U3, les modules ne peuvent se charger que si les clés avec lesquelles ils sont signés se trouvent dans le trousseau sécurisé intégré du noyau.

  1. Créez une base de données NSS à utiliser avec pesign.

    cd ~/certs
    certutil -d . -N
    
    Enter a password which will be used to encrypt your keys.
    The password should be at least 8 characters long,
    and should contain at least one non-alphabetic character.
    
    Enter new password:
    Re-enter password:
    
  2. Ajoutez la clé PCKS#12 à la base de données.

    cd ~/certs
    pk12util -d . -i cert.p12
    
    Enter Password or Pin for "NSS Certificate DB":
    Enter password for PKCS12 file:
    pk12util: PKCS12 IMPORT SUCCESSFUL
    
  3. Insérez la clé dans bzImage du noyau.

    Remarque : seul un certificat personnalisé supplémentaire peut être ajouté au noyau car la taille compressée de l'image d'initialisation du noyau ne peut pas augmenter.

    cd ~/certs
    sudo /usr/src/kernels/$(uname -r)/scripts/insert-sys-cert -s /boot/System.map-$(uname -r) -z /boot/vmlinuz-$(uname -r) -c pubkey.der
    
    INFO:    Executing: gunzip <vmlinux-ceDv0X >vmlinux-rFFumH
    WARNING: Could not find the symbol table.
    INFO:    sym:    system_extra_cert
    INFO:    addr:   0xffffffff828915d6
    INFO:    size:   8194
    INFO:    offset: 0x1c915d6
    INFO:    sym:    system_extra_cert_used
    INFO:    addr:   0xffffffff828935d8
    INFO:    size:   0
    INFO:    offset: 0x1c935d8
    INFO:    sym:    system_certificate_list_size
    INFO:    addr:   0xffffffff828935e0
    INFO:    size:   0
    INFO:    offset: 0x1c935e0
    INFO:    Inserted the contents of pubkey.der into ffffffff828915d6.
    INFO:    Used 1481 bytes out of 8194 bytes reserved.
    INFO:    Executing: gzip -n -f -9 <vmlinux-rFFumH >vmlinux-5wHA2r
    
  4. Supprimez la signature PE existante et reconnectez le noyau au nouveau en utilisant le mot de passe de base de données NSS que vous avez créé précédemment.

    cd ~/certs
    sudo pesign -u 0 -i /boot/vmlinuz-$(uname -r) --remove-signature -o vmlinuz.unsigned
    sudo pesign -n . -c cert -i vmlinuz.unsigned -o vmlinuz.signed -s
    
    Enter Password or PIN for 'NSS Certificate DB":
    
  5. Copiez de nouveau le noyau signé sur /boot.

    cd ~/certs
    sudo cp -bf vmlinuz.signed /boot/vmlinuz-$(uname -r)
    

Inscription du certificat à la base de données de clés UEFI Secure Boot

Pour les noyaux UEK R6 antérieurs à UEK R6U3, vous devez inscrire la clé utilisée pour signer l'image de noyau dans la base de données MOK. Pour tous les autres noyaux, la clé utilisée pour signer le module lui-même est inscrite dans la base de données. Ces clés peuvent être identiques si vous avez utilisé la même clé pour signer le module et le noyau.

Remarque : pour plus d'informations sur l'utilisation de l'utilitaire mokutil, reportez-vous à https://docs.oracle.com/learn/mokutil-uefi/.

  1. Ajoutez la clé appropriée en tant que clé de propriétaire de machine (MOK) au shim d'initialisation UEFI. La commande mokutil import vous invite à saisir un mot de passe que vous devrez fournir à l'étape suivante.

    sudo mokutil --import pubkey.der
    
    input password:
    input password again:
    
  2. Redémarrez votre machine.

    Lors de la réinitialisation, le SHIM UEFI doit démarrer automatiquement MokManager, qui est utilisé pour ajouter la clé MOK à la base de données de clés d'initialisation sécurisée UEFI.

    1. Appuyez sur une touche pour effectuer la gestion de MOK.
      Veillez à appuyer sur une touche d'ici 10 secondes pour interrompre le processus d'initialisation et ajouter votre touche MOK.
    2. Sélectionnez Inscrire MOK.
    3. Sélectionnez View key 0.
    4. Vérifiez que la clé correspond aux valeurs souhaitées.
    5. Appuyez sur une touche, puis sélectionnez Continuer.
    6. Sélectionnez Oui pour inscrire la clé.
    7. Indiquez le mot de passe utilisé lors de l'importation de la clé à l'aide de mokutil.
    8. Sélectionnez reboot.
  3. Vérifiez que le certificat est installé dans le trousseau sécurisé.

    sudo keyctl show %:.builtin_trusted_keys
    
    Keyring
     892034081 ---lswrv      0     0  keyring: .builtin_trusted_keys
     367808024 ---lswrv      0     0   \_ asymmetric: Oracle CA Server: fbcd3d4d950c6b2b0e01f0a146c5a4e3855ae704
     230958440 ---lswrv      0     0   \_ asymmetric: Module Signing Example Key: a43b4e638874b0656db2bc26216f56c0ac39f72b
     408597579 ---lswrv      0     0   \_ asymmetric: Oracle America, Inc.: Ksplice Kernel Module Signing Key: 09010ebef5545fa7c54b626ef518e077b5b1ee4c
     839574974 ---lswrv      0     0   \_ asymmetric: Oracle Linux Kernel Module Signing Key: 2bb352412969a3653f0eb6021763408ebb9bb5ab
    
  4. Vérifiez que le chargement du module a réussi.

    sudo modprobe hello
    lsmod | grep hello
    hello                  16384  0
    
    dmesg | tail -2
    [  108.848848] hello: loading out-of-tree module taints kernel.
    [  108.849191] Hello world! 
    

Problèmes connus

Les versions de noyau suivantes sur Oracle Linux 7 peuvent rencontrer des problèmes d'acceptation d'un nouveau certificat tout en conservant la même taille compressée (ou inférieure) pour le fichier vmlinuz résultant. Il est recommandé d'effectuer une mise à jour vers la dernière version UEKR6 disponible avant de démarrer ce processus.

Le problème de compression n'est pas observé dans les versions équivalentes de ces noyaux sur Oracle Linux 8.

Informations supplémentaires

Ressources de formation supplémentaires

Explorez d'autres exercices sur docs.oracle.com/learn ou accédez à davantage de contenu d'apprentissage gratuit sur le canal Oracle Learning YouTube. De plus, visitez le site education.oracle.com/learning-explorer pour devenir Oracle Learning Explorer.

Pour consulter la documentation du produit, consultez le centre d'aide Oracle.