Creating and exporting a variable for the drive that I would like to prepare as the target device:
export TGTDEV=sda
Looking at the source device, I have this layout:
(parted) p
Model: ATA Samsung SSD 860 (scsi)
Disk /dev/sdb: 1000215216s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 2048s 1050623s 1048576s fat32 EFI boot, esp
2 1050624s 35651583s 34600960s ext2 SWAP swap
3 35651584s 943718399s 908066816s ROOT
So I will replicate the same thing:
# parted /dev/$TGTDEV --script mklabel gpt
# parted /dev/$TGTDEV --script mkpart EFI fat32 2048s 1050623s
# parted /dev/$TGTDEV --script set 1 esp on
# parted /dev/$TGTDEV --script mkpart SWAP ext2 1050624s 35651583s
# parted /dev/$TGTDEV --script set 2 swap on
# parted /dev/$TGTDEV --script mkpart ROOT ext4 35651584s 943718399s
I also want to add another system, so I create anoter SWAP and ROOT partition for it. I intentionally create a new swap partition, as there will be situations when I run both systems, one physically and the other one virtualized.
# parted /dev/$TGTDEV --script mkpart MWSWAP ext2 943718400s 978319359s
# parted /dev/$TGTDEV --script set 4 swap on
# parted /dev/$TGTDEV --script mkpart MWROOT ext4 978319360s 100%
Given that I have created a fresh EFI partition, this needs to be formatted and the EFI needs to be installed:
# mkfs.fat -F32 /dev/${TGTDEV}1
Then I need to mount it
# mkdir -p /efiroot
# mount /dev/${TGTDEV}1 /efiroot
And install EFI there:
# bootctl --path=/efiroot install
I got a couple of warnings here:
Created "/efiroot/EFI".
Created "/efiroot/EFI/systemd".
Created "/efiroot/EFI/BOOT".
Created "/efiroot/loader".
Created "/efiroot/loader/entries".
Created "/efiroot/EFI/Linux".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/efiroot/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/efiroot/EFI/BOOT/BOOTX64.EFI".
⚠️ Mount point '/efiroot' which backs the random seed file is world accessible, which is a security hole! ⚠️
⚠️ Random seed file '/efiroot/loader/.#bootctlrandom-XXX' is world accessible, which is a security hole! ⚠️
Random seed file /efiroot/loader/random-seed successfully written (32 bytes).
Created EFI boot entry "Linux Boot Manager".
After that make sure that you have a nice menu that will be displayed for some time:
# tee "/efiroot/loader/loader.conf" << EOF
timeout 10
console-mode keep
EOF
I decided to ignore those for now. Will go ahead and unmount the filesystem for now:
# umount /efiroot
Now that partition layout has been created, I am creating an encrypted swap partition based on https://wiki.archlinux.org/title/dm-crypt/Swap_encryption#UUID_and_LABEL
Creating a false filesystem on the device, so that it has a label
# mkfs.ext2 -L cryptswap /dev/${TGTDEV}2 1M
Now I can verify what is the label and the uuid for the partition:
# blkid /dev/${TGTDEV}2
Also for the other system I again need another swap partition to be created
# mkfs.ext2 -L mwcryptswap /dev/${TGTDEV}4 1M
I realised that I want different labels on the target computer, so I started with renaming the partitions:
# parted /dev/$TGTDEV --script name 3 SCROOT
# parted /dev/$TGTDEV --script name 2 SCSWAP
I also want the swap to have it's own label:
# mkfs.ext2 -L sccryptswap /dev/${TGTDEV}2 1M
Now I want to create the encrypted root filesystem:
# cryptsetup -y -v luksFormat /dev/disk/by-partlabel/SCROOT
Also another root filesystem for the other root:
# cryptsetup -y -v luksFormat /dev/disk/by-partlabel/MWROOT
Open the encrypted device:
# cryptsetup open /dev/disk/by-partlabel/SCROOT scroot
Format the drive with ext4. This might be optional, if you are doing it the second time, you do not need to do it.
# mkfs.ext4 /dev/mapper/scroot
Mount the root
# mkdir -p /mnt/newroot
# mount /dev/mapper/scroot /mnt/newroot
Now I will use rsync to copy through the files to the target system, but before that, let's check the connection.
Given that I am running the copy as root, but only my user has the agent running, I am hijacking the agent with root. As a user I do:
$ echo "export SSH_AUTH_SOCK=$SSH_AUTH_SOCK" > grab-ssh-agent
And then as root I do:
# . grab-ssh-agent
On the source system let's check connection:
# export TGTSYS=root@192.168.0.129
# ssh $TGTSYS ls /mnt/newroot
If everything went fine, then it is time to start the sync:
# rsync \
-aAXHS \
--delete \
--numeric-ids \
--exclude={"/efiroot/*","/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
/ \
"${TGTSYS}:/mnt/newroot/"
Back to the target system:
Mount the EFI partition under the new root. If you have the EFI partition mounted, please unmount it first.
# mkdir -p /mnt/newroot/efiroot
# mount /dev/disk/by-partlabel/EFI /mnt/newroot/efiroot
Create boot loader configuration:
# mkdir -p /mnt/newroot/efiroot/EFI/sc
# ROOT_UUID=$(blkid -o value -s UUID /dev/disk/by-partlabel/SCROOT)
# tee "/mnt/newroot/efiroot/loader/entries/sc.conf" << EOF
title SC
linux /EFI/sc/vmlinuz-linux-lts
initrd /EFI/sc/intel-ucode.img
initrd /EFI/sc/initramfs-linux-lts-sc.img
options root=/dev/mapper/cryptroot cryptdevice=UUID=${ROOT_UUID}:cryptroot rw
EOF
Prepare fstab
# genfstab -U /mnt/newroot > /mnt/newroot/etc/fstab
Then you need to remove the last line about swap if there is one, and add this line:
# echo "/dev/mapper/swap none swap defaults 0 0" >> /mnt/newroot/etc/fstab
Fix mkinitcpio:
# tee "/mnt/newroot/etc/mkinitcpio.d/linux-lts.preset" << EOF
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/efiroot/EFI/sc/vmlinuz-linux-lts"
[[ -e /boot/vmlinuz-linux-lts ]] && cp -af /boot/vmlinuz-linux-lts "/efiroot/EFI/sc/"
[[ -e /boot/intel-ucode.img ]] && cp -af /boot/intel-ucode.img "/efiroot/EFI/sc/"
PRESETS=('sc')
sc_config="/etc/mkinitcpio-sc.conf"
sc_image="/efiroot/EFI/sc/initramfs-linux-lts-sc.img"
EOF
And:
# tee "/mnt/newroot/etc/mkinitcpio-sc.conf" << EOF
MODULES=()
BINARIES=()
FILES=()
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt filesystems fsck)
EOF
Re-generate initramfs
# arch-chroot /mnt/newroot pacman -S --noconfirm linux-lts
Adjust swap
# echo "swap UUID=$(blkid -o value -s UUID /dev/disk/by-partlabel/SCSWAP) /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=512" > /mnt/newroot/etc/crypttab
Adjust X settings:
# vim /mnt/newroot/home/matelakat/.config/xfce4/xinitrc
# for fname in $(find /mnt/newroot/home/matelakat/.config -name pycharm64.vmoptions); do grep uiScale $fname && vim $fname; done
And finish:
# umount /mnt/newroot/efiroot
# umount /mnt/newroot
# cryptsetup close scroot