收起左侧

飞牛OS启用安全启动支持

0
回复
44
查看
[ 复制链接 ]

1

主题

0

回帖

0

牛值

江湖小虾

写在前面:

  1. 请注意备份重要数据,以免操作发生意外!
  2. 该过程经过本人在实机上测试通过。
  3. 建议在全新安装飞牛OS后就执行该操作,已有的系统(尤其是已经安装并正在使用某些DKMS驱动时)增加安全启动支持可能会出现异常。
  4. 虽然我对将来可能的更新系统、安装其他DKMS驱动时的操作做了兜底,以尽可能保证安全启动在这些操作后一直可用,但仍不能十分确保一些非常规的操作会破坏信任链,导致安全启动失效,从而无法启动机器。如果出现这种情况,可以尝试关闭安全启动来恢复。

部署指南


一、理解信任链

UEFI 固件(内置 Microsoft 证书)
        ↓ 验证(Microsoft 已签名)
    shimx64.efi          ← 微软背书,信任链入口
        ↓ 验证(MOK 数据库)
    grubx64.efi          ← 用你的 MOK 签名
        ↓ 验证(MOK 数据库)
    vmlinuz-*            ← 用你的 MOK 签名
        ↓ 验证(MOK 数据库)
    *.ko 内核模块         ← 用你的 MOK 签名

二、安装必要工具

sudo apt update
sudo apt install shim-signed grub-efi-amd64-signed sbsigntool mokutil dkms

三、部署 shim 到 ESP

fnOS 虽然安装了 shim 软件包,但没有自动部署到 EFI 系统分区,需要手动复制:

# 部署 shim 和 MokManager
sudo cp /usr/lib/shim/shimx64.efi.signed /boot/efi/EFI/debian/shimx64.efi
sudo cp /usr/lib/shim/mmx64.efi.signed   /boot/efi/EFI/debian/mmx64.efi

# 更新 fallback 引导(部分固件只认 BOOTX64.EFI)
sudo cp /usr/lib/shim/shimx64.efi.signed /boot/efi/EFI/BOOT/BOOTX64.EFI

# 确认文件到位
ls -lh /boot/efi/EFI/debian/
ls -lh /boot/efi/EFI/BOOT/

四、修正 EFI 引导项指向 shim

# 删除原有引导项(原来直接指向** GRUB)
sudo efibootmgr --bootnum $(efibootmgr -v | grep -i "debian" | grep -oP 'Boot\K[0-9A-F]+') --delete-bootnum

# 创建新引导项指向 shimx64.efi
# ESP 在 /dev/nvme0n1p1,所以 --disk /dev/nvme0n1 --part 1
sudo efibootmgr \
    --create \
    --disk /dev/nvme0n1 \
    --part 1 \
    --label "fnOS Secure Boot" \
    --loader "\\EFI\\debian\\shimx64.efi"

# 确认 BootOrder 第一项指向新引导项
sudo efibootmgr -v

预期结果:

BootOrder: 0004,...
Boot0004* fnOS Secure Boot  .../File(\EFI\debian\shimx64.efi)

五、生成 MOK 密钥对

sudo mkdir -p /var/lib/shim-signed/mok
sudo chmod 700 /var/lib/shim-signed/mok

# 生成 RSA-4096 私钥 + 自签名证书
sudo openssl req -newkey rsa:4096 -nodes \
    -keyout /var/lib/shim-signed/mok/MOK.key \
    -new -x509 -sha256 -days 3650 \
    -subj "/CN=fnOS Secure Boot MOK/" \
    -out /var/lib/shim-signed/mok/MOK.crt

# 转换为 DER 格式(UEFI 固件需要)
sudo openssl x509 \
    -in /var/lib/shim-signed/mok/MOK.crt \
    -outform DER \
    -out /var/lib/shim-signed/mok/MOK.cer

# 锁定私钥权限
sudo chmod 600 /var/lib/shim-signed/mok/MOK.key

# 确认三个文件都在
sudo ls -lh /var/lib/shim-signed/mok/

六、对内核和 GRUB 签名

重启回系统后:

KVER=$(uname -r)
MOK_KEY="/var/lib/shim-signed/mok/MOK.key"
MOK_CERT="/var/lib/shim-signed/mok/MOK.crt"

# 签名内核
sudo sbsign --key "$MOK_KEY" --cert "$MOK_CERT" \
    --output /boot/vmlinuz-${KVER}.signed \
    /boot/vmlinuz-${KVER}
sudo mv /boot/vmlinuz-${KVER}.signed /boot/vmlinuz-${KVER}

# 签名 GRUB
sudo sbsign --key "$MOK_KEY" --cert "$MOK_CERT" \
    --output /boot/efi/EFI/debian/grubx64.efi.signed \
    /boot/efi/EFI/debian/grubx64.efi
sudo mv /boot/efi/EFI/debian/grubx64.efi.signed \
        /boot/efi/EFI/debian/grubx64.efi

# 验证签名
sudo sbverify --cert "$MOK_CERT" /boot/vmlinuz-${KVER} && echo "✓ 内核签名 OK"
sudo sbverify --cert "$MOK_CERT" /boot/efi/EFI/debian/grubx64.efi && echo "✓ GRUB 签名 OK"

七、部署自动签名脚本

