4

linux迁移和全盘加密

 3 years ago
source link: http://blog.shell909090.org/blog/archives/2881/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

linux迁移和全盘加密

calendar

Dec 16, 2021

clock

1 min read

迁移挺容易的。启一个live系统。把原始系统照样子mount好,把目标盘分区分好,照着你想的样子mount起来。然后对拷数据就行。我踩的一个坑是忘了清理.cache下面各种文件,结果这里复制了好久,我差点以为死机了。Ctrl+C断下来,干掉.cache后速度就快多了。等全部复制好了。umount掉原始系统,然后chroot到新系统里面去,加上以下四个文件系统。[1](其实应该是两个在chroot前做,两个在chroot后做)

$ sudo mount --bind /dev /mnt/dev
$ sudo mount --bind /run /mnt/run
$ sudo chroot /mnt/
$ sudo mount --types=proc proc /proc
$ sudo mount --types=sysfs sys /sys

然后你就可以在目标系统里跑grub系列指令了。grub-installupdate-grub2一下。整个迁移就完事了。

其实grub的重点压根不在install上,而在于引导链条的工作机制。以我这种情况来说,我建议别犹豫,直接上UEFI。让你感觉到无比的轻松。

EFI的引导机制是从磁盘上的EFI分区开始的。当然,你的分区表需要是GPT格式的。EFI分区使用fat32文件格式,里面会存放N个代码文件。以前主板不认识文件系统,所以只能取磁盘第一个分区加载到7C00的方式来引导。因此通行做法是在这个扇区里放一个启动管理器,由管理器加载系统。现在BIOS可以认识文件系统了,因此完全没必要这么干。一个盘上有两个系统的话,就在EFI分区里放两个启动代码,再在BIOS里写两个引导表项。启动的时候你选哪个表项,BIOS就会读取对应的文件来继续引导。如果你有多个盘,每个盘又有多个系统,也可以这么干,只是会形成多个启动表项。所以引导管理就变得非常简单。

对于这样一种结构,我有以下建议:

  1. 基础系统不要跨设备。什么意思呢?以linux为例,你的root和boot最好在一个物理硬盘上,EFI也就安装在这个物理盘上。为什么呢?因为如果这三个跨了多个盘,任意一个盘的丢失都会导致系统挂掉。这等于把问题放大了一倍。如果你做了lvm和分区镜像。也请确保不是任意一个盘丢失你的系统就无法启动了。至于后续mount的各种分区,那到无所谓。反正你有一个基础的系统了,很多问题比较容易修复。
  2. 如果你有多个系统,最好的办法是一个系统一块硬盘。最多是每个盘切出一块来,给对方系统作为数据盘。这个方案同时适配传统引导和EFI引导。这么做的话,每个系统都认为自己独占了硬盘。他的分区结构之类的,是接近最简单设计的。
  3. 主系统最好用SSD。应用程序和主系统的读取频率高,写入频率低,但是对速率的影响很明显。因此我建议你把系统放SSD。数据盘反倒是用不用SSD自己斟酌。
  4. 但是如果你接受了建议3,那么在多数情况下,你就不大会接受建议2了。因为你不大会买两块SSD,一个系统一块。多半就是两个系统合用一个SSD,然后看要不要上HD了。这种情况下,请保证存储空间是够的。一个系统请最少保留不少于500G的存储空间。当然,Linux其实有个4G存储就能玩的很欢快了。500G是保证你在机器上开虚拟机/docker,也能流畅执行无需腾挪。Windows的系统就要保留100G。打游戏的话,500G只多不少。所以SSD要玩双系统,最低就是1T起。现在价格,600上下吧,不算太贵。你的时间比这点空间费用值钱。

然后我们说回引导链条。对于EFI,我们一般会用grub-efi-amd64。这个模块装到EFI上的过程大约是,grub-install把EFI有关的文件都复制到/boot/efi/下面去。所以你首先需要把磁盘的对应EFI分区挂载到这里。然后grub-install会写BIOS的表项,产生一项指向那个位置的项目。你可以用efibootmgr -v查看。

随后,grug-install会更新efi下面的grub.cfg配置。里面有一个search.fs_uuid uuid root。这个指向boot或者root,用来指明efi模块被引导之后,接着读哪个盘。请检查这是不是你想要的boot/root。如果是的话,下面的配置会驱动它去读grub/grub.cfg文件,来进入grub stage 2。

grub stage 2的主要配置很复杂。Debian的配置其实是从系统里生成的。主要的生成配置在/etc/default/grub。一般你不需要改动这个文件。但是你需要看一下生成出来的/boot/grub/grub.cfg文件对不对。最主要就是search后面跟的uuid,是不是boot的uuid。如果是的话,grub2就能找到kernel。然后再看kernel启动参数后面的root参数,uuid是不是root。

如果都没问题的话,你开机应该能进入系统了。

这一圈核对对一般系统是没必要的。一般系统没这个烦恼。但如果是系统迁移,原系统又没有umount掉就开始装新系统的grub。一个搞不好哪里的uuid就指向了原来的。然后就怎么引导就是回到老系统上去。此时就要沿着引导链条排查。

最后我们要说到全盘加密的设计实现。全盘加密的困难处是需要先加载kernel才能解密全盘。但是kernel又在盘里面。所以完整的全盘加密需要grub支持luks。

我没搞那么极端。我分出来一个/boot分区未加密,这样就不需要grub支持luks了。当然,原则上来说,这样攻击者可以插入恶意代码来获得我的密码。例如替换掉我的kernel,插入他的恶意代码。但是EFI方案的问题之一就是,EFI上面的引导代码本身就是可被攻击的。攻击EFI引导代码和攻击kernel没有区别(除了会稍微麻烦一点)。要防御这个需要构成可信引导链条。要构成可信链条,需要EFI验证引导代码被签署,引导代码验证kernel被签署,etc。但是linux本身就不鸟这个思路,因为没一家BIOS接受grub的签署。大家一般也就是支持微软的签署,苹果自己支持自己的签署。所以,这东西没有任何开放意义,只能在微软自家里面用。用Linux的话就别被人近身吧。就这样。

kernel这层呢,需要安装cryptsetup-initramfs。这个工具会把/etc/crypttab这个文件打包到initrd.img里去。这个文件最新的版本不是很好解开。你需要先下载binwalk这个工具,然后查到里面的gzip数据块。再用cpio这个工具解开这个数据块[2]。大致指令是。

binwalk initrd.img-5.10.0-9-amd64
mkdir initrd
cd initrd
dd if=../initrd.img-5.10.0-9-amd64 bs=N skip=1 | gunzip | cpio -idmv

然后你就能看到crypttab这个文件的存在。

这个文件要包括几个内容。target name, source device, key file, options。这个文件的目地其实是驱动cryptsetup来干活。精确的说就是cryptsetup luksOpen <source device> <target name>,后面可以跟key file或options。注意这个写法现在应当写作cryptsetup open --type luks <source device> <target name>。在cryptsetup干完之后,会产生一个/dev/mapper/<target name>的设备文件。随后你就可以在/etc/fstab里面随便mount这个文件了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK