I have been contemplating to update my Gentoo setup for quite a while now.
While my old one is still working it is completely based on a RAID1 with hard
disks, yes the spinning disk kind, and is becoming a bit slow. You can find
the details to my old setup here: Gentoo installation with raid, lvm, luks
and systemd. The new setup will incorporate
an SSD for performance and a big RAID1 to hold rarely accessed data as well as
backups.
Hardware
Naturally this description works for other configurations but for completeness
these are the disks I have in use
- 480GB SSD on /dev/sda
- 2TB HDD on /dev/sdb
- 2TB HDD on /dev/sdc
For all encrypted setups you should fill the whole disks with random data
before you start.
Planned Configuration
One of the main features of this setup will be that each user will have an
"archive" folder which will be automatically mounted. This way each user
profits from the SSD and has access to a lot of extra storage at the same
time.
Details:
- GPT partition layout for UEFI boot
- SSD with EFI System partition, encrypted root, encrypted swap and LVM volume
for user data
- RAID1 mirror with 2 identical disks and LVM to distribute space among the
users
- initramfs with plymouth to unlock the root device in graphics mode
- pam_mount to mount the home directories as well as the special "archive"
directory without having to enter the password again
This time I will go for GDM and GNOME 3 but this setup will work without it
just as well.
Preparation
If you already have a running Linux system on an unaffected drive, preferably
Gentoo, then you can do most of the steps from there. You usually only need a
LiveCD or USB stick for the GRUB installation.
Partitioning
Just like in my old setup we will use a GPT partition table and UEFI boot.
Parted for /dev/sda:
parted /dev/sda
(parted) mklabel GPT
(parted) mkpart boot fat32 0% 512M
(parted) set 1 boot on
(parted) mkpart root 512M 50G
(parted) mkpart swap ext2 50G 85G
(parted) mkpart users 85G -1
(parted) print
Model: ATA KINGSTON SHSS37A (scsi)
Disk /dev/sda: 480GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 512MB 511MB fat32 boot boot, esp
2 512MB 50.0GB 49.5GB root
3 50.0GB 85.0GB 35.0GB ext2 swap
4 85.0GB 479GB 396GB users
The first partition is the "EFI System Partition". It will reside in "/boot"
and hold our linux kernel(s). If you have more than one drive with such a
partition the UEFI BIOS can get confused.
The second partition will hold our encrypted root, including "usr", "var" and
basically everything except "/boot", "/home/[user]" and "/tmp". About 50GB is
more than enough for this.
Swap is set to a bit more than 32GiB to make sure there is enough room for
hibernation on a 32GiB RAM system although it will not work with the setup
described here. It is a bit bigger than 32GiB so it can hold a little dummy
ext2 partition just to name it. This will become clear later on.
Lastly we have the partition for LVM with the fast user home volumes.
Below you can see the partition information for the two big hard disks.
Parted for /dev/sdb:
parted /dev/sdb
(parted) mklabel GPT
(parted) mkpart raid1-vghdd1 0% 100%
(parted) set 1 raid on
(parted) print
Model: ATA WDC WD20EARS-00M (scsi)
Disk /dev/sdg: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 2000GB 2000GB raid1-vghdd1 raid
Parted for /dev/sdc:
parted /dev/sdc
(parted) mklabel GPT
(parted) mkpart raid1-vghdd2 0% 100%
(parted) set 1 raid on
(parted) print
Model: ATA WDC WD20EARS-00M (scsi)
Disk /dev/sdg: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 2000GB 2000GB raid1-vghdd2 raid
Setting the raid flag is not strictly necessary.
File System, RAID and LVM preparation
UEFI
The UEFI system partition needs FAT32.
mkfs.vfat -F 32 /dev/sda1
RAID
To set up the raid you need "sys-fs/mdadm". For this setup it is very
straightforward.
mdadm --create /dev/md1 --level=mirror --raid-devices=2 /dev/sdb1 /dev/sdc1
If you are just testing something and do not want to to have this raid syncing
in the back which can take several hours for 2TB disks like here you can use
the keyword "missing" instead of a device and add the other disk later on.
LVM
We have two separate LVM volume groups in this setup. One on the SSD and one
on the RAID1. The main reason for LVM here is to have flexibility in the
storage distribution between the users. To set up the LVM volumes we will of
course need "sys-fs/lvm2".
pvcreate /dev/sda4
Physical volume "/dev/sda4" successfully created
vgcreate vgssd /dev/sda4
Volume group "vgssd" successfully created
lvcreate -l 50%VG -n user1-home vgssd
Logical volume "user1-home" created.
lvcreate -l 50%VG -n user2-home vgssd
Logical volume "user2-home" created.
If you are operating from a system which has an "/etc/lvm/lvm.conf" that has
been configured to only work with VGs (volume groups) that you specifically
set up you may get an error like "Aborting. Failed to wipe start of new
LV.". In that case you may want to edit "/etc/lvm/lvm.conf" and comment out
your old volume list:
Or you can add the planned new VGs right away.
volume_list = [ "vgssd", "vghdd"]
Also see to it that all the drives you need are actually allowed.
# Gentoo: we exclude /dev/nbd by default, because it makes a lot of kernel
# noise when you probed while not available.
filter = [ "r|/dev/nbd.*|", "a|/dev/md.*|", "a|/dev/sd.*|" ]
And now for the VG on the RAID1.
pvcreate /dev/md1
Physical volume "/dev/md1" successfully created
vgcreate vghdd /dev/md1
Volume group "vghdd" successfully created
lvcreate -l 50%VG -n user1-archive vghdd
Logical volume "user1-archive" created.
lvcreate -l 50%VG -n user2-archive vghdd
Logical volume "user2-archive" created.
At this point we are done with our partitioning layout.
Crypto Preparation
We have several encrypted volumes here.
- root on "/dev/sda2"
- swap on "/dev/sda3"
- user home volumes on "vgssd"
- user archive volumes on "vghdd"
The encryption is pretty straightforward with two notable exceptions.
- root needs to have keys with pass phrases of all users so that trusted
users can boot the machine
- swap gets a random key which disables hibernation aka "suspend to disk" but
I personally only use suspend to RAM or just a regular shutdown anyway
We continue with the actual encryption.
Encrypting the Volumes
I use the default key parameters which I trust to be sufficient for home users
like me.
cryptsetup luksFormat /dev/sda2
[enter root password]
# user 1
cryptsetup luksFormat /dev/vgssd/user1-home
[enter user1 password]
cryptsetup luksFormat /dev/vghdd/user1-archive
[enter user1 password]
# user 2
cryptsetup luksFormat /dev/vgssd/user2-home
[enter user2 password]
cryptsetup luksFormat /dev/vghdd/user2-archive
[enter user2 password]
The users should however also be able to open the root partition with their
user password. This way they can boot the machine.
cryptsetup luksAddKey /dev/sda2
[enter root password and then enter user1 password]
cryptsetup luksAddKey /dev/sda2
[enter root password and then enter user2 password]
Now we need to set up the file systems.
Initializing File Systems
We now open the encrypted volumes and initialize them with ext4 file systems.
cryptsetup open /dev/sda2 root
mkfs.ext4 /dev/mapper/root
# user 1
cryptsetup open /dev/vgssd/user1-home vgssd-user1-home
mkfs.ext4 /dev/mapper/vgssd-user1-home
cryptsetup open /dev/vghdd/user1-archive vghdd-user1-archive
mkfs.ext4 /dev/mapper/vghdd-user1-archive
# user 2
cryptsetup open /dev/vgssd/user2-home vgssd-user2-home
mkfs.ext4 /dev/mapper/vgssd-user2-home
cryptsetup open /dev/vghdd/user2-archive vghdd-user2-archive
mkfs.ext4 /dev/mapper/vghdd-user2-archive
Swap is a bit special. We put a small ext2 partition at the very front of it
just so that we have a nice name to address it later on.
mkfs.ext2 -L cryptswap /dev/sda3 1M
This is a good compromise to get away from using the device names which may
change. Remember that this to be encrypted swap space will be overwritten
without further notice. In contrast to a regular swap partition which would
just fail if the drive had changed. So be extra careful here.
I got the idea from here Archlinux Wiki
Gentoo Installation
The next step is to get going on the Gentoo installation itself. Of course a
lot of steps will be similar to the description in the
Gentoo Handbook.
# mount root
mkdir /mnt/gentoo
mount /dev/mapper/root /mnt/gentoo
# or mount /dev/sda2 /mnt/gentoo if you rebooted after the crypto
# preparation mount UEFI partition as boot
mkdir /mnt/gentoo/boot
mount /dev/sda1 /mnt/gentoo/boot
Download and install the amd64 stage tarball with systemd. You can of course
pick another mirror.
cd /mnt/gentoo
wget ftp://sunsite.informatik.rwth-aachen.de/pub/Linux/gentoo/releases/amd64/autobuilds/current-stage3-amd64-systemd/*
The "*" gets me the current stage file as well as the files with the
checksums.
# get key id from https://gentoo.org/downloads/signatures/ and import it
gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0xBB572E0E2D182910
gpg --edit-key 0xBB572E0E2D182910 trust
gpg> 5
gpg> quit
# check authenticity of checksums
gpg --verify stage3-*.asc
gpg: Signature made Sun 15 Jan 2017 02:35:16 PM CET
gpg: using RSA key BB572E0E2D182910
gpg: Good signature from "Gentoo Linux Release Engineering (Automated Weekly Release Key) <releng@gentoo.org>"
...
You can ignore the last bit of output about "..bz2.DIGESTS' was NOT
verified!". We verified the "bz2.DIGESTS.asc" file that is good enough. Now
we check the file content against the checksum:
grep -A 1 '# SHA512' stage3-*.asc | grep -o '^[0-9a-f].*' | sha512sum -c
stage3-amd64-systemd-20170113.tar.bz2: OK
stage3-amd64-systemd-20170113.tar.bz2.CONTENTS: OK
Subsequently we unpack the stage file:
tar xvjpf stage3-*.tar.bz2 --xattrs
# (optionally) remove the downloaded files
rm stage3*
Portage
Just like in the Gentoo handbook we continue with the "make.conf" file in
"/mnt/gentoo/etc/portage".
A few options will only be needed later on but it does not harm to add them
right away. Mine then looks like this.
# These settings were set by the catalyst build script that automatically
# built this stage.
# Please consult /usr/share/portage/config/make.conf.example for a more
# detailed example.
CFLAGS="-O2 -pipe -march=corei7-avx"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j8"
# WARNING: Changing your CHOST is not something that should be done lightly.
# Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing.
CHOST="x86_64-pc-linux-gnu"
# These are the USE flags that were used in addition to what is provided by the
# profile used for building.
USE="cryptsetup"
PORTDIR="/usr/portage"
DISTDIR="${PORTDIR}/distfiles"
PKGDIR="${PORTDIR}/packages"
GENTOO_MIRRORS="ftp://ftp.halifax.rwth-aachen.de/gentoo/"
FEATURES="parallel-fetch"
GRUB_PLATFORMS="efi-64"
LINGUAS="de en"
L10N="de en"
VIDEO_CARDS="radeon"
CPU_FLAGS_X86="aes avx mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
Copy the Gentoo repository configuration:
mkdir /mnt/gentoo/etc/portage/repos.conf
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
Then take a peek inside if it is OK.
Chroot
I usually configure my new installation from my current system so there is a
loot of chrooting. Because of that I make myself a small script named
"chrootgentoo.sh" which looks like this:
#!/bin/bash
cp -L /etc/resolv.conf /mnt/gentoo/etc/
mount -t proc proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev
Make it executable.
chmod u+x chrootgentoo.sh
Switch to the new environment.
./chrootgentoo.sh
chroot /mnt/gentoo /bin/bash
source /etc/profile
export PS1="(chroot) $PS1"
You should be greeted by a "(chroot) #" prompt.
Configure Portage and update World
Following the handbook we get ourselves a portage snapshot.
Select a profile.
This should pick "default/linux/amd64/13.0/systemd" which is a pretty bare
system with systemd. We will add all the other fancy stuff later when the
system already boots properly.
Install base packages for profile:
If you get any error "emerge --sync" and then try again.
While in the chroot don't forget to set your root password:
I have skipped some handbook steps here like localization and timezone. We can
configure those later on on the running system directly with "systemctl".
RAID Configuration
We only need RAID for our two big HDDs. Auto assembly will probably work but I
usually configure it explicitly to have the drives where I expect them.
Then set up an "/etc/mdadm.conf" file like this:
DEVICE /dev/sd[a-z]*
ARRAY /dev/md1 metadata=1.2 UUID=
Append the UUID of your array after the equals sign. Or you can save yourself
some time and create all the needed lines like this:
echo -e "DEVICE /dev/sd[a-z]*\nARRAY /dev/md1 metadata=1.2 UUID=$(mdadm --misc -D /dev/md1 | egrep -o '([0-9a-f]{8}:?){4}')" >> /etc/mdadm.conf
LVM Configuration
First of all install the LVM tools.
Then I adapt the "/etc/lvm/lvm.conf" file as follows:
use_lvmetad = 1
volume_list = [ "vgssd", "vghdd" ]
filter = [ "r|/dev/nbd.*|", "a|/dev/md.*|", "a|/dev/sda.*|" ]
I do this because I only want to activate required volume groups
automatically.
Fstab
The "fstab" is slightly different from the default. Fill in the UUIDs
accordingly.
UUID= /boot vfat noauto,noatime 1 2
UUID= / ext4 noatime 0 1
tmpfs /var/tmp/portage tmpfs size=2G,uid=portage,gid=portage,mode=775,noatime 0 0
/dev/mapper/swap none swap defaults 0 0
You can find the UUIDs with "blkid". Be sure to pick the unencrypted volumes.
# /boot
blkid /dev/sda1
# /
blkid /dev/mapper/root
The FAT32 partition for boot has a very short UUID. That is normal. The bit
about the swap partition will become clear in the next step.
If you are using VIM to edit this file you can use :read !blkid /dev/sda1
to
get the UUID. From there it only takes a bit of copy and paste.
The tmpfs is just for portage so that most of the compilation is done in
memory. When you emerge big packages you may need to unmount it so that the
disk is used or follow this guide to make it even more convenient:
Portage TMPDIR on tmpfs
Crypttab
Our swap will be encrypted with a random key on each boot. Write the following
to your "/etc/crypttab".
swap LABEL=cryptswap /dev/urandom swap,offset=2048,cipher=aes-xts-plain64,size=256
2048 represents 1M in 512 byte sectors. This is the 1M dummy ext2 partition
that is just used to name the partition.
Configuring the Kernel
To have our configuration work properly with an own kernel we need to make
sure we have the proper options set. With UEFI, RAID, LVM and encryption there
are a few pitfalls to keep in mind.
First get the sources:
emerge -av gentoo-sources
cd /usr/src/linux
make menuconfig
I usually also forget that you can easily reuse your old ".config" with "make
oldconfig" if you copy over your old ".config" file first.
Then make sure to check the following settings:
Gentoo Linux > Support for init systems, system and service managers > [*] systemd
General setup > [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
Enable the block layer > Partition Types > [*] EFI GUID Partition support
Processor type and features > [*] EFI runtime service support
Device Drivers > Generic Driver Options > () path to uevent helper
Device Drivers > Multiple devices driver support (RAID and LVM) > <*> RAID support
Device Drivers > Multiple devices driver support (RAID and LVM) > <*> RAID-1 (mirroring) mode
Device Drivers > Multiple devices driver support (RAID and LVM) > <*> Device mapper support > <*> Crypt target support
Device Drivers > Multiple devices driver support (RAID and LVM) > <*> Device mapper support > <*> Mirror target
Device Drivers > Graphics support > Frame buffer devices > [*] EFI-based Framebuffer Support
Device Drivers > Graphics support > Console display driver support > <*> Framebuffer Console support
Device Drivers > Graphics support > Bootup logo <>
Firmware Drivers > EFI (Extensible Firmware Interface) Support > <*> EFI Variable Support via sysfs
Firmware Drivers > EFI (Extensible Firmware Interface) Support > <*> Export efi runtime maps to sysfs
The Bootup logo is disabled because it can affect plymouth.
You can also have a look at my
.config file.
For the encryption I activated the following as well:
Cryptographic API > <*> SHA256 digest algorithm (SSSE3/AVX/AVX2)
Cryptographic API > <*> SHA512 digest algorithm (SSSE3/AVX/AVX2)
Cryptographic API > <*> AES cipher algorithms (AES-NI)
If you forget the EFI based framebuffer it may later on appear as if your
kernel hangs at boot because you won't see any further output.
For my kernel ".config" I need to have the radeon firmware available so I add
it with:
emerge -av sys-firmware/radeon-ucode
Compile the kernel and copy it to "/boot".
make && make modules_install && make install
Dracut
Dracut and initramfs can be quite difficult to get right sometimes. The kernel
command line options "rd.debug" and "rd.break=mount" can be very helpful if
something fails. The dracut emergency shell these commands drop to is capable
enough to let you copy a log to a USB stick for later analysis.
First of all we emerge dracut:
emerge -av sys-kernel/dracut
Dracut takes its configuration from "/etc/dracut.conf.d/". All files in
there combined make up the whole configuration. Let's make a new file called
"cryptroot.conf" and fill it with the following options:
kernel_cmdline+=" root=UUID= "
kernel_cmdline+=" ro "
kernel_cmdline+=" init=/usr/lib/systemd/systemd "
Add the UUID of your unencrypted root partition in the first line. You can get
it with "blkid /dev/mapper/root". Or have the whole
file generated by this one-liner:
for line in "root=UUID=$(blkid /dev/mapper/root | grep -o 'UUID=.* ' | grep -o '[0-9a-f-]*' )" "ro" "init=/usr/lib/systemd/systemd"; do echo "kernel_cmdline+=\" $line \"" >> /etc/dracut.conf.d/cryptroot.conf; done
The spaces at between " and content were important in my old setup with an
older dracut version! They do not seem to be now but I leave this note here
just to be sure.
These kernel options are not enough for the initramfs to find the root device.
We will have to add the encrypted root device UUID to the kernel command line
via GRUB. You cannot add it here in the dracut configuration because the
systemd of the initramfs will not activate it. Instead you will get cryptic
errors such as "Failed to start systemd-cryptsetup@luks.service No such file
or directory" or something like "systemd-escape: invalid option --". These
have to do with missing unit files for the encrypted root. They are
automatically created by systemd through the systemd-cryptsetup-generator but
only if you hint to them on the kernel command line or place them in the
crypttab.
Then we generate the initramfs with the following command:
dracut --force --kver $(ls -l /usr/src/linux | grep -o "[0-9.]*\-gentoo")
This assumes "/usr/src/linux" points to the current kernel which should be the
case on any new installation.
We have to mention the explicit kernel version here because we are in a chroot
and the otherwise determined kernel version will most likely not match that of
the new system.
Installing GRUB2
You should have the desired platform in your "make.conf". Mose likely
"GRUB_PLATFORMS="efi-64"". Then go ahead and install GRUB.
emerge -av sys-boot/grub
mkdir /boot/grub
Now uncomment and modify the default command line in "/etc/default/grub":
GRUB_CMDLINE_LINUX="splash quiet vconsole.keymap=de-latin1-nodeadkeys rd.luks.uuid=luks-"
Add the UUID of the encrypted root partition after the last '-'. You can get
it with:
I like to disable the GRUB submenu in the grub configuration to make the boot
menu less convoluted and remove the automatic root parameter. We will add
that manually.
GRUB_DISABLE_SUBMENU=y
GRUB_DISABLE_LINUX_UUID=true
You can see I also added the German keyboard layout. Because we did not use
'--hostonly' with dracut the keyboard layout will be the default US layout
which will make password entry difficult.
Build the configuration:
grub-mkconfig -o /boot/grub/grub.cfg
The output should contain something like this:
Found linux image: /boot/...vmlinuz-..
Found initrd image: /boot/...initramfs-..
It may throw out some errors at the end because grub does a bit probing which
may fail with errors such as "/run/lvm/lvmetad.socket: connect failed". You
can ignore those.
Check the "/boot/grub/grub.cfg" file to make sure the options are correct. In
this configuration we have the root parameter in the initramfs. So we can
delete all occurrences of "root=/dev/.." from the kernel command lines in the
"grub.cfg".
Now comes the annoying part. You cannot really install grub2 UEFI properly
from a non UEFI system. So if you are not inside a system booted from UEFI you
have to use an UEFI capable Linux live disk to boot. I always have a
SystemRescueCD USB stick lying around. So I will
use that one. Just be sure to select UEFI boot. On my mainboard this means
pressing F11 during boot and then selecting UEFI: USB .. .
You will of course have to manually put all the parts of your new system
together and chroot. For me this means:
mount /dev/sda2 /mnt/gentoo
mount /dev/sda1 /mnt/gentoo/boot
mount -t proc proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev
chroot /mnt/gentoo /bin/bash
If the live stick is a bit older you might need to use cryptsetup luksOpen
/dev/sda2 root
and then mount the mapped device.
In the chroot source the profile and adapt the prompt:
source /etc/profile
export PS1="(chroot) $PS1"
Then you can install GRUB like this:
grub2-install --efi-directory=/boot
The command might just be named "grub-install" in newer distributions.
This should not produce any errors, but instead just show the current boot
order. In "/boot" you should find an EFI directory now and a new boot entry
"gentoo" has been added to the NVRAM of the UEFI BIOS.
The Reboot
During the installation you may have seen some complaints about an unset
hostname or a missing locale. This is because they should be set through
systemd. That is however best done with systemd running.
Setting the Locale
localectl set-locale LANG=de_DE.utf8
localectl set-keymap de-latin1-nodeadkeys
You may have to generate the locales here first. You can do this as usual by
editing "/etc/locale.gen" and running locale-gen
.
Setting the Hostname
hostnamectl set-hostname testhost
Setting the Timezone
timedatectl set-timezone Europe/Berlin
Getting a Network Connection
For a basic wired network you do not even need the "NetworkManager" service.
you can just use the internal "systemd.networkd". To set it up simply place a
".network" file in "/etc/systemd/network".
For my static network configuration this is a file called "static.network"
with the following content:
[Match]
Name=enp4s0
[Network]
Address=192.168.2.5/24
Gateway=192.168.2.1
You probably do not need to enable the service since sooner or later something
will require a network and start it anyway.
Regular Users
With the system setup done we can move on to the regular users. To mount the
users homes and the archive volumes we will use pam_mount. It seems a bit
dated and can be twitchy on occasion but I have found that it works reasonably
well. One issue that can arise is that the home and archive volumes may not
unmount properly when you log out. With a proper configuration this will not
be the case but it is something to watch out for during setup. Especially if
you have user processes that do not quit quickly enough on logout. In that
case the volumes appear busy and fail to unmount. This can be a security
problem.
Automounting User Homes
First of all get pam_mount.
emerge -av sys-auth/pam_mount
pam_mount offers options for killing running user processes on logout. These
features rely on the somewhat obscure hxtools package. It was masked "~amd64"
at the time of writing. If you need it install it like this:
echo "=dev-util/hxtools-20121125-r1 ~amd64" >> /etc/portage/package.keywords
emerge -av dev-util/hxtools
You will only need this if you want to kill user processes on logout to ensure
unmounting.
If you get an error you may need to instal "x11-libs/libxcb" beforehand.
pam_mount needs to be added to the PAM environment. I have found that it is
best not to put it in "system-auth" like may descriptions propose but instead
place it in "/etc/pam.d/system-login" as the last lines of the "auth" and
"session" blocks. Your "system-login" file should then look somewhat like
this:
..
auth optional pam_gnome_keyring.so
auth optional pam_mount.so
..
session optional pam_mail.so
session optional pam_mount.so
..
If you use "system-auth" I have found that it gets loaded twice which leads to
problems with proper unmounting.
As a side note. If you ever want to do something on login and logout
regardless of the login method (console, ssh, gdm ..) have a look at the
pam_exec.so module.
Add a Regular User
useradd -m user1
passwd user1
Be sure to use the same password that you used when setting up the encrypted
home an archive volumes.
Automounting Home and Archive
Now edit "/etc/security/pam_mount.conf.xml" and add:
<logout wait="2000" hup="0" term="1" kill="1" />
<volume user="user1" mountpoint="/home/user1" path="/dev/vgssd/user1-home" fstype="crypt" options="noatime" />
<volume user="user1" mountpoint="/home/user1/archive" path="/dev/vghdd/user1-archive" fstype="crypt" options="noatime" />
Modify the <logout>
line if it is already uncommented and put the rest
before the last </pam_mount>
. Add the second user accordingly.
Mount user home manually and make the archive mount point:
mount /dev/mapper/vgssd-user1-home /home/user1
mkdir /home/user1/archive
chown -R user1:user1 /home/user1
Mount the archive volume manually.
mount /dev/mapper/vghdd-user1-archive /home/user1/archive
chown -R user1:user1 /home/user1/archive
Unmount it all.
umount /home/user1/archive
umount /home/user1
Now logout or switch to another tty and log in as 'user1'. It should
automatically mount the encrypted LVM volume as your home and the archive
volume as well.
Log out and check as root if everything has been unmounted.
mount | grep '/home/user1'
It should return nothing. Also you should not get any "file exists" errors
when you log in as "user1" again on a different tty. You can of course be
logged in several times and pam_mount will unmount everything on the last
logout. It keeps track about the number of times you are logged in through
""
If you run into trouble with pam_mount set <debug enable="1" />
in
"/etc/security/pam_mount.conf.xml" and look for infos with "journalctl -r"
Eye Candy
We should have a fully working system by now. But you may want to add some
eye candy.
Plymouth
Although we have prepared everything for it plymouth is not yet being used for
a fancy password prompt during boot up. I have left it as one of the final
steps because it will require "X" and therefore quite some compile time.
If you want GDM and a whole GNOME system anyway you can just do all the steps
but postpone the world update.
Add the "plymouth" "libkms" and "X" USE flags to your "make.conf". It probably
looks like this then:
USE="cryptsetup libkms plymouth X"
Emerge the world set with the new USE flags:
Then emerge plymouth itself:
It will pull a lot of stuff. So it is a good time to get yourself a cup of tea
now.
Extend the dracut configuration by adding a file to "/etc/dracut.conf.d/". I
named it "plymouth.conf" with the following content:
# plymouth - graphical passwort prompt configuration
add_dracutmodules+=" plymouth "
Be sure to have your "/boot" mounted. Then regenerate the initramfs.
dracut --force --kver $(ls -l /usr/src/linux | grep -o "[0-9.]*\-gentoo")
If you booted from the new system you can skip the "--kver" option. Dracut
will use the running kernel version.
Reboot and test your setup.
GDM and GNOME
Add the "gdm" USE flag to your "make.conf". Then for a full GNOME setup select
a new profile and update the whole system like this.
eselect profile set 5
emerge -avuDN @world
GDM has not yet been installed. At the state of writing this there was some
awkwardness with the dependencies.
If you try to install "gnome-base/gdm" its dependency
"gnome-base/gnome-control-center" requires the "networkmanager" USE flag. I
add it to my "make.conf" and then try again with the following result:
:::text
emerge: there are no ebuilds built with USE flags to satisfy ">=net-fs/samba-3.6.14-r1[smbclient]".
!!! One of the following packages is required to complete your request:
- net-fs/samba-4.2.14::gentoo (Missing IUSE: smbclient)
- net-fs/samba-4.2.11::gentoo (Missing IUSE: smbclient)
SAMBA is pulled in because of the "cups" USE flag. I do not mind that but the
"smbclient" USE flag is confusing. Ihis issue comes from an error in the
"gnome-base/gnome-control-center-3.20.1-r1" ebuild which seems to have been
fixed in version 3.22.1 but I do not want to unmask it with "~amd64" because
that will force me to unmask other packages as well. Instead I quickly set up
a local portage overlay.
mkdir -p /usr/local/portage/{metadata,profiles}
chown -R portage:portage /usr/local/portage
echo 'localrepo' > /usr/local/portage/profiles/repo_name
echo -e "masters = gentoo\nauto-sync = false" >> /usr/local/portage/metadata/layout.conf
echo -e "[localrepo]\nlocation = /usr/local/portage" >> /etc/portage/repos.conf/localrepo.conf
Another tool we will need to prepare the adapted ebuild is
"app-portage/repoman".
emerge -av app-portage/repoman
Now we prepare our local copy of the "gnome-control-center-3.20.1-r1" ebuild."
mkdir -p /usr/local/portage/gnome-base/gnome-control-center
cp /usr/portage/gnome-base/gnome-control-center/gnome-control-center-3.20.1-r1.ebuild /usr/local/portage/gnome-base/gnome-control-center
cp -R /usr/portage/gnome-base/gnome-control-center/files /usr/local/portage/gnome-base/gnome-control-center
chown -R portage:portage /usr/local/portage
Then fix the error. I simply do this by buy asking for the newer SAMBA version
first. That will match and the old "smbclient" requirement will never be
checked. Use your favorite editor and change line 60 of
"/usr/local/portage/gnome-base/gnome-control-center/gnome-control-center-3.20.1-r1.ebuild".
Before change:
|| ( >=net-fs/samba-3.6.14-r1[smbclient] >=net-fs/samba-4.0.0[client] )
After change:
|| ( >=net-fs/samba-4.0.0[client] >=net-fs/samba-3.6.14-r1[smbclient] )
Generate the manifest for the modified ebuild:
cd /usr/local/portage/gnome-base/gnome-control-center
repoman manifest
Add "client" and "python" USE flags to your "make.conf" update world and then
install "gnome-base/gdm":
emerge -avuDN @world
emerge -av gnome-base/gdm
Now you can test GDM with:
systemctl start gdm.service
And if everything works enable it for startup on boot:
systemctl enable gdm.service
On a side note if you want to have users that do not show up in the login list
on GDM you can mark them as system users. To do that place a file with the
name of the user for example "user2" in "/var/lib/AccountsService/users/" and
put the following inside:
[User]
Language=
XSession=
SystemAccount=true
Everything else GNOME related would be way blow up this tutorial even further.
You have a very basic GNOME system now and will need to install file manager,
browser and so forth manually.
Administrative Tasks
Because each user has access to two LVM volumes and needs to be able to unlock
root on boot up some tasks are a bit more convoluted.
Changing the Password
Changing Keys
If you want to change a users password you also need to change the keys on the
root device and the home and archive LVM volumes.
cryptsetup luksChangeKey /dev/sda2
[enter old and new password]
cryptsetup luksChangeKey /dev/vgssd/user1-home
[enter old and new password]
cryptsetup luksChangeKey /dev/vghdd/user1-home
[enter old and new password]
Changing Password
The user can do this himself with the regular:
Removing a User
Removing a user also requires some steps. Be sure not to forget to remove the
key from the root device. Also the user needs to be logged out. The following
steps assume the user name 'user1'.
Removing Keys
/dev/sda2 is the root device.
cryptsetup luksRemoveKey /dev/sda2
[enter user1 password]
If you do not have the password you can remove a key with "luksKillSlot". You
do however need to know which keyslot it is. If you are expecting this to
happen you should keep track of the assigned keyslots when creating the users.
Removing LVM volume and /home
lvremove vgssd/user1-home
lvremove vghdd/user1-archive
Maybe overwrite them first depending on your degree of paranoia.
Removing User Account
Resizing
Since each user has his own LVM volume with an encrypted volume on it you can
use all the regular lvm, cryptsetup and file system tools. Just make sure to
back up your data first and see to it that the user is logged out.
List of used Software Versions
- gentoo-sources-4.4.39
- sys-fs/lvm2-2.02.116-r4
- sys-fs/cryptsetup-1.7.2
- sys-kernel/dracut-044-r1
- sys-apps/systemd-226-r2
- sys-boot/grub-2.02_beta3-r1
- sys-auth/pam_mount-2.15
- sys-boot/plymouth-0.9.2
All on amd64 architecture.
Conclusion
I hope this tutorial helps some of you out there. It took me some time to
figure it out but it is indeed a quite nice setup I think.