How to Encrypt New Hard Disk (Partition) using LUKS in Linux

User avatar placeholder
Written by Deepak Prasad

May 31, 2025

Earlier I had shared an article to encrypt, decrypt and sign a file using GPG key in Linux. In this article I will show you the steps to create an encrypted block device using LUKS. By default if somebody connects your hard disk to their computer, it can be mounted automatically, even without entering any user credentials, and that is why we should always encrypt hard disk.

If your hard disk was encrypted then in order to mount an encrypted device, you need to enter a passphrase, without passphrase, nobody can mount it. So this will protect your hard disk, or your server, hard disk from being lost or stolen or whatever, after which data can be accessed easily.

To create encrypted devices in Linux we use LUKS which is the Linux encryption layer.

 

dm-crypt and cryptsetup vs LUKS

dm-crypt and cryptsetup

  • Device-mapper is a part of the Linux kernel that provides a generic way to create virtual layers of block devices, most commonly LVM logical volumes. The device-mapper crypt target (dm-crypt) provides transparent encryption of block devices using the kernel crypto API.
  • In Red Hat Enterprise Linux, userspace interaction with dm-crypt is managed by a tool called cryptsetup, which uses the device-mapper infrastructure to setup and operate on encrypted block devices.

 

LUKS

  • With modern versions of cryptsetup (i.e., since ~2006), encrypted block devices can be created in two main formats, plain dm-crypt format or the extended LUKS (Linux Unified Key Setup-on-disk-format) format.
  • LUKS provides a standard on-disk-format for hard disk encryption, which facilitates compatibility among Linux distributions and provides secure management of multiple user passwords.
  • In contrast to previous Linux disk-encryption solutions, LUKS stores all necessary setup information in the partition header, enabling the user to more easily transport or migrate their data.
  • The advantages of LUKS over plain dm-crypt are the obvious higher usability: automatic configuration of non-default crypto parameters, the ability to add, change, and remove multiple passphrases.
  • Additionally, LUKS offers defenses against low-entropy passphrases like salting and iterated PBKDF2 passphrase hashing

 

Attach new hard disk (optional)

So to start with, you need an empty device. I have added a new virtual disk to my virtual machine as /dev/sdb


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
└─ubuntu--vg-ubuntu--lv 252:0 0 23G 0 lvm /
sdb 8:16 0 5G 0 disk
sr0 11:0 1 57.4M 0 rom
How to Encrypt New Hard Disk (Partition) using LUKS in Linux

 

Install cryptsetup

It is possible your distro may not have cryptsetup installed by default. Since we are using Ubuntu 24.10 so we will use apt to install the package:

sudo apt update
sudo apt install cryptsetup -y

 

Create new partition

First let's wipe our device empty, just to be sure that there are no stale data.

sudo wipefs -a /dev/sdb
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=100

We will create a new partition /dev/sdb1 on this disk

golinuxcloud@server1:~$ sudo fdisk /dev/sdb

Welcome to fdisk (util-linux 2.40.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 0xdaf1796a.

Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-10485759, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-10485759, default 10485759):

Created a new partition 1 of type 'Linux' and of size 5 GiB.

Command (m for help): p
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: 0xdaf1796a

Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 10485759 10483712 5G 83 Linux

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

So our partition is successfully created.

[root@node1 ~]# partprobe

So our partition is successfully created as we can check using lsblk command.

How to Encrypt New Hard Disk (Partition) using LUKS in Linux

We can also check /proc/partitions:

golinuxcloud@server1:~$ cat /proc/partitions  | grep sdb
8 16 5242880 sdb
8 17 5241856 sdb1

 

Encrypt the partition with LUKS

So you would do luksFormat on the device, and the luksFormat command is going to create the encryption layer. This is the passphrase that needs to be entered by anyone who wants to access the device. In real life of course, you wanna have something that really is secure because devices are not mounted that often. (computer keys tapping and clicking)

By default, cryptsetup luksFormat uses pretty good defaults but you can pass additional arguments to further secure your disk with better encryption:

Parameter Recommendation Why
--type luks2 LUKS2 is superior (metadata redundancy, re-encryption support)
--sector-size 4096 Matches physical sector size of most modern disks
--key-size 256 Strong AES-256 key strength
--cipher aes-xts-plain64 Default, still recommended
--hash sha512 Stronger key derivation

We can use the following command

sudo cryptsetup luksFormat --type luks2 --sector-size 4096 --key-size 256 --cipher aes-xts-plain64 --hash sha512 /dev/sdb1

Sample output:

How to Encrypt New Hard Disk (Partition) using LUKS in Linux

This will prompt you for a new passphrase. This will be used to unlock the encryption keys that encrypt the actual data. Now it does not directly encrypt the data itself — it just protects the master key which is stored in the LUKS header.

When we basically run luksFormat, The LUKS generates:

  • A random master key (full entropy, very strong).
  • Our passphrase will be used to derive a key encryption key (KEK) using PBKDF2 or Argon2 key derivation.
  • This KEK will encrypt the master key and then it will store it in the LUKS header.

When we later open (cryptsetup open):

  • We have to enter the same passphrase as we gave earlier.
  • Next KEK is derived and Master key is decrypted.
  • The master key will be loaded into kernel memory and will be used for actual disk I/O encryption/decryption.

 

Initialize LUKS device

Next, you need to do luksOpen, and that brings you to a different level where you are going to work with the encrypted device. So this will create a new device, and this new device is managed by the device mapper, so let's call it /dev/mapper/secret.

golinuxcloud@server1:~$ sudo cryptsetup luksOpen /dev/sdb1 secret
Enter passphrase for /dev/sdb1:

As we will see when you are using the cryptsetup, luksOpen command, a new device is created, and you will provide the name for the device. In this example, the name for the device is /dev/mapper/secret

golinuxcloud@server1:~$ ls -l /dev/mapper/
total 0
crw------- 1 root root 10, 236 May 30 18:41 control
lrwxrwxrwx 1 root root 7 May 30 19:06 secret -> ../dm-1
lrwxrwxrwx 1 root root 7 May 30 18:41 ubuntu--vg-ubuntu--lv -> ../dm-0

 

Create file system on LUKS device

Now the important step is that you need to create a file system on the encrypted device, and that means that the file system is going to be created here.

IMPORTANT NOTE:
Here make sure you create a file system on the encrypted device and not on the physical partition. The file system must be created on the LUKS device.
golinuxcloud@server1:~$ sudo pvcreate /dev/mapper/secret
Physical volume "/dev/mapper/secret" successfully created.
golinuxcloud@server1:~$
golinuxcloud@server1:~$ sudo vgcreate secure_vg /dev/mapper/secret
Volume group "secure_vg" successfully created
golinuxcloud@server1:~$
golinuxcloud@server1:~$ sudo lvcreate -l 100%FREE -n secure_lv secure_vg
Logical volume "secure_lv" created.
golinuxcloud@server1:~$
golinuxcloud@server1:~$ sudo mkfs.ext4 /dev/secure_vg/secure_lv
mke2fs 1.47.1 (20-May-2024)
Creating filesystem with 1305600 4k blocks and 326400 inodes
Filesystem UUID: 48ab4b7c-7a7c-41d6-b3a4-be45baa6a571
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

  

Mount the LUKS partition

Once a file system has been created on the LUKS device, you can move on, you can create a mount point and mount it.

sudo mkdir /mnt/secure-lvm
sudo mount /dev/secure_vg/secure_lv /mnt/secure-lvm

Once we can verify using the mount command, you can see that from the mount command perspective, there's nothing visible about the device being encrypted, we just see a device that is encrypted.

golinuxcloud@server1:~$ mount | grep secure
/dev/mapper/secure_vg-secure_lv on /mnt/secure-lvm type ext4 (rw,relatime)

So we can create files on top of it. (computer keys tapping and clicking) And these files will be safely stored on the encrypted device.

 

Auto mount LUKS device using fstab with key (No prompt for LUKS passphrase)

Verify existing key slots

The current version of LUKS (LUKS2) supports up to 32 encryption keys per encrypted volume, whereas LUKS1 only supports up to 8 keys. Each slot can store a different key (password or keyfile) to unlock the same encrypted data. We can use one of these keys (for example, a keyfile stored securely) to configure auto-mounting of LUKS devices

But do you wonder, why we will need so many slots?

This can actually help for scenarios like following:

Reason Why it helps
🔑 Multiple users Admin and user can have separate passphrases
🔄 Key rotation You can add a new key, test it, then remove old key — without re-encrypting the entire disk
🔐 Keyfiles for automation Use passphrase for manual unlock + keyfile for auto-unlock at boot
🎯 Backup key Keep an emergency recovery passphrase
🏢 Enterprise setups One slot for admin, one for automation, one for recovery, etc.

