AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1546576
Accepted
Nullcaller
Nullcaller
Asked: 2025-04-27 01:08:22 +0800 CST2025-04-27 01:08:22 +0800 CST 2025-04-27 01:08:22 +0800 CST

RPi 5 和 Ubuntu Server 24.04 LTS 上的无头根文件系统加密

  • 772

我想在我的树莓派 5 上加密 Ubuntu Server 24.04 的根文件系统。我没有新树莓派上使用的那种奇怪的 microHDMI 接口的线,所以最好是无头模式。根文件系统位于 SD 卡上,我想使用密钥文件而不是密码进行加密。虽然有这个答案和这个指南,但遗憾的是没有关于如何无头模式操作的说明。

24.04
  • 1 1 个回答
  • 37 Views

1 个回答

  • Voted
  1. Best Answer
    Nullcaller
    2025-04-27T01:08:22+08:002025-04-27T01:08:22+08:00

    我一直在苦苦寻找解决这个问题的方法,直到这个答案提醒了我dropbear-initramfs。这似乎是迄今为止最简单的解决方案。只需在 中安装一个 SSH 服务器即可initramfs。以下是我遵循的步骤,以使它正常工作。

    所有命令都必须以超级用户身份运行,sudo -s以打开 root shell。

    标有█ 的步骤可能需要使用特定于您情况的数据更改命令或文件内容。

    准备initramfs

    1. 将系统安装到 SD 卡上(我使用了 Raspberry Pi Imager),插入树莓派并启动。运行以下命令更新系统:

      apt update
      apt upgrade
      reboot
      
    2. 安装dropbear-initramfs并busybox:

      apt update
      apt install dropbear-initramfs busybox
      
    3. █添加您的 SSH 公钥,/etc/dropbear/initramfs/authorized_keys以便在 SSH 服务器运行后能够访问它。您可以从您的机器上复制密钥:

      cat ~/.ssh/id_rsa.pub
      

      并将其粘贴到 RPi 上的相应文件中:

      vi /etc/dropbear/initramfs/authorized_keys
      
    4. █编辑文件/etc/initramfs-tools/initramfs.conf,使 initramfs 从 DHCP 获取 IP 地址。找到文件末尾,添加:

      IP=::::<hostname>::dhcp:::
      

      替换<hostname>为 Pi 应具有的主机名。

      SSH 可能会因为 Pi 不断更改签名而感到恼火。如果实在不行,可以参考这个答案。

    5. 编辑/etc/initramfs-tools/modules以添加 LUKS 和加密所需的内核模块initramfs。在文件末尾添加以下内容:

      algif_skcipher
      aes_arm64
      aes_ce_blk
      aes_ce_ccm
      aes_ce_cipher
      sha256_arm64
      cbc
      dm-crypt
      
    6. initramfs通过创建/etc/initramfs-tools/hooks/luks_hooks以下内容来添加用于处理文件系统的工具:

      #!/bin/sh -e
      PREREQS=""
      case $1 in
              prereqs) echo "${PREREQS}"; exit 0;;
      esac
      
      . /usr/share/initramfs-tools/hook-functions
      
      copy_exec /sbin/e2fsck /sbin
      copy_exec /sbin/resize2fs /sbin
      copy_exec /sbin/fdisk /sbin
      copy_exec /sbin/cryptsetup /sbin
      

      不要忘记使其可执行:

      chmod +x /etc/initramfs-tools/hooks/luks_hooks
      
    7. 更新initramfs以应用所有这些更改:

      update-initramfs -u
      
    8. █您可以initramfs使用以下命令验证是否具有所有必要的工具和模块。

      lsinitramfs /boot/initrd.img-<...> | grep -P "sbin/(cryptsetup|resize2fs|fdisk|e2fsck)"
      

      它应该打印:

      usr/sbin/cryptsetup
      usr/sbin/e2fsck
      usr/sbin/fdisk
      usr/sbin/resize2fs
      

      和

      lsinitramfs /boot/initrd.img-<...> | grep -P "(algif_skcipher|aes-arm64|sha256-arm64|cbc|dm-crypt)"
      

      应该打印:

      usr/lib/modules/<...>/kernel/arch/arm64/crypto/aes-arm64.ko.zst
      usr/lib/modules/<...>/kernel/arch/arm64/crypto/sha256-arm64.ko.zst
      usr/lib/modules/<...>/kernel/crypto/algif_skcipher.ko.zst
      usr/lib/modules/<...>/kernel/crypto/pcbc.ko.zst
      usr/lib/modules/<...>/kernel/crypto/xcbc.ko.zst
      usr/lib/modules/<...>/kernel/drivers/md/dm-crypt.ko.zst
      

      对我来说,<...>是6.8.0-1020-raspi,我猜是内核版本。不过,您的版本可能有所不同。请注意,在上述所有命令中,请将其替换为您的版本。

    准备启动

    1. 生成用于加密的密钥并将其放置在 中/boot/firmware,因为这是一个可从 轻松访问的位置initramfs:

      apt update
      apt install uuid
      cd /boot/firmware
      dd if=/dev/random bs=512 count=4 of=$(uuid).lek
      
    2. 编辑/etc/fstab以使用我们将在几个步骤中创建的加密卷。将第一行更改为:

      /dev/mapper/rootfs  /   ext4    defaults    0   0
      
    3. 更新initramfs,忽略其可怕的警告:

      update-initramfs -u
      
    4. 编辑/boot/firmware/cmdline.txt:

      • 更改root=LABEL=writable为root=/dev/mapper/rootfs
      • cryptdevice=/dev/mmcblk0p2:rootfs在行尾添加

      break=init有些文章建议你在行尾也添加,但如果你这样做,它会跳转到initramfs两次,第一次是因为无法启动,第二次是因为你需要它。问题是,dropbear 第二次启动不了。所以如果你在无头模式下操作,就不要这么做。

      Ubuntu 桌面版似乎也有splash参数cmdline.txt,应该将其删除,因为启动画面根本无法帮助您完成此操作。

    5. 现在您终于可以重新启动了:

      reboot
      

    rootfs就地加密initramfs

    1. █你的树莓派现在应该已经启动,initramfs并且会通过 DHCP 从路由器获取 IP 地址。如果你不知道这个 IP 地址,可以登录路由器查看。之后,你就可以开始使用 SSH 登录 initramfs 了:

      ssh -i ~/.ssh/id_rsa root@<Pi's IP address>
      

      (如果您的 SSH 私钥存储在其他位置,请务必调整命令)

    2. 进入后initramfs,挂载system-boot分区:

      mkdir -p /mnt/boot
      mount /dev/mmcblk0p1 /mnt/boot
      
    3. 检查并修复rootfs(e2fsck此步骤是必需的):

      e2fsck -f /dev/mmcblk0p2
      
    4. 缩小rootfs以为 LUKS 标头腾出空间:

      resize2fs -M /dev/mmcblk0p2
      
    5. █rootfs使用以下方法进行就地加密cryptsetup reencrypt(这将花费一些时间,具体取决于 SD 卡的大小及其性能等级,对我来说,64 GB 的加密需要 40 分钟):

      cryptsetup reencrypt --new --reduce-device-size=16M --type=luks2 -c aes-xts-plain64 -s 256 -h sha256 --use-urandom --key-file /mnt/boot/<key file name>.lek /dev/mmcblk0p2
      
    6. █加密完成后,解锁加密的rootfs:

      cryptsetup luksOpen --key-file /mnt/boot/<key file name>.lek /dev/mmcblk0p2 rootfs
      
    7. 扩展rootfs以填充整个分区:

      resize2fs /dev/mapper/rootfs
      

      此时,您可以尝试安装rootfs以查看一切是否正常工作:

      mkdir -p /mnt/root
      mount /dev/mapper/rootfs /mnt/root
      cd /mnt/root
      ls -la
      

      如果任何命令的输出不正确,请回溯您的步骤。

    8. █此时,尽管/dev/mapper/rootfs已经存在,但 Pi 不会尝试切换到它。为此,请先重启 Pi:

      reboot -f
      

      然后,无需等待太长时间,按照本节第 1 步的操作进行连接,然后rootfs再次解锁:

      mkdir -p /mnt/boot
      mount /dev/mmcblk0p1 /mnt/boot
      cryptsetup luksOpen --key-file /mnt/boot/<key file name>.lek /dev/mmcblk0p2 rootfs
      

      你应该得到类似的东西

      Connection to <IP> closed by remote host.
      

      解锁后 2-3 秒内rootfs。如果无效,请重试,但要更快。此后,Pi 将启动到rootfs。

    恢复正常启动

    1. 由于 Debian 的 crypttab 实现似乎不支持直接从设备读取密钥文件,您可以使用“keyscript”来执行此操作。创建/lib/cryptsetup/scripts/unlock以下内容:

      #!/bin/sh
      set -e
      if [ ! -e /sdboot ]; then
        mkdir -p /sdboot
        sleep 3
      fi
      if mount /dev/mmcblk0p1 /sdboot >/dev/null; then
        if [ -e /sdboot/$CRYPTTAB_KEY.lek ]; then
          cat /sdboot/$CRYPTTAB_KEY.lek
          umount /sdboot
          exit
        fi
        umount /sdboot
      fi
      /lib/cryptsetup/askpass "Insert key or enter passphrase: "
      

      此脚本将尝试将system-bootSD 卡的分区挂载到 ,/sdboot并使用 传递给它的密钥文件名crypttab在该分区上查找正确的密钥system-boot。然后,它会将文件内容转储到标准输出 (stdout),并将其解释为密钥文件的内容。/sdboot挂载点仅存在于 中initramfs,不会成为 的一部分rootfs。

      不要忘记使其可执行:

      chmod a+x /lib/cryptsetup/scripts/unlock
      
    2. █添加一个条目以在启动时自动/etc/crypttab解锁:rootfs

      rootfs  /dev/mmcblk0p2  <key file name (without the .lek extension)>    luks,initramfs,keyscript=unlock
      
    3. 更新initramfs以应用更改:

      update-initramfs -u
      
    4. 重启测试:

      reboot
      

    此时,您可以根据自己的喜好修改设置。例如,您可能想将密钥文件移动到 U 盘上,并相应地修改脚本。我有一个GitHub Gist,其中包含有关如何操作的详细说明。或者,您可以切换到基于密码的解锁方式,并将密钥作为备份。关键在于,您现在拥有一个可以启动并可以执行任何操作的系统。

    我的建议是,如果您切换到基于 USB 驱动器的解锁,则更改加密密钥(因为如果擦除不当,写入 SD 卡的密钥仍然可以读取),并使用设备 UUID(您可以使用查看它们blkid)而不是/dev/<whatever>样式块设备规范,因为 UUID 不依赖于系统。

    • 0

相关问题

  • 安装 24.04 时出现问题

  • 在 Ubuntu 24.04 中,无法点击最大化应用程序的整个右上角

  • 我有一个关于在 LTS 和基本版本之间下载 Ubuntu 版本的问题

  • 24.04 LTS 文本在悬停之前不会显示

  • 软件精品店无法在Ubuntu 24.04 LTS上启动。

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve