Encrypting WSL2 disks
Written May 7, 2022
Why
Reason #1: If you are using Windows 10/11 Professional, you can enable bitlocker support, which will encrypt your entire Windows disk at rest. While a good idea, it still makes me slightly nervous that any Windows program can access all my Linux files. Let's encrypt all your important files within WSL so Windows can't see or read them, most of the time anyway.
Reason #2: This makes backups A LOT easier. All you need to backup is the disk image file, and it contains all your important files, and it's already encrypted.
How
We are going to use a couple tricks for this, the first is a loopback device, which allows you to mount a single file, and treat it like a device. The second will be to use LUKS (Linux Unified Key Setup) to create an encrypted device on top of the loopback mount.
Create a disk image
I will be mounting this device as my home directory, so I'll need a place outside my home directory to put it.
sudo install -o ${USER} -g ${USER} -d "/home/.${USER}"
Next we need to do a bit of math. Your typical ext4 filesystem uses 4kB block sizes. Pretend I want a 7 GB disk image. The dd
command I would run is:
dd if=/dev/zero of="/home/.${USER}/disk.img" bs=4k count=1835008
where 1835008 = 7GB x 1024MB/GB x 1024 MB/kB / 4 kilobytes
This command might take about 40 seconds to run, even on a very fast SSD.
Tip: While it can be tempting to mount a file that lives inside Windows, it will be really slow. Read/writing from WSL2 to Windows is slow, so keep everything inside WSL2 for maximum performance.
Setup the loopback device
sudo losetup /dev/loop0 "/home/.${USER}/disk.img"
Encrypt the disk with a good password
sudo cryptsetup -q luksFormat -y /dev/loop0
# ignore the warning about /run/cryptsetup
Setup the decrypted block device
sudo cryptsetup open /dev/loop0 loop0
Format the decrypted block device
sudo mkfs.ext4 /dev/mapper/loop0
Finally, mount it over your existing home directory
sudo mount /dev/mapper/loop0 "/home/${USER}"
The first time, you'll need to fix the permissions
sudo chown "${USER}:${USER}" "/home/${USER}"
Since your home has changed, get a new bash session
bash -l
cd
All done!
Here are a couple helper scripts:
mount_my_home.sh
#!/bin/bash
sudo echo -n
cd /
sudo losetup /dev/loop0 "/home/.${USER}/disk.img"
sudo cryptsetup open /dev/loop0 loop0
sudo mount /dev/mapper/loop0 "/home/${USER}"
echo 'Home successfully mounted, now type:'
echo bash -l
echo cd
unmount_my_home.sh
#!/bin/bash
cd /
sudo umount /home/${USER}
sudo cryptsetup close loop0
sudo losetup -d /dev/loop0
Source
This is a version of https://gist.github.com/dbehnke/ad19ca8f1ccf80aebca5 with some added commentary and organization.