确保 fnOS 升级内核或 GRUB 后自动重新签名,无需人工干预:

sudo nano /etc/kernel/postinst.d/zz-fnos-secure-boot
#!/bin/bash
# /etc/kernel/postinst.d/zz-fnos-secure-boot
# 内核升级、GRUB 更新后自动签名
set -euo pipefail

MOK_KEY="/var/lib/shim-signed/mok/MOK.key"
MOK_CERT="/var/lib/shim-signed/mok/MOK.crt"
LOG="/var/log/secure-boot-sign.log"
GRUB_EFI="/boot/efi/EFI/debian/grubx64.efi"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }

sign_if_unsigned() {
    local TARGET="$1"
    local LABEL="$2"
    if sbverify --cert "$MOK_CERT" "$TARGET" &>/dev/null; then
        log "✓ ${LABEL} 已有有效签名,跳过"
    else
        log "签名 ${LABEL}..."
        sbsign --key "$MOK_KEY" --cert "$MOK_CERT" \
               --output "${TARGET}.signed" "$TARGET" \
            && mv "${TARGET}.signed" "$TARGET" \
            && log "✓ ${LABEL} 签名成功" \
            || { log "ERROR: ${LABEL} 签名失败"; rm -f "${TARGET}.signed"; return 1; }
    fi
}

# 签名新内核
KERNEL_VERSION="${1:-}"
if [[ -n "$KERNEL_VERSION" && -f "/boot/vmlinuz-${KERNEL_VERSION}" ]]; then
    sign_if_unsigned "/boot/vmlinuz-${KERNEL_VERSION}" "内核 ${KERNEL_VERSION}"
fi

# 检查并签名 GRUB(防止 fnOS 更新覆盖)
[[ -f "$GRUB_EFI" ]] && sign_if_unsigned "$GRUB_EFI" "grubx64.efi"

# 同步 BOOTX64.EFI 保持与 shim 一致
SHIM_SRC="/usr/lib/shim/shimx64.efi.signed"
SHIM_DST="/boot/efi/EFI/BOOT/BOOTX64.EFI"
if [[ -f "$SHIM_SRC" ]] && ! diff -q "$SHIM_SRC" "$SHIM_DST" &>/dev/null; then
    cp "$SHIM_SRC" "$SHIM_DST"
    log "✓ BOOTX64.EFI 已同步更新"
fi
sudo chmod +x /etc/kernel/postinst.d/zz-fnos-secure-boot

APT 层兜底 hook​,覆盖 fnOS 非标准更新路径:

sudo tee /etc/apt/apt.conf.d/99-secure-boot-sign > /dev/null << 'EOF'
DPkg::Post-Invoke {
    "/etc/kernel/postinst.d/zz-fnos-secure-boot '' 2>&1 | tee -a /var/log/secure-boot-sign.log";
};
EOF

八、配置 DKMS 模块自动签名

sudo tee /etc/dkms/sign_helper.sh > /dev/null << 'EOF'
#!/bin/bash
# DKMS 编译后自动签名内核模块
KERNEL_VER="$1"
MODULE_PATH="$2"
MOK_KEY="/var/lib/shim-signed/mok/MOK.key"
MOK_CERT="/var/lib/shim-signed/mok/MOK.crt"
LOG="/var/log/secure-boot-sign.log"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] DKMS: $*" >> "$LOG"; }

SIGN_FILE="/lib/modules/${KERNEL_VER}/build/scripts/sign-file"
if [[ -x "$SIGN_FILE" ]]; then
    "$SIGN_FILE" sha256 "$MOK_KEY" "$MOK_CERT" "$MODULE_PATH" \
        && log "✓ 模块签名成功: $(basename $MODULE_PATH)"
else
    sbsign --key "$MOK_KEY" --cert "$MOK_CERT" \
           --output "${MODULE_PATH}.signed" "$MODULE_PATH" \
        && mv "${MODULE_PATH}.signed" "$MODULE_PATH" \
        && log "✓ 模块签名成功(sbsign): $(basename $MODULE_PATH)"
fi
EOF

sudo chmod +x /etc/dkms/sign_helper.sh

# 启用 DKMS 全局签名
echo 'sign_tool="/etc/dkms/sign_helper.sh"' | sudo tee -a /etc/dkms/framework.conf

如果系统中已经安装了某些DKMS驱动(如i915-sriov-dkms),此时请卸载重新安装这些驱动,以触发签名操作,否则这些驱动可能无法使用。


九、将证书注册到 UEFI NVRAM

# 写入待确认队列(需要设置一个临时密码,重启时用一次)
sudo mokutil --import /var/lib/shim-signed/mok/MOK.cer

重启,进入 UEFI,开启安全启动,保存退出,再次重启后在蓝色 MokManager 界面操作:

Enroll MOK
  → View key 0(确认显示 CN=fnOS Secure Boot MOK)
  → Continue
  → 输入刚才设置的临时密码
  → Reboot

启动后验证:

# 验证安全启动已激活
sudo mokutil --sb-state
# 期望输出:SecureBoot enabled

# 验证内核认可安全启动
sudo dmesg | grep -i "secure boot"

# 查看已注册证书
sudo mokutil --list-enrolled | grep "fnOS"

# 查看签名日志
sudo tail -20 /var/log/secure-boot-sign.log

收藏
送赞
分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则