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.