Arch-linux: Remote unlock root-volume with mdraid and dmcrypt

Posted on Sun 26 February 2017 in linux

Intro

Some time ago I decided to switch my dedicated server from debian to arch, since it was the last of my machines to run on debian. whether or not it's a good idea to use arch on a dedicated server is up for you to decide.

I've got to the point where everything was installed but the server was not booting, and with no access to the boot console I gave up on that idea and used one of the images provided by OVH.

Today I was in the mood again and give it a go, so I've fired up a VM and gave it a try again.

This time I got lucky.

This will be the final layout of the System:
  • /dev/sda
    • /dev/sda1 1gb boot
    • /dev/sda2 100% /dev/md0
  • /dev/sdb
    • /dev/sdb1 1gb boot
    • /dev/sdb2 100% /dev/md0
  • /dev/md0
    • /dev/mapper/root
      • /

As you've probably noticed: there is no swap partition. I don't see the point in a dedicated swap partition on a server. I'll probably adding a swapfile later.

Now to the fun stuff

Preparing the Filesystems

# partition the discs
parted /dev/sda --align=opt --script mklabel msdos mkpart primary 0% 1GiB mkpart primary 1GiB 100%
parted /dev/sdb --align=opt --script mklabel msdos mkpart primary 0% 1GiB mkpart primary 1GiB 100%

# creating the filesystems, actually only /dev/sda1 is needed
mkfs.ext4 -L boot /dev/sda1
mkfs.ext4 -L boot /dev/sdb1

# creating the raid
mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md0 /dev/sda2 /dev/sdb2

# and creating the dmcrypt "container"
cryptsetup -y -v luksFormat /dev/md0
cryptsetup luksOpen /dev/md0 root

# finally create the root filesystem
mkfs.ext4 -v -L root -m 0.01 -b 4096 -E stride=128,stripe-width=256 /dev/mapper/root

Preparing for Arch

mkdir /arch
cd /arch
# download arch bootstrap disc, please choose the correct version
curl -O http://archlinux.mirrors.ovh.net/archlinux/iso/2017.02.01/archlinux-bootstrap-2017.02.01-x86_64.tar.gz
tar xvfz archlinux-bootstrap-2017.02.01-x86_64.tar.gz

Edit /arch/root.x86_64/etc/pacman.d/mirrorlist and choose a mirror

nano /arch/root.x86_64/etc/pacman.d/mirrorlist

Chroot into the bootstrap environment

/arch/root.x86_64/bin/arch-chroot /arch/root.x86_64/

More preparations

# mount the soon-to-be root-volume
mount /dev/mapper/root /mnt/

# and boot-volume
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

# initialize the pacman keychain this takes a long time do something from a second terminal, like dd if=/dev/sda of=/dev/tty7
pacman-key --init

Finally, bootstrap Arch onto the root-volume...

pacstrap /mnt base base-devel intel-ucode

And bootstrap mdadmin.conf (md configuration) and fstab

mdadm --detail --scan >> /etc/mdadm.conf
genfstab -p /mnt > /mnt/etc/fstab

Chroot into the new Arch installation

arch-chroot /mnt/

Setup hostname and locales

echo test > /etc/hostname

echo LANG=en_US.UTF-8 > /etc/locale.conf
echo LC_COLLATE=C >> /etc/locale.conf
echo LANGUAGE=en_US >> /etc/locale.conf

ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Edit locale.gen according to your locale, don't forget en_US.UTF-8 or else some applications might complain.

nano /etc/locale.gen

locale-gen

Setup early ssh with tinyssh and netconf

# some dependencies
pacman -S sudo mkinitcpio-nfs-utils tinyssh ucspi-tcp
cd /tmp

Install mkinitcpio-netconf

curl -O https://aur.archlinux.org/cgit/aur.git/snapshot/mkinitcpio-netconf.tar.gz
tar xf mkinitcpio-netconf.tar.gz
chown -R nobody:nobody mkinitcpio-netconf
cd mkinitcpio-netconf
sudo -u nobody makepkg

pacman -U mkinitcpio-netconf-0.0.4-2-any.pkg.tar.xz

cd ..

Install ucspi-tcp

curl -O https://aur.archlinux.org/cgit/aur.git/snapshot/ucspi-tcp.tar.gz
tar xf ucspi-tcp.tar.gz
chown -R nobody:nobody ucspi-tcp
cd ucspi-tcp
sudo -u nobody makepkg

pacman -U ucspi-tcp-0.88-8-x86_64.pkg.tar.xz

cd ..

Install mkinitcpio-tinyssh

curl -O https://aur.archlinux.org/cgit/aur.git/snapshot/mkinitcpio-tinyssh.tar.gz
tar xf mkinitcpio-tinyssh.tar.gz
chown -R nobody:nobody mkinitcpio-tinyssh
cd mkinitcpio-tinyssh
sudo -u nobody makepkg

pacman -U mkinitcpio-tinyssh-0.0.3-3-any.pkg.tar.xz

cd ..

Install mkinitcpio-utils

curl -O https://aur.archlinux.org/cgit/aur.git/snapshot/mkinitcpio-utils.tar.gz
tar xf mkinitcpio-utils.tar.gz
chown -R nobody:nobody mkinitcpio-utils
cd mkinitcpio-utils
sudo -u nobody makepkg

pacman -U mkinitcpio-utils-0.0.3-3-any.pkg.tar.xz

cd ..

Edit /etc/mkinitcpio.conf and add "dadm_udev netconf tinyssh encryptssh" before filesystems should look something like this

HOOKS="base udev autodetect modconf block mdadm_udev netconf tinyssh encryptssh filesystems keyboard fsck"

Rebuild the initramfs

mkinitcpio -p linux

Insatll and configure GRUB

pacman -S grub

Edit /etc/default/grub and tell the Kernel about the cryptdevice and the mdraid, and netconf that we want dhcp

GRUB_CMDLINE_LINUX="cryptdevice=/dev/md0:root ip=dhcp md=0,/dev/sda2,/dev/sdb2"

Generate the grub config

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

Install Grub to /dev/sda

grub-install /dev/sda

Done

Don't forget to change your root passwort:

passwd

You should now be able to reboot into the new system, just exit the chroots and unmount the filesystems on the way out.

Anyhow it's probably a good idea to install and enable ssh or else you would have no access beyond the unlocking

pacman -S openssh
systemctl enable sshd

and configure it to your taste, rootlogin, publickey authentication etc..

Conclusion

Well, that wen't a lot better than the last time, also on the first try. Maybe that's because I'm not using LVM this time.