在纯 ZFS 安装 Gentoo 并进行全盘加密

本文主要介绍在纯 ZFS 安装 Gentoo,并完成基本设置。

由于使用 LUKS 全盘加密的情况下,内核必须处于未加密的分区,否则无法启动,因此,需要把 /boot 单独分出来。如果觉得这么做不够安全,可以把 /boot 放在 USB 闪存设备,开机插入闪存启动系统,这不在本文讨论之列。

安装介质:
带有 ZFS 和 LUKS 模块的 LiveCD,本文以 Gentoo LiveDVD 2012.1 为例,安装的是 64 位系统。

磁盘规划:
整个系统装到 /dev/sdb,并采用 GPT。

以下是安装步骤:

首先安装 gdisk 这个分区工具

# emerge -av gptfdisk

/dev/sdb 创建分区(boot)

Command: n
Partition Number:(回车) 
First sector: (回车)
Last sector: +512M
Hex Code: (回车)

/dev/sdb 创建分区(Bios Boot Partition,如果打算采用 Grub2 作为引导管理器,此分区必须要,这里我们采用 extlinux,因此不需要此分区)

Command: n
Partition Number:(回车)
First sector:(回车)
Last sector: +1M
Hex Code: EF02

/dev/sdb 创建分区(ZFS,稍后对此分区加密)

Command: n
Partition Number:(回车)
First sector:(回车)
Last sector:(回车)
Hex Code: bf01
Command: p
Disk /dev/sdb: 1953525168 sectors, 931.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): C0C1E56A-B24F-492F-95DB-2E227676F228
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1953525134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number  Start (sector)    End (sector)  Size        Code   Name
1       2048              514047        512.0 MiB   8300   Linux filesystem
2       514048            1953525134    931.3 GiB   BF01   Solaris /usr & Mac ZFS

/boot 进行格式化

# mkfs.ext4 /dev/sdb1

对刚才创建的 /dev/sdb2 进行加密(命令输入以后根据提示自己进行)

# cryptsetup -c aes-xts-plain64 luksFormat /dev/sdb2
# cryptsetup luksOpen /dev/sdb2 cryptroot

创建 zpool

# zpool create -f -o ashift=12 -o cachefile= -O compression=on -m none -R /mnt/gentoo rpool /dev/mapper/cryptroot

创建 ZFS 数据集(根据需要自己增减)

# zfs create -o mountpoint=none rpool/ROOT
# zfs create -o mountpoint=/ rpool/ROOT/gentoo
# zfs create -o mountpoint=/opt rpool/ROOT/opt
# zfs create -o mountpoint=/var rpool/ROOT/var
# zfs create -o mountpoint=/home rpool/HOME
# zfs create -o mountpoint=none rpool/GENTOO
# zfs create -o mountpoint=/usr/src rpool/GENTOO/src
# zfs create -o mountpoint=/var/tmp/ccache rpool/GENTOO/ccache
# zfs create -o mountpoint=/usr/portage -o compression=off rpool/GENTOO/portage 
# zfs create -o mountpoint=/usr/portage/distfiles -o compression=off rpool/GENTOO/distfiles
# zfs create -o mountpoint=/usr/portage/packages -o compression=off rpool/GENTOO/packages

创建 swap 数据集(按照自己需要进行大小规划,一般等同于物理内存数值)

# zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 12G rpool/swap

格式化并启用 swap

# mkswap -f /dev/zvol/rpool/swap
# swapon /dev/zvol/rpool/swap

确认 zpool 以及 ZFS 已经正确创建

# zpool status
# zfs list

把 zpool.cache 复制到目标分区

# mkdir -p /mnt/gentoo/etc/zfs
# cp /etc/zfs/zpool.cache /mnt/gentoo/etc/zfs/

创建空的 mtab 文件

# touch /mnt/gentoo/etc/mtab

安装 Gentoo 的 stage3

# cd /mnt/gentoo
# wget ftp://gentoo.osuosl.org/pub/gentoo/releases/amd64/current-stage3/stage3-amd64-*.tar.bz2
# tar xJvpf stage3-amd64-*.tar.bz2 -C /mnt/gentoo

chroot 进入 Gentoo 环境

# cd /mnt/gentoo

- 挂载 /boot 分区
# mount /dev/sdb1 /mnt/gentoo/boot

- 挂载 /dev、/proc 以及 /sys
# for i in proc dev sys; do mount --bind /$i ./$i; done

- 复制宿主的 resolve.conf
# cp /etc/resolv.conf etc/

- chroot进入新的环境
# env -i HOME=/root TERM=$TERM chroot . bash -l

同步 portage 树

# cd /usr
# emerge --sync

