cockpit-project / cockpit

Cockpit is a web-based graphical interface for servers.
http://www.cockpit-project.org/
GNU Lesser General Public License v2.1
10.95k stars 1.1k forks source link

Display boot type information (EFI, BIOS, Secure Boot, etc.) #19368

Open allisonkarlitskaya opened 11 months ago

allisonkarlitskaya commented 11 months ago

Possibly nice feature that would fit in nicely in the "System information" card.

If it's possible to determine it, show a "Boot type" indicator which could be one of:

allisonkarlitskaya commented 11 months ago

It seems like if you read /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c you'll end up with:

garrett commented 11 months ago

GNOME 45, just released, has included more system information and moved most of the system-level stuff to a popup window.

Here's what it looks like (after I moved the window to the side a bit, to show both parts of the information).

Screenshot from 2023-09-21 15-15-10

Is there anything useful in there that we should also include? WDYT?

garrett commented 11 months ago

GNOME also has secure boot shown like this under the privacy > security section:

image

image

allisonkarlitskaya commented 11 months ago

Firmware and kernel versions are potentially interesting. Some of the other things like CPU type we have tucked away inside of "Hardware details" and I think they belong there...

allisonkarlitskaya commented 11 months ago

My security panel also has "Linux Kernel Lockdown" (I guess that means no unsigned modules) and "Encrypted RAM". Those are potentially nice for the "Hardware details" panel as well?

For me I guess the top-level interesting item is "Secure Boot is enabled" and indeed GNOME also gives it top billing with its own large indicator at the top of the page.

jelly commented 11 months ago

Linux Kernel lockdown is a sysctl / kernel option. Feels a bit weird to mix that with "Hardware details".

https://man7.org/linux/man-pages/man7/kernel_lockdown.7.html

leomoty commented 11 months ago

It seems like if you read /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c you'll end up with:

  • 0000000 0006 0000 0001 secure boot enabled
  • 0000000 0006 0000 0000 secure boot disabled
  • file not present: BIOS boot (or non-EFI platform)

Seems pretty easy to achieve indeed:

diff --git a/pkg/systemd/hw-detect.js b/pkg/systemd/hw-detect.js
index 925116def..305b11a9c 100644
--- a/pkg/systemd/hw-detect.js
+++ b/pkg/systemd/hw-detect.js
@@ -120,6 +120,17 @@ function findMemoryDevices(udevdb, info) {
     info.memory = memoryArray;
 }

+async function getBootType() {
+    try {
+        await cockpit.script("test -f /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c");
+    } catch {
+        return "BIOS or Legacy";
+    }
+
+    const result = await cockpit.script("od -j4 --address-radix=n --format=u1 /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c");
+    return `EFI (Secure Boot ${result.trim() == "1" ? "enabled" : "disabled"})`;
+}
+
 export default function detect() {
     const info = { system: {}, pci: [], memory: [] };
     const tasks = [];
@@ -154,6 +165,11 @@ export default function detect() {
                 return true;
             }));

+    tasks.push(getBootType()
+            .then(result => {
+                info.system.boot_type = result;
+            }));
+
     // Fallback if systemd < 248
     if (info.memory.length === 0) {
         tasks.push(machine_info.memory_info()
diff --git a/pkg/systemd/hwinfo.jsx b/pkg/systemd/hwinfo.jsx
index 53e971390..f0dc022a7 100644
--- a/pkg/systemd/hwinfo.jsx
+++ b/pkg/systemd/hwinfo.jsx
@@ -111,6 +111,10 @@ class SystemInfo extends React.Component {
                                 <DescriptionListDescription>{ bios_date ? timeformat.date(bios_date) : info.bios_date }</DescriptionListDescription>
                             </DescriptionListGroup>
                         </> }
+                        <DescriptionListGroup>
+                            <DescriptionListTerm>{ _("Boot type") }</DescriptionListTerm>
+                            <DescriptionListDescription>{ info.boot_type }</DescriptionListDescription>
+                        </DescriptionListGroup>
                         { info.nproc !== undefined && <>
                             <DescriptionListGroup>
                                 <DescriptionListTerm>{ _("CPU") }</DescriptionListTerm>
allisonkarlitskaya commented 11 months ago

Seems pretty easy to achieve indeed:

Cool!

I would have imagined using a single

cockpit.file('/sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c', {binary: true}).read()

though.

leomoty commented 11 months ago

Yep I never noticed that extra flag, that works :)

leomoty commented 11 months ago

@allisonkarlitskaya the int test TestSystemInfo.testHardwareInfo is not working by default in my end, am I missing something? Mismatched values: QEMU => Red Hat KVM Standard PC => KVM

ashutosh7i commented 9 months ago

Hello @allisonkarlitskaya can i work on this issue, i am new to this project looking for good first issues.

jelly commented 9 months ago

There is already a Pull Request open for this issue, so I would suggest looking into a different issue.

monkCommits commented 9 months ago

Is this issue still open? Can I contribute?

Conan-Kudo commented 7 months ago

We need more than that... We also need to know if we're using a "fake-UEFI" like U-Boot (on ARM and RISC-V).