Verschlüsselung am Linux-Arbeitsplatz
loop-AES verschlüsseltes root- und swap-Filesystem
Anleitung für Ubuntu 22 / Linux Mint 21
von Sven Palme
Wenn das bisherige Linux-System auf dem Desktop-PC in die Jahre gekommen ist und eine Aktualisierung bevorsteht, empfiehlt es sich, beim Umstieg auf das neue System gleich eine Verschlüsselung (swap und root) über loop-AES einzurichten. Wir haben uns erneut für Linux Mint - MATE entschieden (alter Beitrag hier):
32 GB sollten es mindestens sein
Die Installation von Linux Mint 21 benötigt ca. 16GB. Für eine erfolgreiche Kernelkompilierung benötigen wir jedoch mindestens 32GB, so dass wir uns für 32GB als minimale Anforderung entschieden haben. Da wir später auch die root-Partition verschlüsseln wollen und heutige Festplatten deutlich mehr Speicherplatz aufweisen, zeigt folgendes grobes Schema, wie eine Platte aufgeteilt werden kann.
Partition | Größe | Verwendung | Dateisystem |
---|---|---|---|
/dev/sda1 | 1GB | Linux Boot | Linux |
/dev/sda2 | 4GB | Linux Swap | Linux Swap / Solaris |
/dev/sda3 | 64GB-Rest | Linux Root | Linux |
/dev/sda4 | 32-64GB | Linux Test | Linux |
Nach erfolgter Partitionierung entscheiden wir uns bei der Installation für /dev/sda4 als / und /dev/sda1 als /boot Partition.
sda2 als Swap kann entfallen - da es fast immer unnötig ist und bei Speickerlecks im Firefox zu Problemen führt.
loop-AES
Für die Verschlüsselung benutzen wir loop-AES. Dieses Verfahren erzwingt ein modifiziertes mount, umount und losetup sowie ein eigenes loop-Modul für den Kernel. Die modifizierten Programme werden leider nicht mehr direkt zur Verfügung gestellt. Aber wir zeigen wie es geht.
Der Kernel muß wie immer neu gebaut werden, aufgrund der festen Integration des loop-Moduls.
Wir holen uns die Sourcen von https://sourceforge.net/projects/loop-aes/
Aktuell: /loop-aes/v3.8e/loop-AES-v3.8e.tar.bz2
Kernel bauen
Es werden einige zusätzliche Pakete benötigt. Da wir ab hier die ganze Zeit als root arbeiten, setzen wir es mittels sudo su -.
sudo su -
apt-get install abiword-common abiword apache2
apt-get install mariadb-server
apt-get install virualbox
apt-get install vlc
apt-get install lbzip2
apt-get install ssh smartmontools
apt-get install traceroute
apt-get install php
apt-get install python*
apt-get install python-dev
apt-get build-dep linux-image-$(uname -r)
apt-get build-dep linux
apt-get install git-core
apt-get install libelf-dev asciidoc binutils-dev
apt-get install libudev-dev
apt-get install libpci-dev
apt-get install libpci*
apt-get install xmlto
apt-get install openssl
apt-get install openssl-dev
apt-get install libopenssl-dev
apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev
apt-get install libpython-dev
apt-get install fakeroot build-essential devscripts
apt-get install crash kexec-tools makedumpfile kernel-wedge
apt-get install dh-make
apt-get install dh-system*
apt build-dep -y linux
apt install -y libncurses5-dev
apt-get install -y devscripts libsqlite3-dev
Wir holen uns nun die Kernelsource von https://www.kernel.org/ und packen diese aus und konfigurieren es so, dass kein "loop" dabei ist.
cd /usr/src/
wget 'https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.11.10.tar.xz'
tar -xf linux-6.11.10.tar.xz
cd linux-6.11.10
make menuconfig
Der letzte Befehl bring ins Kernel-Setup wo wir uns durchhangeln über Device Driver -> Block devices
und hier zum Loopback device support
Es muss sowohl das Loopback device und die Cryptoloop deacktviert werden - und speichern nicht vergessen!
Und dann sollten wir um Platz zu sparen unbeding auch das Debugging abschalten:
Und speichern nicht vergessen!
Dann können wir den Kern kompilieren (-j8 nutzt 8 Kerne unserer CPU)
make -j8
make -j8 modules
make -j8 modules_install
make -j8 bzImage
Das bzImage müssen wir nun noch boot bekommen:
cp /usr/src/linux-6.11.10/arch/x86_64/boot/bzImage /boot/vmlinuz-6.11.10
cp /usr/src/linux-6.11.10/System.map-6.11.10 /boot/
cp /usr/src/linux-6.11.10/config-6.11.10 /boot/
Wenn wir die Option für debug_infos nicht disabled haben - alle Module mit debug_symbolen versehen die wir nicht brauchen - und vor allem stören, wenn wir die initrd bauen - also kommen die so weg:
find /lib/modules/6.11.10/ -iname "*.ko" -exec strip --strip-debug {} \;
Erstellung des Kernelmoduls Loop
Gute Hilfetellung finden wir in der README.
sudo su -
cd /usr/src
wget 'https://sourceforge.net/projects/loop-aes/files/loop-aes/v3.8e/loop-AES-v3.8e.tar.bz2/download'
tar -xvjf loop-AES-v3.8e.tar.bz2
cd loop-AES-v3.8e
make clean && make KEYSCRUB=y LINUX_SOURCE=/usr/src/linux-6.11.10/
cd ..
Wir brauchen Teile der util-linux
Damit die loop-devices gemountet werden können braucht es ein paar tools die wir neu komplieren müssen. Daher holen wir uns die util-linux von https://www.kernel.org/pub/linux/utils/util-linux/
sudo su -
cd /usr/src
wget 'https://www.kernel.org/pub/linux/utils/util-linux/v2.40/util-linux-2.40.2.tar.xz'
tar -xf util-linux-2.40.2.tar.xz
cd util-linux-2.40.2
patch -p1 < ../loop-AES-v3.8e/util-linux-2.40.2.diff
CFLAGS="-O2 -Wall" ./configure --disable-shared --enable-static --disable-pylibmountstatic-rnd=linux
make clean && make
cd ..
Da bei Paket-updates manchmal dieses Paket auch angefasst wird sollten wir ein kleines Script bereitstellen welches und alle Programme an die richtige Stelle kopiert
#!/bin/bash
cp /usr/src/util-linux-2.40.2/mount /bin/
cp /usr/src/util-linux-2.40.2/umount /bin/
cp /usr/src/util-linux-2.40.2/losetup /sbin/
cp /usr/src/util-linux-2.40.2/swapon /sbin/
cp /usr/src/util-linux-2.40.2/swapoff /sbin/
Vorher sollte man ggf. die originalen mounts/umounts sich sichern - aber das macht man ja nur einmal.
Wir brauchen ein statisches gpg
Für die Verschlüsselung der root-Partition und dem Entschlüsseln des Keyfiles brauchen wir ein im "initrd" sitzendes statisches gpg. Dies bauen wir uns auch schnell:
sudo su -
cd /usr/src
wget https://gnupg.org/ftp/gcrypt/gnupg/gnupg-1.4.23.tar.bz2
tar -xvjf gnupg-1.4.23.tar.bz2
cd gnupg-1.4.23
patch -p1 < ../loop-AES-v3.8e/gnupg-1.4.23.diff
CFLAGS="-O2 -fcommon" LDFLAGS="-static -s -lrt -fcommon" ./configure --prefix=/usr --enable-static-rnd=linux
make clean && make
cd ..
Ein Schlüssel muss her
Zuerst brauchen wir aber noch den eigentlichen Schlüssel, den wir als /boot/rootkey.gpg ablegen, wobei hier die gängigen Regeln für das Vergeben von Passwörtern/ Schlüsseln gelten. Etwas wie "geheim" ist denkbar schlecht. Besser wäre etwas wie "elake8ipus98", allerdings kaum zu merken. Längere Sätze wie "Luke, ich bin dein Vater" mögen zwar schwieriger wirken, sind es aber, aufgrund der Eingängigkeit der Zitate, nicht - so lange man sie für sich selbst nachvollziehbar verändert. Vielleicht wäre "Darth, ich bin dein Sohn" besser, aber nach meiner Veröffentlichung jetzt nicht mehr... Das Passwort sollte leicht zu merken sein, eine Länge von mindestens 16 Zeichen haben, wobei unbedingt der gesamte Zeichensatz benutzt werden sollte.
Der folgende Befehl braucht sehr lange. Schneller geht es mit /dev/urandom. Natürlich machen wir uns vorher wieder zu root.
sudo su -
head -c 3705 /dev/random | uuencode -m - | head -n 66 | tail -n 65 | gpg --symmetric -a > /boot/rootkey.gpg
Eintrag in /etc/fstab anlegen:
/dev/sda3 /mnt ext3 defaults,noauto,loop=/dev/loop3,encryption=AES256,gpgkey=/boot/rootkey.gpg 0 0
Jetzt können wir die Partition endlich verschlüsselt formatieren und unser aktuelles System darauf kopieren.
depmod -a
modprobe Loop
losetup -F /dev/loop3
mkfs.ext3 -j /dev/loop3
losetup -d /dev/loop3
mount /dev/sda3
rsync -vaH --exclude "/boot/*" --exclude "/mnt/*" --exclude "/sys/*" --exclude "/proc/*" --exclude "/dev/*" --exclude "/run/*" / /mnt
Wir ändern die /mnt/etc/fstab auf dem gerade kopierten Image (denn das wird ja unsere neue Root-Platte) und sorgen hierbei auch gleich dafür, dass die Swap-Partion (hier sda2) verschlüsselt wird.
# Ersetze den ROOT Eintrag durch diesen
/dev/loop3 / ext3 errors=remount-ro 0 1
# Ersetze den SWAP Eintrag durch diesen
/dev/sda2 swap swap sw,loop=/dev/loop2,encryption=AES256 0 0
Eine neue initrd
Wir legen uns ein Original der initrd zurecht:
rm -rf initrd 2>/dev/null
mkdir initrd
unmkinitramfs /boot/initrd.img-5.15.0-76-generic initrd
Nun kopieren wir die benötigten Dateien hinein.
cd initrd/main
cp -f /boot/rootkey.gpg .
mv sbin/losetup sbin/losetup.noaes
cp -f /sbin/losetup sbin
mv bin/mount bin/mount.noaes
cp -f /bin/mount bin
cp -f /usr/src/gnupg-1.4.23/g10/gpg bin
touch pubring.gpg
touch secring.gpg
rsync /usr/lib/modules/6.11.10 lib/modules
Nun müssen wir noch dafür sorgen das auch wirrklich loopaes benutzt wird. Dafür gehen wir nach initrd/main/scripts/local-top/
und erzeigen die Datei loopaes mit folgendem Inhalt:
#!/bin/sh
echo "load loop"
modprobe loop
while ! [ -b /dev/loop3 ]; do
sleep 1
echo "wait for device"
done
echo "wait for passwd"
while [ true ]; do
if ! /sbin/losetup -e AES256 -I 0 -K /rootkey.gpg -G / /dev/loop3 /dev/sda3 ; then
echo "try again"
continue
fi
break
done
echo "ROOT=\"/dev/loop3\"" >> /conf/param.conf
Ich habe loop3 ausgewählt, weil sda3 auch unsere Root-Partion sein soll. Neben dieser Datei die mittels chmod a+x loopaes auch ausführbar sein sollte, müssen wir noch in der Datei ORDER ergänzen. Dort fügen wir an:
/scripts/local-top/loopaes "$@"
[ -e /conf/param.conf ] && . /conf/param.conf
Wen bestimmte Hardware nicht erkannt wird (z.b. WLAN bei deuen e100 Boxen) fehlt in der Regel die Firmware für diese Hardware.
Mitteles dmesg kann man sich dann das bootlog ansehen und die fehlende Firmware dann entsprechend nach: /usr/src/initrd/main/lib/firmware schieben (nicht alles von /usr/lib/firmware !).
Mit dieser Abfolge von Befehlen erzeugen wir eine neue initrd mit dem Namen sda3initrd
cd initrd
# Add the first microcode firmware
# --------------------------------
cd early
find . -print0 | cpio --null --create --format=newc > /usr/src/sda3initrd
# Add the second microcode firmware
# ---------------------------------
cd ../early2
find kernel -print0 | cpio --null --create --format=newc >> /usr/src/sda3initrd
# Add the ram fs file system
# --------------------------
cd ../main
find . | cpio --create --format=newc | xz --format=lzma >> /usr/src/sda3initrd
Da wir das ggf. öfter machen wollen, können wir diese Zeilen auch in eine Datei schreiben (executabel). die sd2initrd sollten wir nun noch /boot / kopieren
Jetzt fehlt uns nur noch ein Eintrag in der /boot/grub/grub.cfg
menuentry 'Linux Mint 21.2 MATE, with Linux 6.11.10 SDA3' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.11.10-aes' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_msdos
insmod ext2
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 f155d049-0c06-4bfc-81bb-a9587240e3fe
else
search --no-floppy --fs-uuid --set=root f155d049-0c06-4bfc-81bb-a9587240e3fe
fi
echo 'Loading Linux 6.11.10 ...'
linux /vmlinuz-6.11.10 root=UUID=f155d049-0c06-4bfc-81bb-a9587240e3fe ro nosgx
echo 'Loading initial ramdisk ...'
initrd /sda3initrd
}
Die UUID: f155d049-0c06-4bfc-81bb-a9587240e3fe ist unsere /boot/ Partition - das root-Device haben wir mittels Script ja hart auf sda3 gesetzt - ist hier also egal.
Jetzt sind wir fertig und können neu booten.
Alle genannten Befehle dienen als Anregung - es selber zu versuchen. Bei Fehlermeldungen kann nur der eigene Verstand oder zur Not Mister "google" helfen.
Habt immer ein Backup und eine Install-CD, um im Notfall zu reparieren!