This post represents the steps to perform full disk encryption on Arch Linux using LVM and LUKS, given that I already had a tarball copy of a working Arch Linux machine. These steps were done on my old laptop with the BIOS boot system, so if you are using UEFI system, there may be some differences (grub installation). Please note that, the /boot partition won't be encrypted though.


First, use gparted to create the first partition (sda1) for /boot partition, about 300 MB in size should be more than enough, file system FAT32 (vfat), set the flag to boot.

Next, create second partition (sda2) which is used to store the rest of the whole system data including the root / and /home partition, use all the remaining space for this partition and leave the file system as unformatted, the label is optional, set the flag to lvm.

Then, boot the computer from a USB thumbdrive or an external hard-drive which contains a working Arch Linux operating system (I prefer to use Arch Linux distro as much as possible, but you can use any live distro to proceed further).

Create LVM and encrypt with LUKS

Now, let's encrypt the big (second) partition:

sudo cryptsetup -c aes-xts-plain64 -y -s 512 luksFormat /dev/sda2

Open it with:

sudo cryptsetup luksOpen /dev/sda2 lvm

Check if the lvm volume is opened correctly:

sudo fdisk -l

Create a physical volume:

# pvcreate /dev/mapper/lvm

Create volume group main:

# vgcreate main /dev/mapper/lvm

Create logical volume for / partition:

# lvcreate -L 39GB -n lvroot main

Create logical volume for /home partition with the remaining space:

# lvcreate -l 100%FREE -n lvhome main

Make ext4 file system for the 2 logical volumes of / and /home and reserve only 1% of space during formatting:

# mkfs.ext4 -m 1 /dev/mapper/main-lvroot
# mkfs.ext4 -m 1 /dev/mapper/main-lvhome

Restore the tarball copy and other personal data

  • Mount the lvroot volume: # mount /dev/mapper/main-lvroot /mnt
  • Copy the backed up tar archive from the working Arch Linux machine to /mnt
  • Change dir: cd /mnt
  • Untar it: # tar -xvpzf arch-backup.tar.gz --numeric-owner
  • Mount /home partition: # mount /dev/mapper/main-lvhome /mnt/home. Then copy data and dot files from the old machine over.
  • Mount /boot partition: # mount /dev/sda1 /mnt/boot. Then copy the old /boot partition to /mnt/boot

Perform chroot and other important settings:

Add keymap encrypt lvm2 (in that order!) to /mnt/etc/mkinitcpio.conf between block and filesystems

HOOKS="base udev autodetect modconf block keymap encrypt lvm2 filesystems keyboard fsck"

Install arch-chroot script to the host Arch Linux OS:

sudo pacman -S arch-install-scripts

Setup some mount points ( reference )

# mount -t proc none /mnt/proc
# mount -t sysfs none /mnt/sys
# mount -o bind /dev /mnt/dev
# mount -o bind /dev/pts /mnt/dev/pts  (important for pacman (for signature check))
cp -L /etc/resolv.conf /mnt/etc  (this is needed to use networking within the chroot)

If we issue command lsblk -f now, the following info (or similar) should be displayed:

lsblk -f
NAME              FSTYPE      LABEL   UUID                                   MOUNTPOINT
├─sda1            vfat        boot    88B0-3D1E                              /mnt/boot
├─sda2            crypto_LUKS         4f655e50-3660-49c1-9dad-155fa2a39dfd
│ └─lvm           LVM2_member         yDYDSC-yh0q-etS2-JeMf-QSfk-ufvB-ETRQLl
│   ├─main-lvroot ext4                f4c409b6-ef76-436c-ad67-48e75cac95e2   /mnt
│   └─main-lvhome ext4                c276a7de-b816-4f8e-97f5-eeb456ce773c   /mnt/home
└─sda3            ntfs        Storage 63ED391174748B3C
├─sdc1            vfat        ESP     68EE-7E11                              /boot
├─sdc2            ext4        lttroot bfa8127d-9b33-4dbf-815c-a4c5cd57788a   /
├─sdc3            crypto_LUKS         3d3bd39f-9ba7-4bef-87b5-067225f2db4b
│ └─phome         ext4                a4ee7104-e405-42c4-87d6-a7612f89d3c3   /home
└─sdc4            vfat        FATDATA 97EF-3B76

where sda is the internal hard-drive that we want to install Linux into, sdc is the external hard-drive that contain Arch Linux and was used to boot the marchine to perform all the taks so far.

Now we chroot to our new system on /mnt:

# chroot /mnt bash

In the chroot environment, the lsblk -f command will display something like this:

lsblk -f
├─sda1                              /boot
│ └─lvm
│   ├─main-lvroot                   /
│   └─main-lvhome                   /home
│ └─phome

where sda is the internal hard-drive of the computer, sdc is the external hard-drive that was used to boot the computer to perform all the tasks so far.

Within the chroot environment, create initial RAM disk:

# mkinitcpio -p linux

Take note that the Linux kernel version of /mnt and /mnt/boot must be the same, otherwise this error will be thrown:

mkinitcpio -p linux
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
==> ERROR: '/lib/modules/3.8.11-1-ARCH' is not a valid kernel module directory
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'fallback'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux-fallback.img -S autodetect
==> ERROR: '/lib/modules/3.8.11-1-ARCH' is not a valid kernel module directory

Now, in the chroot environment, install GRUB for BIOS boot system, make sure it is installed to sda, NOT sdb:

# grub-install --target=i386-pc --root-directory=/ --recheck --debug /dev/sda

In /etc/default/grub edit the line GRUB_CMDLINE_LINUX="" to GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda2:main" then run:

# grub-mkconfig -o /boot/grub/grub.cfg

After that, add a menu entry in /boot/grub/grub.cfg with something like this:

menuentry 'Arch Linux' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-f4c409b6-ef76-436c-ad67-48e75cac95e2' {
    set gfxpayload=keep
    insmod gzio
    insmod part_msdos
    insmod fat
    set root='hd0,msdos1'
    if [ x$feature_platform_search_hint = xy ]; then
      search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1  88B0-3D1E
      search --no-floppy --fs-uuid --set=root 88B0-3D1E
    echo    'Loading Linux linux ...'
    linux   /vmlinuz-linux root=UUID=f4c409b6-ef76-436c-ad67-48e75cac95e2 rw cryptdevice=/dev/sda2:main quiet
    echo    'Loading initial ramdisk ...'
    initrd  /intel-ucode.img /initramfs-linux.img

Then, exit chroot: exit

Finish up:


# umount /mnt/boot
# umount /mnt/home
# umount/mnt

We should not need any entry in /mnt/etc/cryptab anymore.

View and edit /mnt/etc/fstab accordingly



My working environment set up with bspwm, zsh, urxvt, tmux and vim on Arch Linux

(Select `720p` (or `1080p`) HD video quality and watch in full screen mode if you want to see the commands)This video showcases my latest...… Continue reading

Jekyll blog on Amazon S3

Published on February 13, 2015