On Wed, Dec 30, 2015 at 07:34:52AM +1000, Hans wrote:
> Hi,
> 
> Is it possible to fully encrypt a Gentoo system as can be done with 
> Fedora, Suse, Arch Linux, Debian and Ubunto without using a unencrypted 
> USB boot stick or unencrypted /boot partition?
> 
> If yes, where can I find instructions that really work on a BIOS only 
> box without UEFI, EFI, systemd using EXT4 file system?
> 
> Hans

I can confirm that it's entirely possible, as I've managed to do it with
my laptop.
I don't remember exactly how I did everything, but here are the main
points of my setup.

Each of the three disks in my laptop is set up with GPT partitions
(although it should work fine with plain old DOS-style partitions).

If you use GPT with BIOS, make sure you leave room for (and create) the
GRUB boot partition (which GRUB stores the stage 2 part of the
bootloader in, since the first stage is limited to only a few hundred
bytes by BIOS standards).
Use 4MiB, just to be safe (a couple MiB is cheap, anyway).
You can read about how to get it set up just right here:
<https://wiki.gentoo.org/wiki/GRUB2#Partitioning_for_BIOS_with_GPT>

Each disk has a LUKS partition.
GRUB2 supports both AES and Serpent (I have partitions of both)
encryption with LUKS, though I recommend AES.

If you look around on the Gentoo wiki, or around online, you can
probably find how to set up the encrypted partitions.
What I did was:

    cryptsetup luksFormat -v -c aes-xts-plain64 -h sha512 -y -s 512 \
    --use-random -i 4000 /dev/sda2

This sets the encryption and key derivation algorithms and key size to
pretty secure settings.
The 4000 is the number of milliseconds used to compute the encryption
key from your passphrase.
Feel free to increase/decrease as you like.
You can always change it later (you can add and remove encryption
passphrases from the partition with varying derivation times).

Your partitions will be decrypted at boot, but while setting this all
up, decrypt the partition manually with:

    cryptsetup luksOpen /dev/sda2 luks-system

This will ask for your passphrase, and open the partition as
/dev/mapper/luks-system.
If you have multiple disks like I do, just open them all and give them
different names.

On top of LUKS, I've got LVM, because it's all shiny and I like to
resize my partitions every few days without rebooting.
If you're not familiar with it, I recommend reading around in the wiki a
little.

Set up your opened encrypted partitions for LVM (as physical volumes
(PVs)) by running:

    pvcreate /dev/mapper/luks-system

If you have multiple disks, run that for each partition.

Now, create a volume group to hold all of your partitions by running:

    vgcreate sys_vg /dev/mapper/luks-system [...]

If you have any other disks, add them to the end of that command.
"sys_vg" will be the name of your volume group.
You can use pretty much anything, but I recommend suffixing it with
"_vg" so you're not risking collisions with other stuff in "/dev".
I like to use "HOSTNAME_vg" for mine.

