In this guide, you will learn how to easily extend existing LUKS-encrypted LVM by adding physical volume. LUKS, Linux Unified Key Setup, is a standard for encrypting entire disks or partitions on Linux systems.
Table of Contents
Extending LUKS-Encrypted LVM by Adding Physical Volume
So, how can you easily extend existing root LUKS encrypted LVM by adding an extra Physical disk?
Current Drive Information
In my test environment, I have an Ubuntu 24.04 virtual machine with LUKs encrypted physical volume that was enabled and configured during initial installation process.
lsblk
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 23G 0 part
└─dm_crypt-0 252:0 0 23G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:1 0 23G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
As you can see /dev/sda3 (with root filesystem) is LUKs encrypted.
More information about the Physical volumes, volume group and logical volume;
sudo pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/dm_crypt-0 ubuntu-vg lvm2 a-- 22.98g 0
sudo vgs
VG #PV #LV #SN Attr VSize VFree
ubuntu-vg 1 1 0 wz--n- 22.98g 0
sudo lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
ubuntu-lv ubuntu-vg -wi-ao---- 22.98g
Additional Drives
Now, I want to expand the existing storage by attaching two more physical drives to the machine;
lsblk
...
sdb 8:16 0 5G 0 disk
sdc 8:32 0 15G 0 disk
Format New Drives as Linux LVM (8e
)
Format your new drives as Linux LVM;
sudo fdisk /dev/sdb
Create new primary partition and use all available space. Set the partition as Linux LVM:
Welcome to fdisk (util-linux 2.39.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS (MBR) disklabel with disk identifier 0x63f961b1.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): ENTER
Using default response p.
Partition number (1-4, default 1): ENTER
First sector (2048-10485759, default 2048): ENTER
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-10485759, default 10485759): ENTER
Created a new partition 1 of type 'Linux' and of size 5 GiB.
Command (m for help): t
Selected partition 1
Hex code or alias (type L to list all): lvm
Changed type of partition 'Linux' to 'Linux LVM'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Do the same on the other drive;
sudo fdisk /dev/sdc
Check the partition type;
sudo fdisk /dev/sdb -l
Disk /dev/sdb: 5 GiB, 5368709120 bytes, 10485760 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x63f961b1
Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 10485759 10483712 5G 8e Linux LVM
Encrypt New Drives Partitions with LUKS
Next, encrypt the new Drives partitions with LUKS key;
sudo cryptsetup luksFormat /dev/sdb1
Confirm that you want to proceed and provide passphrase to encrypt your drive partition;
WARNING!
========
This will overwrite data on /dev/sdb1 irrevocably.
Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/sdb1: PASSPHRASE
Verify passphrase: PASSPHRASE
Similarly, format the other drives partitons;
sudo cryptsetup luksFormat /dev/sdc1
To view detailed header information about the LUKS header of a device (such as UUID, cipher, key size, etc.), you can use the luksDump
sub-command.
LUKS header information
Version: 2
Epoch: 3
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 848a0a92-0c0e-46aa-8a02-368fc0dd6a4c
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 512 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2id
Time cost: 5
Memory: 1048576
Threads: 2
Salt: 67 5f 9d 71 1f 7b 20 17 bd e1 da 17 51 84 67 76
2f 78 45 cc b1 cf a6 21 9d 5e c5 d2 09 6a 81 7f
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0
Tokens:
Digests:
0: pbkdf2
Hash: sha256
Iterations: 144830
Salt: fe 3c e3 47 ea 84 24 8c 74 6f 79 1d 05 d7 5c 6b
b0 15 77 b4 d9 6e 79 5c ec 83 7c 4b 2b 74 9e 27
Digest: 18 87 98 d6 62 91 a5 2c 65 8e fc 67 dd a2 d7 16
52 ae 72 dd 9f cd 85 5c c1 f9 4e 5e 07 07 40 1c
Unlock LUKs Devices and Create Physical Volume
Unlock your newly create LUKS devices and create new physical volumes that can be used to expand your current drive.
The cryptsetup luksOpen
command is used to open (unlock) a LUKS (Linux Unified Key Setup) encrypted device, making it accessible for further use.
The basic syntax of the luksOpen
command is as follows:
sudo cryptsetup luksOpen /dev/sdXn <mapping_name>
Where:
/dev/sdXn
: The path to the LUKS-encrypted partition (replace with your actual device).<mapping_name>
: The name you want to assign to the decrypted mapping. This name is used to refer to the decrypted device when accessing it.
Thus;
sudo cryptsetup luksOpen /dev/sdb1 sdb1
sudo cryptsetup luksOpen /dev/sdc1 sdc1
In this example, the LUKS-encrypted partition at /dev/sdb1/sdc1
is opened with the mapping name sdb1/sdc1
respectively. After running this command, you will find a device named /dev/mapper/sdb1|sdc1
, which represents the decrypted version of the LUKS-encrypted partition.
You can check the status using cryptsetup status
command;
sudo cryptsetup status sdb1
/dev/mapper/sdb1 is active.
type: LUKS2
cipher: aes-xts-plain64
keysize: 512 bits
key location: keyring
device: /dev/sdb1
sector size: 512
offset: 32768 sectors
size: 10450944 sectors
mode: read/write
Now that the devices are unlocked, create physical volumes on them;
sudo pvcreate /dev/mapper/sdb1
sudo pvcreate /dev/mapper/sdc1
See some information;
sudo pvs
PV VG Fmt Attr PSize PFree
/dev/mapper/dm_crypt-0 ubuntu-vg lvm2 a-- 22.98g 0
/dev/mapper/sdb1 lvm2 --- 4.98g 4.98g
/dev/mapper/sdc1 lvm2 --- 14.98g 14.98g
Extend the Volume Group
Now that we have two extra physical volumes, extend the volume group by adding the new physical volumes.
My volume group is named ubuntu-vg
. See above VG column.
sudo vgextend ubuntu-vg /dev/mapper/sdb1 /dev/mapper/sdc1
Confirm;
sudo vgs
VG #PV #LV #SN Attr VSize VFree
ubuntu-vg 3 1 0 wz--n- 42.94g 19.96g
Extend Root Logical Volume
Extend the logical volume to use the new all the new space. Our LVM is ubuntu-lv
.
sudo lvextend -r -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
-r
: This option is used to resize the filesystem on the logical volume along with extending the logical volume itself.-l +100%FREE
: This option specifies how much to extend the logical volume. In this case, it is extended by 100% of the available free space in the volume group.
Confirm;
sudo df -hT -P /
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv ext4 43G 8.9G 32G 22% /
You have successfully extended your existing LUKS-encrypted LVM by adding new physical volume.
Mount the LUKS Devices on Boot
The /etc/crypttab
file is a configuration file used in Linux systems to define encrypted block devices (usually partitions or LVM logical volumes) that are set up during the system boot process.
Since we enabled LVM LUKS encryption while setting up our OS from the beginning, the crypttab contains the information below at the moment;
cat /etc/crypttab
dm_crypt-0 UUID=67482f55-a3ea-433a-bdf4-87210ce042ba none luks
The typical format of entries in the /etc/crypttab
file is as follows:
<name> <device> <key file> <options>
<name>
: The name used to refer to the mapping of the encrypted device. This is often a symbolic name and is used in the/dev/mapper/
path. For example, if<name>
is set to “sdb1,” the mapped device might be/dev/mapper/sdb1
.<device>
: The path to the encrypted block device, such as a partition or logical volume.- <key file> An optional parameter specifying a file containing the key or passphrase for the encrypted device. This can be left empty or set to none if a key file is not used so as to be prompted to enter passphrase while booting.
<options>
: LUKS option such as cipher/key size
So, let’s update the crypttab with the new devices entries.
To begin with, get the devices UUIDs.
sudo blkid | grep LUKS
/dev/sdb1: UUID="848a0a92-0c0e-46aa-8a02-368fc0dd6a4c" TYPE="crypto_LUKS" PARTUUID="63f961b1-01"
/dev/sdc1: UUID="e98f363f-dc74-4202-8680-87e968a73770" TYPE="crypto_LUKS" PARTUUID="4cb3d400-01"
/dev/sda3: UUID="67482f55-a3ea-433a-bdf4-87210ce042ba" TYPE="crypto_LUKS" PARTUUID="0e14c2c8-17e7-4dbc-8d86-c1541b9d5edf"
Now that we have UUIDS, update crypttab.
sudo vim /etc/crypttab
Entries we will add;
sdb1 UUID=848a0a92-0c0e-46aa-8a02-368fc0dd6a4c none luks
sdc1 UUID=e98f363f-dc74-4202-8680-87e968a73770 none luks
So, crypttab now looks like;
cat /etc/crypttab
dm_crypt-0 UUID=67482f55-a3ea-433a-bdf4-87210ce042ba none luks
sdb1 UUID=848a0a92-0c0e-46aa-8a02-368fc0dd6a4c none luks
sdc1 UUID=e98f363f-dc74-4202-8680-87e968a73770 none luks
With this, when the system boots, you will be prompted for passphrase to unlock them.
Update Initial RAM FileSystem
If you make any changes, you need to update the initial RAM filesystem, initramfs
to include the changes. initramfs is a temporary filesystem loaded into memory during the initial stage of the Linux boot process. It contains essential tools, modules, and scripts required to initialize the system before transitioning to the actual root filesystem.
You can update initramfs as follows;
sudo update-initramfs -u
Any Updates for FSTAB?
No, at this point the new physical volumes added are already part of the LVM;
lsblk
...
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 23G 0 part
└─dm_crypt-0 252:0 0 23G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:1 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
sdb 8:16 0 5G 0 disk
└─sdb1 8:17 0 5G 0 part
└─sdb1 252:2 0 5G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:1 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
sdc 8:32 0 15G 0 disk
└─sdc1 8:33 0 15G 0 part
└─sdc1 252:3 0 15G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:1 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
Hence, no changes required for FSTAB for now.
Reboot the System to Confirm Changes
if you are doubting something, address it properly before proceeding. Otherwise, reboot your system to apply the changes and ensure that both LUKS-encrypted devices are automatically unlocked and mounted during boot.
sudo systemctl reboot -i
Unlock LUKs Devices
If everything went well, your system should boot with no issue and you will be prompted to enter LUKS decryption passphrase.
Unlock First Drive;
Unlock second LUKS device;
Unlock third LUKS device;
Successful!
Login to the system and confirm that you have extend existing LUKS-encrypted LVM.
df -hT -P /
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv ext4 43G 8.9G 32G 22% /
lsblk
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 23G 0 part
└─dm_crypt-0 252:0 0 23G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:3 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
sdb 8:16 0 5G 0 disk
└─sdb1 8:17 0 5G 0 part
└─sdb1 252:1 0 5G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:3 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
sdc 8:32 0 15G 0 disk
└─sdc1 8:33 0 15G 0 part
└─sdc1 252:2 0 15G 0 crypt
└─ubuntu--vg-ubuntu--lv 252:3 0 42.9G 0 lvm /var/snap/firefox/common/host-hunspell
/snap
/
And that is it on how to extend existing LUKS-encrypted LVM.
Read more LUKS tutorials in our other guides