Installing Gentoo with GRUB2, GPT, LUKS and software raid (mdraid/mdadm)

So for various reasons I wanted to install Gentoo utilizing full disk encryption with luks (except for /boot ofc), mdraid, gpt and grub2.

I’m mostly writing this for myself as copy/paste kind of notes, but posting it in case anyone else is looking to do the same kind of installation too, and maybe this will save you some time.

These notes assume you’ve done your fair share of Gentoo installations, although as almost everything is copy/paste you could probably survive anyway.

Begin by downloading a Gentoo install cd (install-amd64-minimal-20130509.iso used at the time of writing) and boot it up.

Configure the network and power up ssh.

ifconfig enp1s0f0 192.168.0.2 netmask 255.255.255.0
route add default gw 192.168.0.1
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
passwd root
/etc/init.d/sshd start

Prepare the partitions, I’m going to create a small 2MB partition at the beginning for GRUB2 to reside on, ~94MB for /boot, ~2GB swap, ~2GB /tmp and the rest for /.

parted -a opt /dev/sda
mklabel gpt
mkpart primary ext2 1 2mb
mkpart primary ext2 2mb 96mb
mkpart primary ext2 96mb 2144mb
mkpart primary ext2 2144mb 4192mb
mkpart primary ext2 4192mb -1s (just answer Y when prompted)
name 1 grub
name 2 boot
name 3 swap
name 4 tmp
name 5 root
set 1 bios_grub on
set 2 raid on
set 3 raid on
set 4 raid on
set 5 raid on

Make sure you make the partitions identical on the second drive.
parted -a opt /dev/sdb
[…]
Now lets create the raid arrays, setting the –name makes us able to completely skip the need for a mdadm.conf later on, which I find much smoother.
We can also use the 1.2 metadata version on all arrays (including root) without problems, as we’re going to use GRUB2.

mdadm --create --name=server:boot --verbose /dev/md1 --level=1 --raid-devices=2 /dev/sda2 /dev/sdb2
mdadm --create --name=server:swap --verbose /dev/md2 --level=1 --raid-devices=2 /dev/sda3 /dev/sdb3
mdadm --create --name=server:tmp --verbose /dev/md3 --level=1 --raid-devices=2 /dev/sda4 /dev/sdb4
mdadm --create --name=server:root --verbose /dev/md4 --level=1 --raid-devices=2 /dev/sda5 /dev/sdb5

Encrypt and open root.

cryptsetup --verify-passphrase luksFormat -c aes-xts-plain64 /dev/md4
cryptsetup luksOpen /dev/md4 root

Mount swap, format /boot and /. If you’re concerned by an unencrypted swap during the installation, skip that part 🙂
mkswap /dev/md2 && swapon /dev/md2
mkfs.ext2 /dev/md1
mkfs.xfs /dev/mapper/root

Some usual Gentoo installation steps..
mount /dev/mapper/root /mnt/gentoo
cd /mnt/gentoo/
mkdir boot
mount /dev/md1 /mnt/gentoo/boot

Get desired stage3 from http://mirrors.kernel.org/gentoo/releases/amd64/autobuilds/

wget http://mirrors.kernel.org/gentoo/releases/amd64/autobuilds/....tar.bz2
tar xvjpf stage3-*.tar.bz2
rm -v stage3-*.tar.bz2

Initialize the portage tree.
wget http://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2
tar xvjf /mnt/gentoo/portage-latest.tar.bz2 -C /mnt/gentoo/usr
rm -v portage-latest.tar.bz2

For GRUB2, add the following to make.conf, also add some mirrors.

echo 'GRUB_PLATFORMS="pc"' >> /mnt/gentoo/etc/portage/make.conf
mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf
mirrorselect -i -r -o >> /mnt/gentoo/etc/portage/make.conf

More usual Gentoo steps..
cp -L /etc/resolv.conf /mnt/gentoo/etc/
cd /
mount -t proc none /mnt/gentoo/proc && mount --rbind /sys /mnt/gentoo/sys && mount --rbind /dev /mnt/gentoo/dev
chroot /mnt/gentoo /bin/bash
env-update && source /etc/profile && export PS1="(chroot) $PS1"
emerge --sync
eselect profile list

Generate some locales and configure UTF-8.
nano -w /etc/locale.gen
en_US.UTF-8 UTF-8
en_US ISO-8859-1
sv_SE.UTF-8 UTF-8
sv_SE ISO-8859-1

locale-gen

