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.