内核 4.15.0-34-generic 上的 Ubuntu 18.04 启动至 BusyBox

jim*_*bob 4 encryption boot kernel luks 18.04

该机器全新安装了 Ubuntu 18.04.1,并在安装过程中使用了 LVM 和 LUKS。该机器在内核 4.15.0-33-generic 上运行良好。

内核从 4.15.0-33 升级到 4.15.0-34-generic。内核更新后,不再提示输入 LUKS 密码并直接启动至 BusyBox v1.27.2

当从旧内核启动时,它会像平常一样提示 LUKS,并且机器能够正常启动。问题出在从较新的内核启动时。

我尝试从 18.04 的 liveCD 运行 fsck。我先解锁驱动器然后运行

fsck -f /deb/sda3
Run Code Online (Sandbox Code Playgroud)

然而我只得到

fsck from util-linux 2.31.1
Run Code Online (Sandbox Code Playgroud)

没有别的。

有我可以运行的修复程序吗?

小智 6

问题是它/sbin/cryptsetup不在 initramfs 文件中/boot/initrd.img-4.15.0-36-generic

您需要添加CRYPTSETUP=y进去/etc/cryptsetup-initramfs/conf-hook。您还需要initramfs在 中添加该选项/etc/crypttab。然后,你必须运行update-initramfs,这就解决了这个问题。

