# Ruhezustand mit encrypted Swap.

## Max Steel

Hallo Leute,

hier heute mal einen Ansatz der garnicht neu ist und für mich funktioniert.

Quasi ein positiver Erfahrungsbericht.

Ziel ist es für Laptops den Datendiebstahl durch einfaches Laptop mitnehmen zu erschweren, sodass es sich für "${Angreifer}" kaum lohnt, dich stehen zu lassen. (FYI Ich bin kein wirklich paranoider Typ, sonst würde ich "mein Setup" ja wohl kaum vorstellen  :Wink:  )

An dieser Stelle hoffe ich dass jeder irgendwie die Partitionen resizen kann um etwas zusätzlichen Platz für eine eigene swap-Partition anzulegen, oder schon immer eine eigene swap dafür hatte, diese aber bislang nicht nutzen konnte.

Was brauchen wir:

Ein laufendes Gentoo Linux mit crypted Root.

ein wenig Platz auf der Platte für eine eigene Partition für swap (ich wählte die Größe etwas über dem eingebauten Arbeitsspeicher)

Also, wie gehts los.

Den ersten Rückschlag über den ich garnicht vorher nachdachte, das Standardsetup von dmcrypt sieht wohl vor, dass der Key für das cryptswap aus RNG-Daten automagisch generiert wird und es jeden Boot neu erzeugt wird. Ich habe cryptswap allerdings fest mit LUKS und 2 Keys formatiert. Einem keyfile, welches ich unter /etc/crypt legte, root-only lesbar natürlich generiert aus urandom (bytes=4096 count=1).

```
dd if=/dev/urandom of=/etc/crypt/cryptswap bytes=4096 count=1

cryptsetup luksFormat /dev/sda3 -d /etc/crypt/cryptswap
```

und zum zweiten ein zusätzliches Passwort, da man auch in der Wildnis den Rechner zuverlässig aus dem Ruhezustand holen können möchte.

```
cryptsetup luksAddKey /dev/sda3 -d /etc/crypt/cryptswap
```

in der /etc/conf.d/dmcrypt muss das natürlich auch entsprechend geändert werden, sonst wäre das alles hinfällig:

```
#/etc/conf.d/dmcrypt

target=cryptswap

source='/dev/sda3'

key='/etc/crypt/swap'

```

Nun zur initramfs, das Setup habe ich mit einer genkernel-initramfs ehrlich gesagt garnicht erst ausprobiert. Ich habe meine initramfs mittels usr/gen_init_cpio aus dem Kernel-paket erstellt.

Dieses Tool nach /usr/src/initramfs kopiert und um eine initramfs-list und einem init erweitert und wir sind ready-to-go.

Die Ergänzung innerhalb des init-scripts sieht einen dividing Path vor, der auf das Keyword resume in der cmdline des Kernel reagiert um dann nach resume_after_hibernate abzubiegen:

```
#/usr/src/initramfs/init

[...]

resume_from_hibernation() {

        /sbin/cryptsetup open /dev/sda3 cryptswap --allow-discards || rescue_shell

        echo "Resuming previous Session."

        echo /dev/dm-0 > /sys/power/resume

}

# temporarily mount proc and sys

mount -t proc none /proc

mount -t sysfs none /sys

# start for real here

KERNELCMDLINE="`cat /proc/cmdline`"

for i in ${KERNELCMDLINE}; do

        case ${i} in

                resume)

                        resume_from_hibernation

                        ;;

                *)

                        ;;

        esac

done

[...]

```

Die initramfs-list kann gerne mit dem gefüllt werden was man gerne so drin hat aber beachtet bitte dass die benötigten Libs alle vorhanden sind. dazu verwendete ich den kurzen Befehl:

```
for i in /bin/busybox /sbin/cryptsetup /sbin/lvm; do ldd ${i}; done | cut -d' ' -f1 | uniq
```

