CLONING YOUR CURRENT (LUKS-FDE) GNU+Linux TO A NEW HDD
Situation: You have an encrypted RootFS with unencrypted boot partition and you want to transfer it to a new Hard Disk Drive or Solid State Drive.
You do not want to install a new OS and reconfigure everything from scratch.
Use gparted to create Partitions
Clone boot partition to our new partition (Use rsync or cp)
Format the second partition for our Root FS and Swap (ENCRYPTED)
# cryptsetup luksFormat /dev/sda2 WARNING! ======== This will overwrite data on /dev/sda2 irrevocably. Are you sure? (Type uppercase yes): YES Enter passphrase: Verify passphrase:
LUKS Open the partition
$ sudo cryptsetup luksOpen /dev/sda2 new Enter passphrase for /dev/sda2:
Create a new physical volume
$ sudo pvcreate /dev/mapper/new Physical volume "/dev/mapper/new" successfully created.
Display physical volumes:
$ sudo pvdisplay
--- Physical volume ---
PV Name /dev/mapper/new
VG Name FIVE
PV Size 100.08 GiB / not usable 2.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 25620
Free PE 25620
Allocated PE 0
PV UUID XXX-XXX-XXX-XXX-XXX-XXX-XX
Create volume group
$ sudo vgcreate FIVE /dev/mapper/new
Display volume group
$ sudo vgdisplay --- Volume group --- VG Name FIVE System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 1 VG Access read/write VG Status resizable MAX LV 0 Cur LV 0 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size 100.08 GiB PE Size 4.00 MiB Total PE 25620 Alloc PE / Size 0 / 0 Free PE / Size 25620 / 100.08 GiB VG UUID XXX
Create our logical volumes: (SWAP PARTITION)
$ sudo lvcreate -L 2G -n swapp FIVE Logical volume "swapp" created.
Show the logical volumes:
sudo vgdisplay --- Volume group --- VG Name FIVE System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 2 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size 100.08 GiB PE Size 4.00 MiB Total PE 25620 Alloc PE / Size 512 / 2.00 GiB Free PE / Size 25108 / 98.08 GiB VG UUID XXXXXX
The free space is now 98GB or 25108
Create the partition for our root:
$ sudo lvcreate -l 25108 -n roots FIVE Logical volume "roots" created.
Show the logical volumes:
$ sudo lvdisplay --- Logical volume --- LV Path /dev/FIVE/swapp LV Name swapp VG Name FIVE LV UUID LV Write Access read/write LV Creation host, time LV Status available # open 0 LV Size 2.00 GiB Current LE 512 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 254:4 --- Logical volume --- LV Path /dev/FIVE/roots LV Name roots VG Name FIVE LV UUID LV Write Access read/write LV Creation host, time LV Status available # open 0 LV Size 98.08 GiB Current LE 25108 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 254:5
Make the swap partition swap:
$ sudo mkswap /dev/FIVE/swapp Setting up swapspace version 1, size = 2 GiB (2147479552 bytes) no label, UUID=9xx-xx-x
Create our root fs:
$ sudo mkfs.ext4 -L root /dev/FIVE/roots mke2fs 1.43.4 (31-Jan-2017) Creating filesystem with 25710592 4k blocks and 6430720 inodes Filesystem UUID: 6 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done
Boot the system using a Live CD/USB:
Decrypt the LUKS partitions for our source and destination:
Assume,
sdb = HDD Destination
sda = HDD Source
sdb1 = boot partition
sdb2 = physical volume for encryption with LVM root and swap partitions inside (VG name FIVE)
FIVE-root = the root partition
FIVE-swap = the swap parition (ignore)
sdb-root = the source root partition (we will clone this to sda)
sdb-swap = our source swap (ignore)
Mount the boot partition for our source and destination, copy the boot contents from source to destination. Unmount boot partition of the destination.
Mount the source rootfs (sdb-root) to /mnt and the destination rootfs (FIVE-root) to /media/user/root
Start the file transfer: (May take a while)
$ sudo rsync --progress -avhPHAXx --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found} /mnt/ /media/user/root/ sending incremental file list ./ .autorelabel . . . . var/www/html/www2/vendor/symfony/polyfill-util/composer.json 751 100% 0.80kB/s 0:00:00 (xfr#435842, to-chk=0/835385) sent 26.49G bytes received 36.42M bytes 3.80M bytes/sec total size is 49.82G speedup is 1.80
Display the luks /dev/mapper names:
$ sudo ls /dev/mapper luks-12313131133 sdb_crypt
Display the blkids:
$ sudo blikd /dev/sda1: UUID="uuid-of-dest-boot" TYPE="ext4" PARTUUID="" /dev/sda2: UUID="uuid-of-dest-dm" TYPE="crypto_LUKS" PARTUUID="" /dev/mapper/luks-12313131133: UUID="this-is-my-decrypted-sda2-dest" TYPE="LVM2_member" /dev/mapper/FIVE-swapp: UUID="my-desti-swap-UUID" TYPE="swap" /dev/mapper/FIVE-roots: LABEL="root" UUID="my-desti-rootfs-UUID" TYPE="ext4" /dev/sdb1: UUID="uuid-of-sourc-boot" TYPE="ext4" PARTUUID="" /dev/sdb2: UUID="uuid-of-sourc-dm" TYPE="crypto_LUKS" PARTUUID="" /dev/mapper/sdb_crypt: UUID="this-is-my-decrypted-sdb-source" TYPE="LVM2_member" /dev/mapper/sdb-swap: UUID="my-source-uuid-swap" TYPE="swap" /dev/mapper/sdb-root: UUID="my-source-uuid-root" TYPE="ext4"
Mount the boot partition of our sda1 to /media/user/root/boot
Chroot the destination rootfs:
$ for i in /sys /proc /run /dev; do sudo mount --bind "$i" "/media/user/root$i"; done $ sudo chroot /media/user/root/
Edit the crypttab and replace the sdb_crypt to our new blkid and dm name:
# nano /etc/crypttab FROM sdb_crypt UUID=this-is-my-encrypted-sdb-source none luks TO luks-12313131133 UUID=this-is-my-encrypted-sda2-dest none luks
Edit the fstab (replace the old entries with our ‘destination’ entries):
# UUID=uuid-of-dest-boot /boot ext4 defaults 0 2 /dev/disk/by-uuid/dev/mapper/FIVE-swapp: UUID="my-desti-swap-UUID" TYPE="swap" none swap sw 0 0 /dev/mapper/FIVE-roots / ext4 errors=remount-ro 0 1
Update the initramfs:
$ sudo update-initramfs -u -k all [sudo] password for user: update-initramfs: Generating /boot/initrd.img-4.9.0-8-amd64 ... live-boot: core filesystems devices utils udev wget blockdev dns.
Install GRUB2 to the MBR of /dev/sda
$ sudo grub-install /dev/sda Installing for i386-pc platform. $ sudo update-grub Generating grub configuration file ... Found background image: .background_cache.png ... done
Exit Chroot and Unmount:
$ for i in /sys /proc /run /dev; do sudo umount "/media/user/root$i"; done $ sudo umount /media/user/root/boot $ sudo umount /media/user/root
Close volume groups, LUKS and reboot.
$ sudo vgchange -an $ sudo cryptsetup luksClose /dev/mapper/luks-12313131133
This is tested on Master Boot Record, not on GPT.
If your first boot fail after our changes earlier, but can access initramfs, mount your encrypted partition and generate a new initram image:
(initramfs) cryptsetup luksOpen /dev/sdb2 luks-12313131133 Enter your passphrase: (initramfs) exit After booting up, open a root terminal and generate initram: # update-initramfs -u -k all
Reboot and you should be able to boot normally.
If you still cannot boot, please double check the crypttab entry and the /dev/mapper name.
Video tutorial: https://youtu.be/FE5yxls74PE
References:
Rsync command stackoverflow
Except where otherwise noted, this work is licensed under Creative Commons Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0/).
I hope that this post is useful to you, if you liked this post you may support me via Patreon or liberapay. Thank you for your support.