nano -w /etc/env.d/02locale
LANG="en_US.UTF-8"
LC_COLLATE="C"

Set your timezone.

cp /usr/share/zoneinfo/Etc/UTC /etc/localtime
echo "Etc/UTC" > /etc/timezone

Time for the kernel.

emerge hardened-sources
cd /usr/src/linux
make menuconfig

These are some essential options for our setup (enable AES-NI if your CPU supports it).

Device Drivers --->
Generic Driver Options --->
[*] Maintain a devtmpfs filesystem to mount at /dev

[*] Multiple devices driver support (RAID and LVM) --->
<*> RAID support
[ ] Autodetect RAID arrays during kernel boot
<*> RAID-1 (mirroring) mode
<*> Device mapper support
<*> Crypt target support

-*- Cryptographic API --->
-*- XTS support
<*> AES cipher algorithms (AES-NI)

make && make modules_install
cp arch/x86_64/boot/bzImage /boot/vmlinuz-3.8.6-hardened

Run blkid to get UUID, we need the one for /boot, which should be /dev/md1.

nano -w /etc/fstab
UUID=xxxxxxxxxxxxxxxxx /boot ext2 noauto,noatime 1 2
/dev/mapper/root / xfs relatime 0 1
/dev/mapper/cryptswap none swap sw 0 0
/dev/mapper/crypttmp /tmp xfs relatime,nodev,nosuid,noexec 0 0

More usual Gentoo yaddayadda

nano -w /etc/conf.d/hostname
hostname="server"

nano -w /etc/hosts
127.0.0.1 server.devshm.net server localhost
::1 server.devshm.net server localhost

hostname server
hostname -f

Configure the network.
nano -w /etc/conf.d/net
dns_domain="devshm.net"
dns_servers="8.8.8.8 8.8.4.4"

config_enp1s0f0="192.168.0.2/24"
routes_enp1s0f0="default via 192.168.0.1"

Set the new root password.
passwd
Change keymap if you need to.
nano -w /etc/conf.d/keymaps
keymap="se-lat6"

We want quite a bit of packages to use static-libs for our initrd to work.
nano -w /etc/portage/package.use
dev-libs/libgcrypt static-libs
dev-libs/libgpg-error static-libs
dev-libs/popt static-libs
sys-apps/util-linux static-libs
sys-fs/cryptsetup static static-libs udev
sys-fs/lvm2 static-libs
sys-fs/mdadm static
sys-fs/udev static-libs
sys-kernel/genkernel cryptsetup
sys-libs/e2fsprogs-libs static-libs
virtual/udev static-libs

And we absolutely want to use the newest GRUB.
nano -w /etc/portage/package.keywords
sys-boot/grub ~amd64

Emerge some essential packages.

emerge xfsprogs postfix syslog-ng vixie-cron logrotate
emerge mdadm
emerge cryptsetup

IF YOU’RE USING BROADCOM NICS.
emerge linux-firmware
Make sure stuff start at boot.
cd /etc/init.d/ && ln -s net.lo net.enp1s0f0
rc-update add net.enp1s0f0 default
rc-update add sshd default
rc-update add postfix default
rc-update add syslog-ng default
rc-update add vixie-cron default
rc-update add dmcrypt boot

Configure dmcrypt to encrypt swap and /tmp with one-time keys on each boot (pre_mount ref. https://bugs.gentoo.org/show_bug.cgi?id=288270).
nano -w /etc/conf.d/dmcrypt
swap=cryptswap
source='/dev/md/server:swap'
pre_mount='mkswap -f ${dev}'

## /tmp
target=crypttmp
source='/dev/md/server:tmp'
options='-c aes-xts-plain -h sha1 -d /dev/urandom'
pre_mount='mkfs.xfs ${dev}'
post_mount='chown root:root ${mount_point}; chmod 1777 ${mount_point}'

Almost done, emerge genkernel and create our initrd.
emerge genkernel
genkernel --install --luks --mdadm --no-ramdisk-modules initramfs

Emerge and configure GRUB.
emerge grub
nano -w /etc/default/grub
GRUB_CMDLINE_LINUX="domdadm rootfstype=xfs crypt_root=/dev/md/server:root"

Install GRUB on all devices and generate the config.

grub2-install /dev/sda
grub2-install /dev/sdb
grub2-mkconfig -o /boot/grub2/grub.cfg

That’s it, all done!
exit
cd
umount -l /mnt/gentoo/dev{/shm,/pts,}
umount -l /mnt/gentoo{/boot,/proc,/sys,}
reboot