Introduction and warning
This tutorial is a recap on an adminsys operation made in march 2026 with other yunohost.pro adminsys. I think it could be useful for some people so i have documented it here.
This tutorial is quite advanced, freshly written, you should understand what you do in order to be able to debug. Make backup AND snapshot before everything else… Shrinking filesystem and partition may result in data loss if proper precautions are not taken.
Feel free to contribute if you discover some mistakes or misunderstood.
If you have a physical server or other kind of vps, this tuto could work too, however you should be careful with partition number and partition order.
Why encrypt a VPS (or a physical server) ? Which additional actions should be done
For data security offcourse. Encrypt your disk make harder to explore the data inside your VPS.
Note that if it’s a VPS (and not a physical hardware under your control) it’s probably possible for your hoster to find LUKS key inside a dump of your RAM.
Note that, encrypt your disk is really not useful if you let some tools running inside your system like qemu-guest-agent or if you have hoster public key configured in a user… So you have to remove qemu-guest-agent
apt remove qemu-guest-agent
Note: some features like root password reinit or graph monitoring inside your hoster web console won’t be able to work anymore.
And check authorized_keys
cat /root/.ssh/authorized_keys
cat /home/debian/.ssh/authorized_keys
cat /home/USER/.ssh/authorized_keys
May be the cloudinit config should be checked to, to avoid the hoster to be able to trigger it again and replace a password for example…
Prerequisite
- A VPS build with cloudinit image (for example with proxmox or openstack), your partition should be like
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 5G 0 disk
├─sda1 8:1 0 4.9G 0 part /
├─sda14 8:14 0 3M 0 part
└─sda15 8:15 0 124M 0 part /boot/efi
- A rescue mode allowing you to mount vps disk on another system
IMPORTANT: allmost all actions should be run in rescue mode, it’s possible that your disk is called /dev/sdb instead of /dev/sda in that context, you should adapt things…
1. Create a /boot partition
First of all, you need to create a /boot partition, this operation is quite risky cause you probably should reduce the size of / partition in order to have space for creating /boot partition.
Here we suggest to allocate 1G to /boot but it can be smaller, you probably should clean /boot more regularly if you do.
Reduce the size of /dev/sda1 ext4 file system
First check you have more than 1GB available on /dev/sda1
$ df -h /dev/sda1
Get exact number of bytes for the partition
$ parted -s -a opt /dev/sda1 "unit b print"
Model: Unknown (unknown)
Disk /dev/sda1: 5234474496B
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0B 5234474495B 5234474496B ext4
Important: as we mention /dev/sda1 instead of /dev/sda we have the relative end (from the start) and not the end of the partition in absolute position in the disk…
Note: here i prefer to work with bytes, cause it could be confuse between GiB and GB when you use resize2fs and parted…
Remove 1GiB from the End value (here 5234474495B)
5234474495 - 1024*1024*1024 = 4160732671
Resize the FS
resize2fs /dev/sda1 4160732671B
Reduce the partition size of /dev/sda1
Display your partition number and the start and end in the disk
$ parted -s -a opt /dev/sda "unit b print free"
Model: QEMU QEMU HARDDISK (scsi)
Disk /dev/sda: 5368709120B
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
17408B 1048575B 1031168B Free Space
14 1048576B 4194303B 3145728B bios_grub
15 4194304B 134217727B 130023424B fat16 boot, esp
1 134217728B 5368692223B 5234474496B ext4
Remove 1GiB from the End value (here 5368692223B)
5368692223 - 1024*1024*1024 = 4294950399
Resize the / partition (here sda1)
parted -s -a opt /dev/sda "resizepart 1 4294950399b"
Create /boot partition
parted -s -a opt /dev/sda "mkpart boot ext4 4294950400b 5368692223b"
Note: in my memories, it could be more complex if you have to align partition on sector/cylinder.
TODO: @lab.8916100448256 @Thatoo feel free to change this part of the tutorial if you remember it
Create /boot ext4 filesystem
mkfs.ext4 -L boot /dev/sda2
2. Move old /boot into the new one
Mount filesystems:
mkdir /mnt/system
mkdir /mnt/boot
mount /dev/sda1 /mnt/system
mount /dev/sda2 /mnt/boot
And move the files to the new /boot
mv /mnt/system/boot/* /mnt/boot/
3. Encrypt /
Make the filesystem slightly smaller to make space for the LUKS header
Run a filesystem check
e2fsck -f "/dev/sda1"
Compute new filesystem size. Be sure dumpe2fs is installed
BLOCK_SIZE=`dumpe2fs -h /dev/sda1 | grep "Block size" | cut -d ':' -f 2 | tr -d ' '`
BLOCK_COUNT=`dumpe2fs -h /dev/sda1 | 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))
IMPORTANT: before resizing, check that $BLOCK_SIZE $BLOCK_COUNT $SPACE_TO_FREE and $NEW_BLOCK_COUNT are not empty. If it’s empty, you check dumpe2fs is installed.
echo "$BLOCK_SIZE , $BLOCK_COUNT , $SPACE_TO_FREE , $NEW_BLOCK_COUNT"
Resize the filesystem
resize2fs -p "/dev/sda1" "$NEW_BLOCK_COUNT"
Run the encryption process
apt install cryptsetup
cryptsetup reencrypt --encrypt --reduce-device-size 16M "/dev/sda1"
Resize the filesystem to fill up the remaining space
cryptsetup open "/dev/sda1" recrypt
resize2fs /dev/mapper/recrypt
cryptsetup close recrypt
4. Chroot the VPS system
apt install cryptsetup -y
cryptsetup open /dev/sda1 crypt-root
mkdir /mnt/system
mount /dev/mapper/crypt-root /mnt/system
mount /dev/sda2 /mnt/system/boot
mount /dev/sda15 /mnt/system/boot/efi
mount --bind /dev /mnt/system/dev
mount --bind /dev/pts /mnt/system/dev/pts
mount --bind /proc /mnt/system/proc
mount --bind /sys /mnt/system/sys
chroot /mnt/system
5. Update crypttab, fstab and update grub
Disable linux UUID and PARTUUID in grub (you want /dev/mapper/crypt-root to be used)
Add a file to be sure linux UUID and PARTUUID are disabled in grub
/etc/default/grub.d/99_custom.cfg
# Use PARTUUID instead of UUID for root=
GRUB_DEVICE=/dev/mapper/crypt-root
GRUB_DISABLE_LINUX_UUID=true
GRUB_DISABLE_LINUX_PARTUUID=true
Update /etc/crypttab
Crypttab lists which disks should be decrypt at boot.
# <target name> <source device> <key file> <options>
crypt-root UUID=aaaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeee none luks
With aaaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeee replaced by the result of blkid -s UUID -o value /dev/sda1
Note: if you want to decrypt 2 disks instead of 1, you should install keyutils with apt install keyutils and add ,keyscript=decrypt_keyctl at the end of each lines in /etc/crypttab
Update /etc/fstab
/dev/mapper/crypt-root / ext4 rw,discard,errors=remount-ro,x-systemd.growfs 0 1
PARTUUID=aaaaaaaaaaaaaa /boot ext4 rw,discard,errors=remount-ro,x-systemd.growfs 0 1
PARTUUID=bbbbbbbbbbbbb /boot/efi vfat defaults 0 0
Replace aaaaaaaaaaaaaa by the result of blkid -s PARTUUID -o value /dev/sda2
Replace bbbbbbbbbbbbb by the result of blkid -s PARTUUID -o value /dev/sda15
Update grub
update-grub2
Be sure it worked by running this command, it should return some lines
grep "root=/dev/mapper/crypt-root" /boot/grub/grub.cfg
6. Configure Dropbear, an ssh service to decrypt your disk
At this step, if you restart your VPS, you should be able to decrypt it with a VNC console, however VNC could be unencrypted / unauthenticated and is not really safe to decrypt your disk through it.
That’s why , we want a more secure way to do it, like an authenticated ssh service. However you can’t do it with openssh cause the service is not running cause your disk in not decrypted, you have to setup this service into the initramfs run earlier in the boot process… Dropbear is an ssh service dedicated to do this operation.
Note that a cryptroot-unlock package exists to do those operation however network config could be not totaly ok. Bellow are manual operations:
apt install busybox dropbear-initramfs initramfs-tools
Write your public ssh key into /etc/dropbear/initramfs/authorized_keys
Configure a dedicated SSH port for dropbear (distinct of openssh port) and run cryptroot-unlock automatically.
/etc/dropbear/initramfs/dropbear.conf
echo 'DROPBEAR_OPTIONS="-I 180 -j -k -p 2222 -s -c cryptroot-unlock"' >> /etc/dropbear/initramfs/dropbear.conf
Edit your /etc/initramfs-tools/initramfs.conf with good network config, think to replace <VARIABLE> by good values.
echo "ip=<PUBLIC_IP>::<PUBLIC_GATEWAY>:<MASK>:<FULL_HOSTNAME>:off:<IP_DNS_RESOLVER1>:<IP_DNS_RESOLVER2>" >> /etc/initramfs-tools/initramfs.conf
Ensure the keyboard layout is usable with your keyboard in /etc/default/keyboard (example for french keyboard)
XKBMODEL="pc105"
XKBLAYOUT="fr"
XKBVARIANT="latin9"
Update initramfs
update-initramfs -k all -u
Enjoy (or not)
Now, you can try to restart out of rescue mode and connect with SSH through the port 2222, you should be able to uncrypt your disk by providing passphrase and next to ssh with your standard port.
If yes you succeed to encrypt your / partition congratulations
.
External ressources
Williamdes's blog - Encrypt an existing Debian 12 system with LUKS