Let's dump the existing set of key slots using luksDump:

golinuxcloud@server1:~$ sudo cryptsetup luksDump /dev/sdb1
LUKS header information
Version: 2
Epoch: 5
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 9cc957b0-fd12-4e73-affb-a96f2138d6e2
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)

Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 4096 [bytes]

Keyslots:
0: luks2
Key: 256 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 256 bits
PBKDF: argon2id
Time cost: 4
Memory: 761034
Threads: 2
Salt: db 23 b5 e3 ab 47 e3 5d 1d 70 8c 13 20 2c 16 38
46 65 3e 5c 05 92 5d 55 5e ba fa 4d bb e1 da f4
AF stripes: 4000
AF hash: sha512
Area offset:32768 [bytes]
Area length:131072 [bytes]
Digest ID: 0

Tokens:
Digests:
0: pbkdf2
Hash: sha512
Iterations: 193607
Salt: 80 b9 5e 4b f8 cc f0 fb 3a 14 7b a4 90 be 30 d5
cd 75 e6 50 49 41 71 b2 89 f9 fe 2c 95 89 2d 2c
Digest: 84 1e 62 02 c5 64 26 79 0f 0e 4e 4f f5 c5 b5 94
a2 69 d3 49 03 1c 1a 19 db 86 cd a2 f8 40 05 6d
9c 05 70 2e 72 44 87 9c 71 bb 43 f2 3c b8 fe a0
0f 1d d9 e3 e9 35 58 d8 b7 cd 73 f8 5a a5 5e 7d

As you can see, currently only one active keyslot: Keyslot 0. This slot holds the encrypted copy of the master key — protected by the passphrase we entered during luksFormat.

When we run sudo cryptsetup open /dev/sdb1 secret then we are using the passphrase stored in Keyslot 0 to decrypt the master key and unlock the disk.

Next we need to create a keyfile which will be used to auto mount the partition during reboot. As if you don't follow this then the boot up stage will halt at password prompt while trying to mount the encrypted disk.

 

Create keyfile to avoid interactive passphrase prompt

sudo dd if=/dev/urandom of=/root/keyfile.bin bs=512 count=4
sudo chmod 600 /root/keyfile.bin

Now add this key to LUKS:

sudo cryptsetup luksAddKey /dev/sdb1 /root/keyfile.bin

This will just add the keyfile into a new slot.

Let's re-verify the key dump:

golinuxcloud@server1:~$ sudo cryptsetup luksDump /dev/sdb1
LUKS header information
Version: 2
Epoch: 6
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 9cc957b0-fd12-4e73-affb-a96f2138d6e2
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)

Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 4096 [bytes]

Keyslots:
0: luks2
Key: 256 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 256 bits
PBKDF: argon2id
Time cost: 4
Memory: 761034
Threads: 2
Salt: db 23 b5 e3 ab 47 e3 5d 1d 70 8c 13 20 2c 16 38
46 65 3e 5c 05 92 5d 55 5e ba fa 4d bb e1 da f4
AF stripes: 4000
AF hash: sha512
Area offset:32768 [bytes]
Area length:131072 [bytes]
Digest ID: 0
1: luks2
Key: 256 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 256 bits
PBKDF: argon2id
Time cost: 4
Memory: 1048576
Threads: 2
Salt: 45 06 0a 8b fd ec 3a 03 60 71 9d 62 c2 ef 8b 8f
b3 75 76 dd 4a 38 28 40 5d 93 06 b4 d8 68 d4 b6
AF stripes: 4000
AF hash: sha256
Area offset:163840 [bytes]
Area length:131072 [bytes]
Digest ID: 0
NOTE:
If you want to delete the key slot then you can use sudo cryptsetup luksRemoveKey /dev/sdb1 which will remove that keyslot. If you know the exact keyslot to be removed then you can also use sudo cryptsetup luksKillSlot /dev/sdb1 1 where 1 is the slot to be deleted.

 

Configure /etc/crypttab for automatic LUKS unlock

First, get UUID of your encrypted partition:

golinuxcloud@server1:~$ sudo blkid /dev/sdb1
/dev/sdb1: UUID="9cc957b0-fd12-4e73-affb-a96f2138d6e2" TYPE="crypto_LUKS" PARTUUID="daf1796a-01"

Now edit /etc/crypttab using sudo privilege and add following entry based on your UUID value:

secret UUID=9cc957b0-fd12-4e73-affb-a96f2138d6e2 /root/keyfile.bin luks
  • secret → this is the LUKS mapper name (/dev/mapper/secret)
  • Keyfile path is used to unlock automatically.

 

Configure /etc/fstab for LVM mount

Earlier we had created a directory /mnt/secure-lvm to mount our secure LVM /dev/secure_vg/secure_lv. So, now we will update our /etc/fstab to automatically mount this partition:

 

Update initramfs

Since we're modifying boot-time decryption:

golinuxcloud@server1:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.11.0-19-generic

Don't skip this — or else boot may fail because your crypttab changes won’t be loaded into initrd.

 

Test the full boot automation

Reboot your VM. System should automatically:

  1. Unlock /dev/sdb1 via keyfile.
  2. Map it as /dev/mapper/secret.
  3. Activate secure_vg automatically.
  4. Mount secure_lv on your target mount point.

As in my case, the partition is added automatically:

golinuxcloud@server1:~$ mount | grep secure
/dev/mapper/secure_vg-secure_lv on /mnt/secure-lvm type ext4 (rw,relatime)

  

Lastly I hope the steps from the article to encrypt hard disk (partition) using LUKS on Linux was helpful. So, let me know your suggestions and feedback using the comment section.

In the next article I will share the steps to automatically decrypt and mount the encrypted partition at booting stage using key file on Linux

 

Views: 2,091
Image placeholder

Deepak Prasad is the founder of GoLinuxCloud, bringing over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, Networking, and Security. His extensive experience spans development, DevOps, networking, and security, ensuring robust and efficient solutions for diverse projects.

Certifications and Credentials:

  • Certified Kubernetes Application Developer (CKAD)
  • Go Developer Certification
  • Linux Foundation Certified System Administrator (LFCS)
  • Certified Ethical Hacker (CEH)
  • Python Institute PCAP (Certified Associate in Python Programming)
You can connect with him on his LinkedIn profile and join his Facebook and LinkedIn page.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

14 thoughts on “How to Encrypt New Hard Disk (Partition) using LUKS in Linux”

  1. Great & helpful tutorials, these helped me to setup & automount encrypted partition, thank you!

    As suggestion, running the cryptsetup with arguments “cryptsetup –sector-size=4096 –key-size=256” provides better performance than the default settings.

    Reply
  2. hello, thank you for this tutorial..
    I want to ask about change mount point..
    I want to move all my /home to separated encrypted disk..
    so, according this tutorial, I just need change /secret to /home, isn’t it?? or there is additional workaround??

    thank you..

    Reply
  3. Hi there!
    I tried to do this procedure on a second backup device. The first device still works like a charm (also automounting) but the new device is not mounting.
    My fstab looks like this:

    /dev/mapper/secret      /media/Benjis_ZS                 ext4    nofail,users,defaults        0 2
    /dev/mapper/backup      /media/backup                    ext4    nofail,users,defaults        0 2 

    and my crypttab like this:

    secret  /dev/sdc1       /root/lukskey
    secret  /dev/sdb1       none

    When plugin the new HDD sdb changed to sdc. So the old HDD is /dev/sdc1 and still working. The new is /dev/sdb1.
    I can only mount the new HDD after:

    sudo cryptsetup luksOpen /dev/sdb1 backup

    Before this I am not able to mount the new HDD. How can I perform encryption with two HDDs?

    Reply
    • You will have to create a key slot for the second device as well to make it auto mount after reboot.

      secret /dev/sdb1 none
      Reply
      • Thanks a lot! Works like a charm now. I think the mistake was with this:

        secret  /dev/sdc1       /root/lukskey
        secret  /dev/sdb1       none

        It should be:

        secret  /dev/sdc1       /root/lukskey
        backup  /dev/sdb1       none
        Reply
        • Thanks for highlighting, I overlooked the LVM name 🙂
          I am glad you sorted it out and thanks for sharing the solution.

          Reply
  4. Hello, thank you very much for the tuto!

    A question: what is the difference between encrypting a partition and simply assigning password protected privileges to a file system, like a user password or a root password? For instance, allowing only root access to a file, or simply use a user’s password to open a session? If the drive is stolen, people won’t have access to the content either, no?

    Reply
  5. Really great Tutorial! I run through it in Kubuntu 18.04 and everything from the start worked out very nicely!!! Great job! Cheers

    Reply

Leave a Comment