Das legte für mich den Schluss nahe dass ich folgende initramfs-list benötige (ich gehe hier von einem statischen dev-system aus. und brauche daher kein udev, mdev oder ähnliches. muss mich dafür um die nötigen nodes selbst kümmern)

```
#/usr/src/initramfs/initramfs-list

# directory structure

dir /bin        755 0 0

dir /usr        755 0 0

dir /bin        755 0 0

dir /sys        755 0 0

dir /var        755 0 0

dir /lib64      755 0 0

dir /proc       755 0 0

dir /mnt        755 0 0

dir /mnt/root   755 0 0

dir /etc        755 0 0

dir /root       755 0 0

dir /dev        755 0 0

dir /dev/mapper 755 0 0

slink /sbin     /bin    755 0 0

slink /lib      /lib64  755 0 0

slink /usr/lib  /lib64  755 0 0

slink /usr/lib64 /lib64 755 0 0

# we have a static /dev so we need all dev entries too

# e.g. /dev/console below

nod /dev/console        0600 0 0 c 5 1

nod /dev/null           0666 0 0 c 1 5

nod /dev/random         0666 0 0 c 1 8

nod /dev/urandom        0666 0 0 c 1 9

# dev/sda and partitions

nod /dev/sda            0660 0 0 b 8 0

nod /dev/sda1           0660 0 0 b 8 1

nod /dev/sda2           0660 0 0 b 8 2

nod /dev/sda3           0660 0 0 b 8 3

nod /dev/sda4           0660 0 0 b 8 4

# dev/sdb

nod /dev/sdb            0660 0 0 b 8 16

nod /dev/sdb1           0660 0 0 b 8 17

# dev/sdc

nod /dev/sdc            0660 0 0 b 8 32

nod /dev/sdc1           0660 0 0 b 8 33

# all the device-mapper nodes I need

nod /dev/dm-0           0660 0 0 b 253 0

nod /dev/dm-1           0660 0 0 b 253 1

nod /dev/dm-2           0660 0 0 b 253 2

nod /dev/dm-3           0660 0 0 b 253 3

nod /dev/dm-4           0660 0 0 b 253 4

nod /dev/dm-5           0660 0 0 b 253 5

nod /dev/dm-6           0660 0 0 b 253 6

nod /dev/dm-7           0660 0 0 b 253 7

slink /dev/stderr       /proc/self/fd/2 777 0 0

slink /dev/stdin        /proc/self/fd/0 777 0 0

slink /dev/stdout       /proc/self/fd/1 777 0 0

# busybox

file /bin/busybox       /bin/busybox    755 0 0

# for lvm on crypt

file /bin/cryptsetup    /sbin/cryptsetup 755 0 0

file /bin/lvm           /sbin/lvm       755 0 0

# libraries required

file    /lib64/ld-linux-x86-64.so.2     /lib64/ld-linux-x86-64.so.2     755 0 0

file    /lib64/libargon2.so.1           /usr/lib64/libargon2.so.1       755 0 0

file    /lib64/libblkid.so.1            /lib64/libblkid.so.1            755 0 0

file    /lib64/libcom_err.so.2          /lib64/libcom_err.so.2          755 0 0

file    /lib64/libcrypto.so.1.0.0       /usr/lib64/libcrypto.so.1.0.0   755 0 0

file    /lib64/libcryptsetup.so.12      /usr/lib64/libcryptsetup.so.12  755 0 0

file    /lib64/libc.so.6                /lib64/libc.so.6                755 0 0

file    /lib64/libdevmapper-event.so.1.02       /lib64/libdevmapper-event.so.1.02       755 0 0

file    /lib64/libdevmapper.so.1.02     /lib64/libdevmapper.so.1.02     755 0 0

file    /lib64/libdl.so.2               /lib64/libdl.so.2               755 0 0

file    /lib64/libe2p.so.2              /lib64/libe2p.so.2              755 0 0

file    /lib64/libext2fs.so.2           /lib64/libext2fs.so.2           755 0 0

file    /lib64/libjson-c.so.4           /usr/lib64/libjson-c.so.4       755 0 0

file    /lib64/libmount.so.1            /lib64/libmount.so.1            755 0 0

file    /lib64/libm.so.6                /lib64/libm.so.6                755 0 0

file    /lib64/libncurses.so.6          /lib64/libncurses.so.6          755 0 0

file    /lib64/libpopt.so.0             /usr/lib64/libpopt.so.0         755 0 0

file    /lib64/libpthread.so.0          /lib64/libpthread.so.0          755 0 0

file    /lib64/libreadline.so.7         /lib64/libreadline.so.7         755 0 0

file    /lib64/librt.so.1               /lib64/librt.so.1               755 0 0

file    /lib64/libudev.so.1             /lib64/libudev.so.1             755 0 0

file    /lib64/libuuid.so.1             /lib64/libuuid.so.1             755 0 0

file    /lib64/libz.so.1                /lib64/libz.so.1                755 0 0

file    /bin/fsck              /sbin/fsck                      755 0 0

file    /bin/fsck.ext4         /sbin/fsck.ext4                 755 0 0

# our init script

file    /init                   /usr/src/initramfs/init               755 0 0

```