(You may need to run `vgchange -a y` to get your system to load the new
volume group now; I don't quite remember.)

Now, create your partitions (logical volumes (LVs)) with:

    lvcreate -L 8GiB -n rootfs sys_vg

Replace "8GiB" with whatever partition size you want, and "rootfs" with
whatever you want to name that partition.
I recommend avoiding '-' in the partition name (and volume group name),
as it sometimes escapes them (?) by turning them into "--", but only in
some places.

The LVs will be in /dev/YOUR_VOLUME_GROUP_NAME.
So, for example, the above will create "/dev/sys_vg/rootfs" as your
logical volume.

At the very least, you'll want a boot partition, a swap partition, and a
root partition.

Try to leave them smaller, rather than using up all of the free space.
With LVM, you can grow filesystems (at least, EXT4 and such) online
(that is, without unmounting and/or rebooting).

(That's because LVM maps blocks between the partition that software
sees, and the (encrypted) PVs.
So, logical volumes don't necessarily need to be contiguous, or even on
the same disk.
LVM takes care of that transparently.)

Leave room in case you want to change your partitioning later, or give a
virtual machine its own LV or something.

Format your filesystems just like in the Gentoo Handbook:

    mkfs.ext4 -L rootfs /dev/sys_vg/rootfs
    mkfs.ext4 -L boot /dev/sys_vg/boot
    mkswap -L swap /dev/sys_vg/swap

Then, mount them just like in the Gentoo Handbook and add them to your
fstab.
(Obviously, use /dev/sys_vg/* instead of /dev/sd?* when mounting.)

All of that is a pretty standard LVM/LUKS setup (except for /boot on
LVM/LUKS).

Now, when you compile your kernel, make sure to enable all of the device
mapper, LVM, and encryption features you need.
If you're not sure what you need, poke around on the Gentoo wiki pages
for LVM and/or LUKS.
You can compile them as either modules or built-in (I use modules),
since you'll need an initramfs anyway.

For your initramfs, I recommend using dracut.

I can't quite remember exactly what everything I did in my dracut
configuration was for, but here are some of the important looking bits
(in /etc/dracut.conf):

    
    add_dracutmodules+="bash crypt lvm udev-rules usrmount"
    hostonly="no"
    lvmconf="yes"
    persistent_policy="by-uuid"
    use_fstab="yes"

(If you get stuff about dracut being unable to find /dev/disk/by-uuid/*
when it tries to mount your /usr when booting after all of this, you may
want to change the persistent_policy (see the dracut.conf man page).
For some reason it keeps doing this to me, and I don't quite know why.
If it does happen to you, just run `e2fsck /dev/sys_vg/usr` to check the
filesystem and `mount -o ro /dev/sys_vg/usr /sysroot/usr` to mount it.)

You can build your initramfs by running:

    dracut -v --xz -f --kver KERNEL_VERSION

Substitute KERNEL_VERSION for the release version of your kernel (if
it's named in a standard way).
You can take out the "--xz" flag if you want, it just compresses the
initramfs.
If you leave it in, however, make sure you compile XZ compressed
initramfs support into your kernel (it should be with the other
initramfs options).

I don't know how everyone else does it, but here's the one-liner (well,
it was one line before I broke it up to fit it here) I use to build and
install my kernel/initramfs:

    (mount /boot;
    make all &&
    make modules_install &&
    cp -v .config "/boot/config-$(make kernelrelease)" &&
    cp -v "$(make image_name)" "/boot/vmlinuz-$(make kernelrelease)" &&
    dracut -v --xz -f --kver "$(make kernelrelease)" &&
    grub2-mkconfig -o /boot/grub/grub.cfg)

(Wrapping it all in parentheses runs it in a sub-shell, so you can use
C-Z to suspend and resume the entire set of commands, rather than just
the currently running one (which wouldn't run the rest)).

When you build and install sys-boot/grub:2, make sure you have the
device-mapper USE flag enabled.
(I also have the mount USE flag enabled for it, and I'm too lazy to look
up right now whether that will be necessary or not, but it doesn't hurt
to enable it anyway.)

Now comes the important part: configuring GRUB.
(This part actually took me the longest to figure out, primarily because
whatever guide I was originally following a year or two ago said the
important option was GRUB_CRYPTODISK_ENABLE instead of
GRUB_ENABLE_CRYPTODISK.
Either that, or I misread it.)

This will probably give you a good explanation:
<http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/>.
Just ignore the Arch Linux bits.

In addition to whatever else you add to your GRUB configuration, here's
the lines to enable GRUB to understand your disks, and load things from
your boot partition (which is on top of LVM on top of LUKS).
(You'll want this in /etc/default/grub):

    GRUB_ENABLE_CRYPTODISK=y
    GRUB_PRELOAD_MODULES="cryptodisk crypto gcry_rijndael gcry_sha512 
gcry_serpent luks lvm"

The first line tells GRUB to use your boot partition, even though it's
encrypted.
The second will preload the necessary cryptographic modules (and LVM)
into the stage 2 bootloader.
If you used different algorithms than AES, SHA-512, and Serpent, make
sure to add their gcry_* modules here.
The modules are in /usr/lib/grub/i386-pc/ and/or /boot/grub/i386-pc/ if
you need to find their exact names.

Now, you'll need to add some stuff to the kernel command line so that
dracut can find and set up your partitions properly.
(Add this to /etc/default/grub as well):

    GRUB_CMDLINE_LINUX="rd.luks.uuid=luks-LUKS-PART-UUID rd.lvm.vg=sys_vg 
root=/dev/sys_vg/rootfs rootfstype=ext4 rd.shell rd.info"

The first part (rd.luks.uuid) tells dracut which LUKS partitions to
open.
Replace "LUKS-PART-UUID" with whatever UUID you get from running:

    blkid /dev/sda3

So, you'll have, for example,
"rd.luks.uuid=luks-c972bd1a-64c4-439c-ac34-fb996328ca7d".

If you have multiple disks, just use repeat that for each disk
(rd.luks.uuid is cumulative).
So, you'd have "rd.luks.uuid=luks-UUID1 rd.luks.uuid=luks-UUID2 ...".

The rd.lvm.vg part of the command line tells dracut the name of the
volume group to open.
It will be able to find it after opening all of the encrypted
partitions.
(I'm not sure if having it after the rd.luks.uuid parts was significant
or not, so you may want to leave it after.)

The "root" part of the command line just tells dracut what your root
partition will be after it's done loading all of this.
The "rootfstype" specifies the file system type, and I'm pretty sure
it's not necessary.

The "rd.shell rd.info" part you may want to keep.
The first part will drop you into a shell if something goes wrong, and
the latter will print enough text to give you a hint as to what went
wrong.

Now, with all of the configuration done, it's time to install GRUB to
your boot partition.

First, generate your GRUB configuration with:

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

Make sure it finds your kernel and initramfs.
(It should say when it finds each).

Now, for the final step, install GRUB to your disk with:

    grub2-install /dev/sda

It should say that it installed everything successfully.
If it doesn't, or if you want to make sure, add the "-v" flag and scroll
back up through it to make sure it found all of the LUKS and LVM stuff.

You should be good to go now.

When you reboot, GRUB will immediately prompt you for the passphrase for
each of your LUKS partitions (or your one LUKS partition).
After you enter it, you should end up in GRUB 2, just as normal.

When GRUB loads the kernel (and dracut), dracut will prompt you for your
passphrase again for each LUKS partition (because it doesn't have the
keys that GRUB derived and used).
This is more of a minor inconvenience unless you reboot a lot (and the
page I linked to had some ideas on how to get around this).

Afterward, the initramfs should load up the rest of your system as
usual.
I don't use systemd, so I can't help you on that part, but if you read
around the Gentoo wiki (and other sources) about systemd and dracut, you
should be able to figure that part out.

(Also, if the initramfs has issues finding something, it should, again,
drop you into a shell.
You can then just mount the filesystem manually.)

I hope this helps.
It ended up a little longer than I planned, but it should be helpful at
least to me in a couple more years when I can't remember how I did this
in the first place.

Alex

Attachment: signature.asc
Description: PGP signature

Reply via email to