安装内核源代码(选择自己喜欢的内核,本文以 gentoo-sources 为例)

# emerge -av gentoo-sources

必要的内核配置:
在进行内核配置时候,务必禁用 CFQ 调度器,ZFS 有自己的调度器,可能会与 CFQ 调度器冲突。

ZLIB_INFLATE/DEFLATE必须编入内核(不作为模块)。 
> ZLIB_INFLATE [=y], ZLIB_DEFLATE [=y]

General setup --->
	[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
	() Initramfs source file(s)
	[*] Enable loadable module support --->
	[*] Module unloading
Enable the block layer --->
	IO Schedulers --->
		< > Deadline I/O scheduler
		< > CFQ I/O scheduler
	Default I/O scheduler (No-op)
Device Drivers --->
	Generic Driver Options --->
		[*] Maintain a devtmpfs filesystem to mount at /dev
		[*] Automount devtmpfs at /dev, after the kernel mounted the rootfs
Cryptographic API --->
	<*> XTS support
	-*- AES cipher algorithms

*其他访问磁盘所必须的 PATA/SATA 驱动也编入内核。

编译并安装内核

# make -j9 && make -j9 modules_install
# make install

安装ZFS模块

# emerge -av zfs

确保 zpool 以及 ZFS 都正确

# zpool status
# zfs list

使用 Bliss Initramfs Creator 创建初始化内存盘

由于 genkernel 创建的内存盘效率较差,而且有时候会出问题导致无法 import zpool,因此 fearedbliss 写了这个工具来代替。

- 安装 busybox 以及 cryptsetup
# echo "sys-apps/busybox static" >> /etc/portage/package.use
# echo "sys-fs/cryptsetup static" >> /etc/portage/package.use
# echo "sys-libs/e2fsprogs-libs static-libs" >> /etc/portage/package.use
# echo "dev-libs/popt static-libs" >> /etc/portage/package.use
# echo "sys-apps/util-linux static-libs" >> /etc/portage/package.use
# echo "dev-libs/libgpg-error static-libs" >> /etc/portage/package.use
# echo "dev-libs/libgcrypt static-libs" >> /etc/portage/package.use
# emerge -avt sys-apps/busybox sys-fs/cryptsetup

- 同步 Bliss Initramfs Creator 代码
# cd /boot
# git clone git://github.com/fearedbliss/Bliss-Initramfs-Creator.git
# cd Bliss-Initramfs-Creator
# ./createInit

- 选择第二项 ZFS+LUKS
# mv initrd-<kernel_name>.img /boot/

安装 extlinux

# emerge -avt syslinux
# install -d /boot/extlinux
# extlinux --install /boot/extlinux
# cd /boot
# ln -s . boot

把 extlinux 安装到磁盘引导区(GPT)

# sgdisk /dev/sdb --attributes=1:set:2
# sgdisk /dev/sdb --attributes=1:show
1:2:1 (legacy BIOS bootable)
# dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/gptmbr.bin of=/dev/sdb
# cp /usr/share/syslinux/menu.c32 /boot/extlinux/
# touch /boot/extlinux/extlinux.conf

配置 extlinux

打开 /boot/extlinux/extlinux.conf,写入以下内容

TIMEOUT 100
UI menu.c32
MENU TITLE Funtoo
Boot Menu MENU COLOR title 1;37;40
MENU COLOR border 30;40
MENU COLOR unsel 37;40
LABEL funtoo bzImage-<Kernel-Version>
	MENU LABEL Funtoo Linux bzImage-<Kernel-Version>
	KERNEL /bzImage-<Kernel-Version>
	INITRD /initrd-<Kernel-Version>.img
	APPEND enc_root=/dev/sdb2 root=rpool/ROOT/gentoo

添加 ZFS 启动项

# rc-update add zfs boot

设置 /etc/fstab

# nano /etc/fstab

# <fs>                            <mountpoint>    <type>          <opts>          <dump/pass>
/dev/sdb1                        /boot            ext4            defaults        1 2
/dev/zvol/rpool/swap             none             swap            sw              0 0

清理并进行最后设置

清理 stage3 压缩文件

# cd /
# rm stage3-*.tar.xz

设置 root 密码

# passwd

退出 chroot 环境

# exit

卸载文件系统

# cd /mnt/gentoo
# umount proc dev sys boot

关闭 swap

# swapoff /dev/zvol/rpool/swap

Export zpool

# cd /
# zpool export -f rpool

重启

# reboot

如果以后需要进入 chroot 环境修复系统,按照以下步骤操作

# cryptsetup luksOpen /dev/sdb2 cryptroot
# zpool import -f -o cachefile= -R /mnt/funtoo -d /dev/mapper rpool