Skip to content

Instantly share code, notes, and snippets.

@krzys-h
Last active June 2, 2025 19:24
Show Gist options
  • Save krzys-h/226a16eb56c82df0dc3a9d35fad989c8 to your computer and use it in GitHub Desktop.
Save krzys-h/226a16eb56c82df0dc3a9d35fad989c8 to your computer and use it in GitHub Desktop.
Encrypt existing partitions with LUKS2 on Ubuntu 20.04
#!/bin/bash
# Encrypt an existing partition with LUKS2 on Ubuntu 20.04 LTS
# DISCLAIMER: USE AT YOUR OWN RISK AND MAKE BACKUPS
# Made for my personal use and has almost NO error checking!!
# Based on instructions from:
# https://wiki.archlinux.org/index.php/dm-crypt/Device_encryption#Encrypt_an_existing_unencrypted_filesystem
DISK="$1"
if [ -z "$DISK" ]; then
echo "Usage: $0 /dev/sdXY"
exit 1
fi
# Run a filesystem check
e2fsck -f "$DISK"
# Make the filesystem slightly smaller to make space for the LUKS header
BLOCK_SIZE=`dumpe2fs -h $DISK | grep "Block size" | cut -d ':' -f 2 | tr -d ' '`
BLOCK_COUNT=`dumpe2fs -h $DISK | grep "Block count" | cut -d ':' -f 2 | tr -d ' '`
SPACE_TO_FREE=$((1024 * 1024 * 32)) # 16MB should be enough, but add a safety margin
NEW_BLOCK_COUNT=$(($BLOCK_COUNT - $SPACE_TO_FREE / $BLOCK_SIZE))
resize2fs -p "$DISK" "$NEW_BLOCK_COUNT"
# Run the encryption process
cryptsetup reencrypt --encrypt --reduce-device-size 16M "$DISK"
# Resize the filesystem to fill up the remaining space (i.e. remove the safety margin from earlier)
cryptsetup open "$DISK" recrypt
resize2fs /dev/mapper/recrypt
cryptsetup close recrypt
# Don't forget to update /etc/crypttab and /etc/fstab if required!
#
# For example:
# /etc/crypttab
# crypt_root UUID=xxx none luks,keyscript=decrypt_keyctl
# crypt_home UUID=xxx none luks,keyscript=decrypt_keyctl
# /etc/fstab
# /dev/mapper/crypt_root / ext4 errors=remount-ro 0 1
# /dev/mapper/crypt_home /home ext4 defaults 0 2
#
# The decrypt_keyctl makes it possible to unlock both partitions with the same password,
# and unlock gnome-keyring-daemon if you enable autologin and it's encrypted with the same password
# Note: if you are doing a clean install, using LVM is probably a better idea
#
# and remember to run "update-initramfs -u -k all" after updating the rootfs crypttab
@tk425
Copy link

tk425 commented May 13, 2022

worked like a champ on Ubuntu 22.04 - thank you!

@williamdes
Copy link

Awesome, this still works on Debian 12 !
I added set -euo pipefail as a second line for more safety.

@williamdes
Copy link

As said on Debian's reddit and Unix StackExchange GRUB will not unlock if the keyslot is PBKDF: argon2id

You will need to run:

  • cryptsetup luksDump /dev/sda to check that is needs to be converted
  • cryptsetup luksConvertKey --pbkdf pbkdf2 /dev/sda to convert the key
  • cryptsetup luksDump /dev/sda to check that is worked

@chertykov
Copy link

Work for Ubuntu 24.04 !

@Vorlent
Copy link

Vorlent commented Jun 2, 2025

I have used the script and it works flawlessly, but I simply couldn't figure out a way to boot the encrypted root directory without a separate boot partition even with pbkdf2. Resizing an encrypted partition is a pain in the ass and the in-place encryption took 4 hours, so I decided to reinstall ubuntu 24.04 anyway. Let me be clear: I did not lose any data in the process (except the files that I didn't bother copying over).

TL;DR: Create a boot partition before resizing and make sure that you can boot from an unencrypted installation first, before starting with the encryption step.

So here is a completely untested guide for people who want to setup grub beforehand. (basically follow this guide [0])

Here is the high level summary:

  1. Boot a Ubuntu Live-USB
  2. Shrink/Resize your root partition by 2GiB (you can use the disks utility if you want)
  3. Create a 2 GiB boot partition (disks utility works too)
  4. Create a ext4 filesystem on the boot partition (again, whatever tool of your choice)
  5. Mount the root fileystem on /mnt/main, the new boot partition on /mnt/boot
  6. Copy files over cp -a /mnt/main/boot/* /mnt/boot/
  7. Edit /mnt/main/etc/fstab to mount the boot partition via UUID
  8. Unmount /mnt/boot and mount it on /mnt/main/boot
  9. Mount the efi partition under /mnt/boot/efi (depends on your setup)
  10. Rerun the grub install command with /mnt/main/ as root directory AND the efi directory (this will create a new boot entry on your motherboard) (if this doesn't work, consider using chroot [1] and don't forget to bind /sys recursively, umount --lazy *)

If you can boot using the new boot entry, then I would recommend you to boot back into the Live-USB and mount the root filesystem and just move the original /boot to /boot2, then go back to see if you can still boot, if yes, delete /boot2.

Now you are ready to run encrypt.sh from a Live-USB and do an in-place encryption of your root fileystem. Always make a backup first. This step can take several hours.

Okay, but now your disk is obviously encrypted. Your grub2 setup will break again. You need to remount all your partitions (possibly chroot), update /etc/fstab and /etc/crypttab preferrably via UUID. Set GRUB_ENABLE_CRYPTODISK=y and do grub-install again.

[0] https://help.ubuntu.com/community/CreateBootPartitionAfterInstall
[1] German Chroot Guide: https://wiki.ubuntuusers.de/chroot/Livesystem/ (couldn't find a better guide specifically for ubuntu in english, just use it as a reference for the commands)
Guide for ArchLinux: https://wiki.archlinux.org/title/Chroot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment