Migrating a FreeBSD system to a new disk while using ZFS on root and GELI full disk encryption can be a complex process. However, with the right approach and a thorough understanding of the steps involved, it can be accomplished without data loss. In this post, we will provide a step-by-step guide on how to migrate your FreeBSD system to a new disk using ZFS on root and GELI full disk encryption.

In this case, I will move my entire operating system from ada0 to nvd0.

Setup Disk

gpart create -s gpt nvd0
gpart add -a 1M -s 260M -t efi -l efiboot1 nvd0
gpart add -a 1M -s 4G -t freebsd-swap -l swap1 nvd0
gpart add -t freebsd-zfs -l zfsroot1 nvd0

The first command, gpart create -s gpt nvd0, creates a new partition table of type GPT (GUID Partition Table) on the disk identified as nvd0.

The next three commands add partitions to the newly created partition table on the nvd0 disk.

The command gpart add -a 1M -s 260M -t efi -l efiboot1 nvd0 adds a partition for EFI system, with a size of 260 megabytes and a label of efiboot1.

The command gpart add -a 1M -s 4G -t freebsd-swap -l swap1 nvd0 adds a partition for swap space, with a size of 4 gigabytes and a label of swap1.

The command gpart add -t freebsd-zfs -l zfsroot1 nvd0 adds a partition for ZFS (Zettabyte File System) and labels it zfsroot1.

Verify

gpart show -p nvd0

Setup EFI Partition

newfs_msdos -F32 -c 1 /dev/nvd0p1
mount -t msdosfs -o longnames /dev/nvd0p1 /mnt/
mkdir -p /mnt/EFI/BOOT
cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.efi
umount /mnt/

The commands are used to format and mount an EFI System Partition (ESP) on a storage device /dev/nvd0 in the msdos file system format.

The first command newfs_msdos creates a new file system on the first partition /dev/nvd0p1 with the -F32 flag indicating to use the FAT32 file system, and the -c 1 flag indicates to set the cluster size to 1 sector.

The second command mount mounts the newly formatted partition on the mount point /mnt with the -t msdosfs flag indicating that the file system is msdosfs and the -o longnames flag enabling long file name support.

The third command creates the directory /mnt/EFI/BOOT with sudo mkdir -p to create the necessary folder structure for the EFI boot loader.

The fourth command copies the EFI boot loader loader.efi to /mnt/EFI/BOOT/BOOTX64.efi with sudo cp to make it available for booting.

The fifth and final command umount unmounts the partition at /mnt.

Setup GELI

geli init -b -g -K /root/nvd0p3.key -s 4096 -l 256 /dev/nvd0p3

This is a command that initializes encryption using GELI (FreeBSD’s cryptographic disk encryption system) on the device /dev/nvd0p3.

The command uses several options:

-b creates a bootable GELI partition.

-g Enable booting from this encrypted root filesystem.

-K /root/nvd0p3.key specifies a key file to export for the encryption.

-s 4096 sets the sector size for the encrypted partition to 4096 bytes.

-l 256 sets the number of PBKDF2 iterations to use for key derivation.

Once the command is run, the system prompts the user to enter a passphrase to encrypt the partition. The encrypted partition can then be used like any other disk partition.

Backup Metadata and Keys

cp -R /var/backups/nvd0p3.eli /root/nvd0p3.key /media/da0p1/

Remove GELIBOOT Flag From Old Disk

geli configure -G /dev/ada0p3

Attach

geli attach -k /root/keys/nvd0p3.key /dev/nvd0p3

Setup ZFS

zpool attach zroot /dev/ada0p3.eli /dev/nvd0p3.eli

ZPool Status

zpool status zroot

Remove Old Disk

zpool detach zroot /dev/ada0p3.eli