generiert wird die initramfs dann mit deem einfachen Befehl:

```
./gen_init_cpio initramfs-list > /boot/initramfs
```

(FYI: Meine tools sind alle nicht static compiled. Also hier, gibts durchaus Raum für Verbesserungen um die extra-libs loszubekommen.)

Gut! schön! nun haben wir i.d.T alles vorhanden um manuell zu stoppen und zu starten. Ich wollte aber das grub automatisch auf einen Eintrag mit resume springt.

diesen ganzen grub-mkconfig rubbish hab ich nie ganz verstanden. Daher hab ich die grub.cfg schon immer händisch geschrieben und nutze auch hier 2 fast identische Einträge und das Tool grub-save-default.

```
#/etc/grub/grub.conf

set timeout="3"

load_env

set default="${saved_entry}"

function savedefault {

        set saved_entry="0"

        save_env saved_entry

}

menuentry 'Gentoo Linux' --class gnu-linux --id Gentoo-Linux {

        set root='(hd0,gpt2)'

        savedefault

        linux /vmlinuz root=/dev/system/root CONSOLE=tty1 init=/init

        initrd /initramfs

}

menuentry 'Gentoo Linux Resume from Suspend to Disk' --class gnu-linux --id Gentoo-Linux-resume {

        set root='(hd0,gpt2)'

        savedefault

        linux /vmlinuz root=/dev/system/root CONSOLE=tty1 init=/init resume

        initrd /initramfs

}

```

und dem elogind habe ich als hook folgendes Script mitgegeben:

```
#/lib64/elogind/system-sleep/01grub

#! /bin/bash

case $1/$2 in

  pre/hibernate)

    grub-set-default 1

    sync

    umount /boot/efi /boot

    ;;

  post/hibernate)

    mount /boot

    mount /boot/efi

    grub-set-default 0

    ;;

esac
```

(nicht vergessen dass das skript exec sein muss chmod +x /lib64/elogind/system-sleep/01grub)

Das waren meine 2 ct. ich habe zu dem ganzen nicht wirklich Quellen, aber 2 möchte ich nennen die mir persönlich bei der Sache halfen:

https://wiki.gentoo.org/wiki/Custom_Initramfs/Hibernation

https://wiki.gentoo.org/wiki/Old_Fashioned_Gentoo_Install#Making_the_initrd

PS: Ergänzungen, Verbesserungen und Shitstorm in die Kommentare, die Freude darüber variiert.

PPS: Sorry für die krude Schreibweise... ich weiß nicht wirklich wie man sinnvoll eine Dokumentation schreibt und schrieb einfach wie ich dachte. Verbesserungen sind willkommen.

Edith: 15.12.22

pm-utils ist alt und keiner will das mehr, daher eine Änderung um stattdessen elogind zu unterstützen.

----------