详细解决方案:

  1. 在另一台 Ubuntu 机器上,使用“Startup Disk Creator”创建可启动的 Ubuntu 18.04 USB 驱动器
  2. 将此 USB 驱动器插入启动至 BusyBox 的计算机的 USB 端口
  3. 当实时 USB Ubuntu 准备就绪时,连接到互联网(WiFi 或有线)

  4. 打开终端

    ubuntu@ubuntu:~$ sudo su
    
    Run Code Online (Sandbox Code Playgroud)
  5. 找到加密的块设备。

    root@ubuntu:~# blkid|grep LUKS
    /dev/nvme0n1p3: UUID="4b206e76-1531-48ae-95be-ae0ed7a244c1" TYPE="crypto_LUKS" PARTUUID="21db499d-b87b-41c6-864f-04d1531cb083"
    
    Run Code Online (Sandbox Code Playgroud)
  6. 解密设备

    root@ubuntu:~# cryptsetup open UUID="4b206e76-1531-48ae-95be-ae0ed7a244c1" nvme0n1p3_crypt
    Enter passphrase for /dev/disk/by-uuid/4b206e76-1531-48ae-95be-ae0ed7a244c1: 
    
    Run Code Online (Sandbox Code Playgroud)
  7. 列出映射的设备。control是用于向设备映射器发送命令的文件。nvme0n1p3_crypt是解密后的设备。ubuntu--vg-root是LVM卷组中的一个LVM逻辑卷ubuntu-vg

    root@ubuntu:~# ls /dev/mapper/*
    /dev/mapper/control  /dev/mapper/ubuntu--vg-root  /dev/mapper/nvme0n1p3_crypt
    
    Run Code Online (Sandbox Code Playgroud)
  8. 创建挂载点。这是我们将挂载无法启动的系统的 / 的位置。

    root@ubuntu:~# mkdir -p /mnt/ubuntu-root
    
    Run Code Online (Sandbox Code Playgroud)
  9. 挂载根逻辑卷

    root@ubuntu:~# mount /dev/mapper/ubuntu--vg-root /mnt/ubuntu-root/
    
    Run Code Online (Sandbox Code Playgroud)
  10. 挂载伪文件系统

    root@ubuntu:~# mount -o bind /sys /mnt/ubuntu-root/sys
    root@ubuntu:~# mount -o bind /proc /mnt/ubuntu-root/proc
    root@ubuntu:~# mount -o bind /dev /mnt/ubuntu-root/dev
    
    Run Code Online (Sandbox Code Playgroud)
  11. 复制 DNS 信息

    root@ubuntu:~# cp /etc/resolv.conf /mnt/ubuntu-root/etc/
    
    Run Code Online (Sandbox Code Playgroud)
  12. 更改根目录

    root@ubuntu:~# chroot /mnt/ubuntu-root/
    
    Run Code Online (Sandbox Code Playgroud)
  13. Mount /boot,其中包含 initramfs 文件。该分区未加密。

    root@ubuntu:/# mount /boot/
    
    Run Code Online (Sandbox Code Playgroud)
  14. 安装binwalk(查看init ram文件系统的内容)

    root@ubuntu:~# apt update
    root@ubuntu:~# apt install binwalk
    
    Run Code Online (Sandbox Code Playgroud)
  15. 查找 gzip 压缩的 initramfs 内容的偏移量

    root@ubuntu:~# binwalk /boot/initrd.img-4.15.0-36-generic | grep gzip
    1605632       0x188000        gzip compressed data, from Unix, last modified: 2018-10-18 13:00:32
    
    Run Code Online (Sandbox Code Playgroud)
  16. 问题是 initramfs 文件系统不包含 cryptsetup。所以,这就是为什么没有 LUKS 密码提示的原因。

    root@ubuntu:/# cd /root/
    root@ubuntu:~# mkdir initramfs-4.15.0-36-generic
    root@ubuntu:~# cd initramfs-4.15.0-36-generic
    root@ubuntu:~/initramfs-4.15.0-36-generic# dd if=/boot/initrd.img-4.15.0-36-generic bs=1605632 skip=1 | gunzip | cpio -i
    root@ubuntu:~/initramfs-4.15.0-36-generic# ls sbin/cryptsetup
    ls: cannot access 'sbin/cryptsetup': No such file or directory
    
    Run Code Online (Sandbox Code Playgroud)
  17. 要在启动时解密 root,initramfs 需要包含:

    sbin/cryptsetup
    lib/modules/4.15.0-36-generic/kernel/drivers/md/dm-crypt.ko
    
    Run Code Online (Sandbox Code Playgroud)
  18. initramfs选项添加到/etc/crypttab

    root@ubuntu:/# cat /etc/crypttab 
    nvme0n1p3_crypt UUID=4b206e76-1531-48ae-95be-ae0ed7a244c1 none luks,discard,initramfs
    
    Run Code Online (Sandbox Code Playgroud)
  19. 加入CRYPTSETUP=y/etc/cryptsetup-initramfs/conf-hook

  20. 跑步update-initramfs

    root@ubuntu:~# update-initramfs -k 4.15.0-36-generic -c -v &> update-initramfs-4.15.0-36-generic.cryptsetup.log
    
    Run Code Online (Sandbox Code Playgroud)
  21. 现在,我们cryptsetup在 initramfs 和 Linux 内核模块中dm-crypt.ko也有了:

    root@ubuntu:~# grep /sbin/cryptsetup update-initramfs-4.15.0-36-generic.cryptsetup.log
    Adding binary /sbin/cryptsetup
    
    root@ubuntu:~# grep dm-crypt.ko update-initramfs-4.15.0-36-generic.cryptsetup.log
    Adding module /lib/modules/4.15.0-36-generic/kernel/drivers/md/dm-crypt.ko
    
    Run Code Online (Sandbox Code Playgroud)
  22. 现在,运行 update-initramfs,不带 -c (新)和 -v (详细):

    root@ubuntu:~# update-initramfs -k 4.15.0-36-generic -u
    
    Run Code Online (Sandbox Code Playgroud)
  23. 验证 initramfs 是否确实正确

    root@ubuntu:~# binwalk /boot/initrd.img-4.15.0-36-generic | grep gzip
    1605632       0x188000        gzip compressed data, from Unix, last modified: 2018-10-18 14:26:29
    
    root@ubuntu:~# dd if=/boot/initrd.img-4.15.0-36-generic bs=1605632 skip=1 2> /dev/null | gunzip | cpio -t 2> /dev/null |grep sbin/crypt 
    sbin/cryptsetup
    
    root@ubuntu:~# dd if=/boot/initrd.img-4.15.0-36-generic bs=1605632 skip=1 2> /dev/null | gunzip | cpio -t 2> /dev/null |grep dm-crypt.ko
    lib/modules/4.15.0-36-generic/kernel/drivers/md/dm-crypt.ko
    
    Run Code Online (Sandbox Code Playgroud)
  24. 现在,重新启动。