Was ist UEFI Secure Boot?
UEFI Secure Boot ist ein Überprüfungsmechanismus, der sicherstellt, dass der von der Firmware gestartete Code vertrauenswürdig ist.
Die ordnungsgemäße, sichere Verwendung von UEFI Secure Boot erfordert, dass jede beim Booten geladene Binärdatei anhand bekannter Schlüssel in der Firmware überprüft wird, die vertrauenswürdige Anbieter und Quellen für die Binärdateien oder vertrauenswürdige spezifische Binärdateien bezeichnen, die über kryptografisches Hashing identifiziert werden können.
Die meiste x86-Hardware wird ab Werk mit Microsoft-Schlüsseln vorgeladen. Das bedeutet, dass wir uns im Allgemeinen darauf verlassen können, dass die Firmware auf diesen Systemen den von Microsoft signierten Binärdateien vertraut, und die Linux-Gemeinschaft verlässt sich stark auf diese Annahme, damit Secure Boot funktioniert. Dies ist das gleiche Verfahren, das beispielsweise von Red Hat und SUSE verwendet wird.
Viele ARM- und andere Architekturen unterstützen ebenfalls UEFI Secure Boot, laden aber möglicherweise keine Schlüssel in die Firmware vor. Auf diesen Architekturen kann es notwendig sein, Boot-Images mit einem Zertifikat neu zu signieren, das vom Eigentümer der Hardware in die Firmware geladen wird.
Initialer Implementierungsplan: Implementierungsplan.
Unterstützte Architekturen
-
amd64: Ein von Microsoft signiertes shim-Binary und ein von Canonical signiertes grub-Binary werden im Ubuntu-Hauptarchiv als shim-signed bzw. grub-efi-amd64-signed bereitgestellt.
-
arm64: Ab 20.04 („focal“) werden ein von Microsoft signiertes shim-Binary und ein von Canonical signiertes grub-Binary im Ubuntu-Hauptarchiv als shim-signed oder grub-efi-arm64-signed bereitgestellt. Es gibt einen GRUB-Bug, der untersucht wird und der behoben werden muss, bevor dies durchgängig funktioniert.
Testen von UEFI Secure Boot
Wenn Sie daran interessiert sind, Secure Boot auf Ihrem System zu testen, lesen Sie die Anleitung hier: UEFI/SecureBoot/Testing.
Wie UEFI Secure Boot unter Ubuntu funktioniert
Unter Ubuntu sind alle vorgefertigten Binärdateien, die als Teil des Boot-Prozesses geladen werden sollen, mit Ausnahme des initrd-Images, mit dem UEFI-Zertifikat von Canonical signiert, das selbst implizit vertrauenswürdig ist, da es in den Shim-Loader eingebettet ist, der wiederum von Microsoft signiert ist.
Auf Architekturen oder Systemen, auf denen vorinstallierte Signierzertifikate von Microsoft nicht verfügbar sind oder nicht in die Firmware geladen werden, können Benutzer die vorhandenen Signaturen auf shim oder grub ersetzen und sie nach Belieben laden, indem sie sie mit ihren eigenen, in die Firmware des Systems importierten Zertifikaten abgleichen.
Wenn das System bootet, lädt die Firmware das Shim-Binary, wie in den BootEntry-Variablen der Firmware angegeben. Ubuntu installiert seinen eigenen BootEntry zum Zeitpunkt der Installation und kann ihn jedes Mal aktualisieren, wenn der GRUB-Bootloader aktualisiert wird. Da die Shim-Binärdatei von Microsoft signiert ist, wird sie von der Firmware validiert und akzeptiert, wenn sie mit bereits in der Firmware vorhandenen Zertifikaten abgeglichen wird. Da das Shim-Binary ein Canonical-Zertifikat sowie seine eigene Vertrauensdatenbank einbettet, können weitere Elemente der Boot-Umgebung nicht nur mit einem der akzeptablen, in der Firmware vorinstallierten Zertifikate, sondern auch mit dem UEFI-Schlüssel von Canonical signiert werden.
Das nächste Element, das von shim geladen wird, ist das Second-Stage-Image. Dies kann eines von zwei Dingen sein: entweder GRUB, wenn das System normal gebootet wird, oder MokManager, wenn eine Schlüsselverwaltung erforderlich ist, wie durch Firmware-Variablen konfiguriert (normalerweise geändert, als das System zuvor lief).
Wenn das System normal gebootet wird, wird die GRUB-Binärdatei (grub*.efi) geladen, und es wird versucht, sie mit allen zuvor bekannten vertrauenswürdigen Quellen zu vergleichen. Die GRUB-Binärdatei für Ubuntu ist mit dem Canonical UEFI-Schlüssel signiert, so dass sie erfolgreich validiert wird und der Bootvorgang fortgesetzt wird.
Wenn der Bootvorgang mit Schlüsselverwaltungsaufgaben fortgesetzt werden soll, wird das MokManager-Binary (mm*.efi) geladen. Diese Binärdatei wird von shim ausdrücklich als vertrauenswürdig eingestuft, indem sie mit einem ephemeren Schlüssel signiert wird, der nur existiert, während die shim-Binärdatei erstellt wird. Dies bedeutet, dass nur die MokManager-Binärdatei, die mit einer bestimmten Shim-Binärdatei erstellt wurde, ausgeführt werden kann, und schränkt die Möglichkeit einer Gefährdung durch die Verwendung kompromittierter Tools ein. MokManager ermöglicht es jedem Benutzer, der sich an der Systemkonsole befindet, Schlüssel zu registrieren, vertrauenswürdige Schlüssel zu entfernen, binäre Hashes zu registrieren und die Secure-Boot-Validierung auf der Shim-Ebene umzuschalten, aber die meisten Aufgaben erfordern die Eingabe eines zuvor festgelegten Passworts, um zu bestätigen, dass der Benutzer an der Konsole tatsächlich die Person ist, die die Änderungen angefordert hat. Solche Passwörter bleiben nur für einen einzigen Durchlauf von shim / MokManager bestehen und werden gelöscht, sobald der Prozess abgeschlossen oder abgebrochen wird. Sobald die Schlüsselverwaltung abgeschlossen ist, wird das System neu gebootet und nicht einfach mit dem Booten fortgesetzt, da die Änderungen in der Schlüsselverwaltung möglicherweise erforderlich sind, um den Bootvorgang erfolgreich abzuschließen.
Wenn das System mit dem Booten fortfährt, lädt der GRUB-Prozess alle erforderlichen Konfigurationen (normalerweise wird die Konfiguration von der ESP (EFI System Partition) geladen, die auf eine andere Konfigurationsdatei auf der Root- oder Boot-Partition verweist), die ihn auf das zu ladende Kernel-Image verweist.
EFI-Anwendungen haben bis zu diesem Punkt vollen Zugriff auf die System-Firmware, einschließlich des Zugriffs auf die Änderung vertrauenswürdiger Firmware-Variablen, der zu ladende Kernel muss auch gegen die Vertrauensdatenbank validiert werden. Offizielle Ubuntu-Kernel, die mit dem Canonical-UEFI-Schlüssel signiert sind, werden erfolgreich validiert, und die Kontrolle wird an den Kernel übergeben. Initrd-Images werden nicht validiert.
Im Fall von inoffiziellen oder von Benutzern erstellten Kerneln müssen zusätzliche Schritte unternommen werden, wenn Benutzer solche Kernel laden und dabei die vollen Fähigkeiten von UEFI Secure Boot beibehalten wollen. Alle Kernel müssen signiert sein, um von GRUB geladen werden zu können, wenn UEFI Secure Boot aktiviert ist. Alternativ können Benutzer die Validierung im Shim deaktivieren, während sie mit aktiviertem Secure Boot auf einem offiziellen Kernel booten, indem sie ’sudo mokutil –disable-validation‘ verwenden, ein Passwort eingeben, wenn sie dazu aufgefordert werden, und neu booten; oder Secure Boot in der Firmware insgesamt deaktivieren.
Bis zu diesem Punkt wird jeder Fehler bei der Validierung eines zu ladenden Images mit einem kritischen Fehler beantwortet, der den Boot-Prozess stoppt. Das System bootet nicht weiter und kann nach einer gewissen Zeit automatisch neu starten, da andere BootEntry-Variablen möglicherweise gültige und vertrauenswürdige Bootpfade enthalten.
Nach dem Laden deaktivieren überprüfte Kernel die Boot-Dienste der Firmware, so dass die Privilegien entfallen und das System effektiv in den Benutzermodus wechselt, in dem der Zugriff auf vertrauenswürdige Variablen auf den reinen Lesezugriff beschränkt ist. In Anbetracht der weitreichenden Berechtigungen, die Kernel-Modulen gewährt werden, muss jedes Modul, das nicht in den Kernel integriert ist, beim Laden ebenfalls validiert werden. Module, die von Canonical erstellt und mit den offiziellen Kerneln ausgeliefert werden, sind mit dem Canonical UEFI-Schlüssel signiert und somit vertrauenswürdig. Bei selbst erstellten Modulen muss der Benutzer die notwendigen Schritte unternehmen, um die Module zu signieren, bevor sie vom Kernel geladen werden können. Dies kann mit Hilfe des Befehls ‚kmodsign‘ erreicht werden.
Unsignierte Module werden vom Kernel einfach abgelehnt. Jeder Versuch, sie mit insmod oder modprobe einzufügen, schlägt mit einer Fehlermeldung fehl.
Da viele Benutzer Module von Drittanbietern benötigen, damit ihre Systeme ordnungsgemäß funktionieren oder damit einige Geräte funktionieren; und dass diese Module von Drittanbietern lokal auf dem System erstellt werden müssen, um in den laufenden Kernel eingepasst zu werden, bietet Ubuntu Werkzeuge, um den Signierungsprozess zu automatisieren und zu vereinfachen.
Wie kann ich eine nicht-automatisierte Signierung von Treibern durchführen?
Einige Projekte können die Verwendung von benutzerdefinierten Kernel-Treibern erfordern, die nicht so eingerichtet sind, dass sie mit DKMS funktionieren. In diesen Fällen sollte man die im shim-signed-Paket enthaltenen Werkzeuge nutzen: das update-secureboot-policy-Skript ist verfügbar, um ein neues MOK zu generieren (wenn keine DKMS-gebauten Module bereits die Generierung eines solchen ausgelöst haben).
Verwenden Sie den folgenden Befehl, um einen vorhandenen Schlüssel in shim zu registrieren:
sudo update-secureboot-policy --enroll-key
Ist kein MOK vorhanden, wird das Skript mit einer entsprechenden Meldung beendet. Wenn der Schlüssel bereits registriert ist, beendet sich das Skript, ohne etwas zu tun. Wenn der Schlüssel vorhanden ist, aber nicht als registriert angezeigt wird, wird der Benutzer aufgefordert, ein Passwort einzugeben, das er nach dem Neustart verwenden kann, damit der Schlüssel registriert werden kann.
Mit dem folgenden Befehl kann man einen neuen MOK erzeugen:
sudo update-secureboot-policy --new-key
Und dann den neu erzeugten Schlüssel in shim mit dem zuvor erwähnten Befehl für diese Aufgabe registrieren.
Kernelmodule können dann mit dem Befehl kmodsign (siehe UEFI/SecureBoot/Signing) als Teil des Erstellungsprozesses signiert werden.
Sicherheitsimplikationen bei der Verwaltung von Machine-Owner-Keys
Der bei der Installation oder beim Upgrade erzeugte MOK ist maschinenspezifisch und wird nur vom Kernel oder Shim zum Signieren von Kernelmodulen zugelassen, indem eine spezifische KeyUsage OID (1.3.6.1.4.1.2312.16.1.2) verwendet wird, die die Einschränkungen des MOK angibt.
Neuere Shim-Versionen enthalten eine Logik, die die Beschränkungen von „module-signing-only“-Schlüsseln berücksichtigt. Diese Schlüssel können in der Firmware in der Vertrauensdatenbank von shim registriert werden, werden aber ignoriert, wenn shim oder GRUB Images zum Laden der Firmware validieren. Shim’s verify() Funktion wird nur erfolgreich Images validieren, die von Schlüsseln signiert wurden, die nicht die „Module-signing only“ (1.3.6.1.4.1.2312.16.1.2) KeyUsage OID enthalten. Die Ubuntu-Kernel verwenden die globale Vertrauensdatenbank (die sowohl die des Shim als auch die der Firmware enthält) und akzeptieren jeden der enthaltenen Schlüssel als Signierschlüssel beim Laden von Kernelmodulen.
Angesichts der Beschränkungen, die dem automatisch generierten MOK auferlegt werden, und der Tatsache, dass Benutzer mit Superuser-Zugang zum System und Zugang zur Systemkonsole, um das Passwort einzugeben, das bei der Registrierung von Schlüsseln erforderlich ist, bereits über einen hochrangigen Zugang zum System verfügen, wird der generierte MOK-Schlüssel im Dateisystem als reguläre Datei im Besitz von root mit Nur-Lese-Berechtigungen aufbewahrt. Dies wird als ausreichend erachtet, um den Zugriff auf den MOK zum Signieren durch böswillige Benutzer oder Skripte einzuschränken, insbesondere angesichts der Tatsache, dass kein MOK auf dem System existiert, es sei denn, es werden Treiber von Drittanbietern benötigt. Dadurch wird die Möglichkeit einer Kompromittierung durch den Missbrauch eines generierten MOK-Schlüssels zum Signieren eines bösartigen Kernel-Moduls eingeschränkt. Dies ist gleichbedeutend mit einer Kompromittierung der Userland-Anwendungen, die bereits mit Superuser-Zugriff auf das System möglich wäre, und die Absicherung dessen liegt außerhalb des Anwendungsbereichs von UEFI Secure Boot.
Bei früheren Systemen wurde die Secure Boot-Validierung möglicherweise im Shim deaktiviert. Als Teil des Upgrade-Prozesses werden diese Systeme migriert, um die Secure Boot-Validierung in shim wieder zu aktivieren und einen neuen MOK-Schlüssel zu registrieren, falls erforderlich.
MOK-Generierungs- und Signierungsprozess
Der Schlüsselgenerierungs- und Signierungsprozess unterscheidet sich geringfügig, je nachdem, ob es sich um eine brandneue Installation oder ein Upgrade eines Systems handelt, auf dem zuvor Ubuntu lief; diese beiden Fälle sind im Folgenden deutlich gekennzeichnet.
In allen Fällen, in denen das System nicht im UEFI-Modus gebootet wird, finden keine speziellen Schritte zur Signierung der Kernelmodule oder zur Schlüsselgenerierung statt.
Wenn Secure Boot deaktiviert ist, erfolgt die MOK-Erzeugung und -Registrierung trotzdem, da der Benutzer Secure Boot später aktivieren kann. Das System sollte in diesem Fall ordnungsgemäß funktionieren.
Der Benutzer installiert Ubuntu auf einem neuen System
Der Benutzer geht durch das Installationsprogramm. Schon bei der Vorbereitung der Installation und nur dann, wenn das System Module von Drittanbietern benötigt, um zu funktionieren, wird der Benutzer aufgefordert, ein Systempasswort einzugeben, das deutlich als erforderlich gekennzeichnet ist, nachdem die Installation abgeschlossen ist, und während das System installiert wird, wird automatisch ein neues MOK ohne weitere Benutzerinteraktion erstellt.
Treiber oder Kernel-Module von Drittanbietern, die vom System benötigt werden, werden bei der Installation des Pakets automatisch erstellt, und der Erstellungsprozess umfasst einen Signierungsschritt. Der Signierschritt verwendet automatisch den zuvor generierten MOK, um das Modul zu signieren, so dass es sofort geladen werden kann, sobald das System neu gestartet und der MOK in die Vertrauensdatenbank des Systems aufgenommen wurde.
Nach Abschluss der Installation und dem Neustart des Systems wird dem Benutzer beim ersten Start das Programm MokManager (Teil des installierten Shim-Loaders) als eine Reihe von Textmodus-Panels präsentiert, die dem Benutzer die Möglichkeit geben, den generierten MOK zu registrieren. Der Benutzer wählt „MOK einschreiben“, bekommt einen Fingerabdruck des einzuschreibenden Zertifikats angezeigt und wird aufgefordert, die Einschreibung zu bestätigen. Nach der Bestätigung wird das neue MOK in die Firmware eingegeben und der Benutzer wird aufgefordert, das System neu zu starten.
Wenn das System neu startet, werden Treiber von Drittanbietern, die von dem soeben registrierten MOK signiert wurden, nach Bedarf geladen.
Der Benutzer aktualisiert ein UEFI-fähiges Ubuntu-System auf eine neue Version, für die das System Treiber von Drittanbietern benötigt
Beim Upgrade werden das Shim-Paket und das von Shim signierte Paket aktualisiert. Die Nachinstallationsaufgaben des shim-signierten Pakets generieren ein neues MOK und fordern den Benutzer zur Eingabe eines Passworts auf, das eindeutig als erforderlich angegeben wird, sobald der Upgrade-Prozess abgeschlossen und das System neu gebootet ist.
Während des Upgrades werden die Kernel-Pakete und Module von Drittanbietern aktualisiert. Module von Drittanbietern werden für die neuen Kernel neu erstellt und ihr Post-Build-Prozess fährt fort, sie automatisch mit dem MOK zu signieren.
Nach der Aktualisierung wird dem Benutzer empfohlen, sein System neu zu starten.
Nach dem Neustart wird dem Benutzer das Programm MokManager (Teil des installierten Shim-Loaders) in Form einer Reihe von Textfeldern präsentiert, die dem Benutzer die Möglichkeit geben, das erzeugte MOK zu registrieren. Der Benutzer wählt „MOK einschreiben“, bekommt einen Fingerabdruck des einzuschreibenden Zertifikats angezeigt und wird aufgefordert, die Einschreibung zu bestätigen. Der Benutzer wird außerdem aufgefordert, die Secure-Boot-Validierung wieder zu aktivieren (falls diese deaktiviert war); auch hier verlangt MokManager eine Bestätigung des Benutzers. Sobald alle Schritte bestätigt sind, wird die Shim-Validierung wieder aktiviert, der neue MOK wird in die Firmware eingegeben und der Benutzer wird aufgefordert, das System neu zu starten.
Wenn das System neu startet, werden Treiber von Drittanbietern, die von dem soeben registrierten MOK signiert sind, nach Bedarf geladen.
In allen Fällen wird, sobald das System mit aktiviertem UEFI Secure Boot und einer aktuellen Version von shim läuft, die Installation eines neuen DKMS-Moduls (Drittanbieter-Treiber) fortgesetzt, um das erstellte Modul mit dem MOK zu signieren. Dies geschieht ohne Benutzerinteraktion, wenn ein gültiger MOK-Schlüssel auf dem System vorhanden ist und bereits registriert zu sein scheint.
Wenn kein MOK vorhanden ist oder der vorhandene MOK nicht registriert ist, wird unmittelbar vor dem Signieren automatisch ein neuer Schlüssel erstellt, und der Benutzer wird aufgefordert, den Schlüssel zu registrieren, indem er ein Kennwort angibt, das beim Neustart erforderlich ist.