Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
C6 Embedded Initramfs für signed IMA
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

 
Reply to topic    Gentoo Forums Forum Index Deutsches Forum (German) Deutsche Dokumentation
View previous topic :: View next topic  
Author Message
pietinger
Moderator
Moderator


Joined: 17 Oct 2006
Posts: 5167
Location: Bavaria

PostPosted: Sat Nov 26, 2022 4:29 am    Post subject: C6 Embedded Initramfs für signed IMA Reply with quote

(Dieser Post ist Teil einer Installation-Anleitung. Falls nicht schon geschehen lies bitte: Installation Guide for Paranoid Dummies Post Nr. 2)


C.6 Embedded Initramfs für signed IMA

... auf vielfachen Wunsch eines Einzelnen :D durfte ich mich mit einem ungeliebten Thema auseinandersetzen ... Ja, ich mag eigentlich kein initramfs. Glücklicherweise ist vieles im Laufe der Zeit besser und einfacher geworden. Wenn Du die beiden Links ins Wiki aus dem vorherigen Post liest, vergiß einiges gleich wieder. Es ist nicht mehr notwendig ein Utility (gen_init_cpio) vorher manuell zu compilieren oder ausführbar zu machen - das macht der "make" automatisch selbst.

Im anderen Artikel steht, dass für ein embedded initramfs die Kernel Option "Initramfs source file(s)" auf ein Verzeichnis stehen sollte, in dem schon alle Dateien drin sind. Es geht aber noch einfacher: Wir zeigen in dieser Kernel Option nur auf eine Datei mit einer Liste aller nötigen Dateien und der "make" macht wieder alles selbst (Nein, der delegiert das auch nur an die Tools).

Falls Du mal die Bezeichnung "UKI" gehört haben solltest. Ja, wir haben damit ein "Unified Kernel Image" in dem alles eingepackt ist:
- Kernel selbst
- Kernel Command Line
- Microcode und Firmware (für z.B. Intel Prozessor und Intel GPU)
- Initramfs
Damit können wir dieses Image signieren und eine schönen SecureBoot machen. DAS ALLES MIT BORDMITTELN und nicht so idiotisch wie z.B. hier:
https://wiki.archlinux.org/title/Unified_kernel_image

(Sorry, aber da musste ich jetzt mal ein bischen lästern)

Falls Du mal selbst ein embedded initramfs bauen willst ... das wichtigste was Du wissen musst: Selbst wenn Du alle Devices mittels "mount -t devtmpfs none /dev " erstellen läßt, musst Du /dev/console zwingend vorher manuell in Deinem initramfs drin haben. Deshalb MUSS die Zeile "nod /dev/console 0600 0 0 c 5 1" zwingend in die initramfs_list. Gemeinerweise wäre das nicht nötig wenn Du Dein initramfs als EXTERNES CPIO-Archiv bauen würdest. (Erklärung auf Englisch findest Du hier: https://wiki.gentoo.org/wiki/User:Pietinger/Tutorials/Initramfs_Overview#Why_do_I_need_an_additional_line_when_using_an_embedded_initramfs_.3F )

Was aber wirklich gezickt hat, war nicht das Bauen des initramfs, sondern IMA ... Ja, sobald man IMA aktiviert, ist es auch aktiv ... und verhindert das Laden von ausführbaren Programmen die keine Signierung (früher: Hash) haben. Diese werden ja in den erweiterten Attributen des File-Systems gespeichert ... leider hat ein initramfs keine erweiterten Attribute. Hahaha :evil:

Wenn Du das INIT Skript betrachtest, wirst Du feststellen, dass nach der Aktivierung von IMA (durch das Laden der Policy) nicht mehr das im initramfs enthaltene busybox aufgerufen wird / werden kann, sondern nur noch das auf unserer "echten" Root Partition ... weil das eben signiert ist. Das ist auch der Grund warum busybox zwingend statisch gebaut werden muss. Denn der Aufruf von /mnt/root/bin/busybox ist nicht in der Lage Libraries nachzuladen. Ja, ich habe das hier gelesen und dachte es wäre eine gute Idee:
https://wiki.gentoo.org/wiki/Talk:Early_Userspace_Mounting#static_busybox_.3F
Ist aber leider nicht möglich. Das ist auch der Grund für den etwas merkwürdig aussehenden Aufruf von switch_root (am Ende von init). Glaub mir, jede andere Kombination führt zu einem Segmentation Fault und damit zu einer Kernel Panic ... rate mal wie ich zu dem 10. Post in A.2 gekommen bin ...

Falls Du mal dieses init File erweitern möchtest, solltest Du alles was Du einbauen willst VOR der Aktivierung von IMA machen.


Ich habe das mit meinem monolithischen Kernel Version 5.15.79 getestet, möchte das aber ausdrücklich noch als EXPERIMENTELL brandmarken. (weil das eben noch nicht lange genug getestet ist).


Voraussetzungen

Du hast einfach mal alles von C.2 bis C.5 gemacht (und verstanden), oder Du kannst alle Schritte gedanklich kombinieren ;-)


Vorbereitungen

0. Boote in den UNLOCKED Kernel und melde Dich dort als root an.

1. Das umkopieren des öffentlichen Schlüssels/Zertifikat nach /etc/ima ist zwar nicht zwingend nötig, aber damit ist es etwas aufgeräumter. Wir holen uns den Schlüssel nämlich später aus /etc/ima. Wenn Du einen anderen Namen verwendet hast musst Du das weiter unten anpassen oder Du renamest es gleich jetzt.
Code:
# cp /etc/MY/efikeys/DB.cer /etc/ima/.


2. Wir benötigen busybox. Und zwar statisch. Stand heute benötigt das drei Use-Flags. Das kann sich aber wieder ändern. Probiere deshalb zuerst den "emerge -p" NUR mit Use-Flag "static", dann mit "-pam static". Und wenn sich nichts geändert haben sollte, benötigst Du:
Code:
USE="-pam static static-libs" emerge -pvD busybox

Damit wird halt zwangsweise auch noch libxcrypt re-emerged. Natürlich musst Du auch das bei Gelegenheit in die /etc/portage/package.use reintun ;-)
Überprüfe sicherheitshalber ob busybox wirklich statisch gebaut wurde:
Code:
# ldd /bin/busybox
        das Programm ist nicht dynamisch gelinkt

3. Falls Du IMA bereits im Einsatz hast, vergiß nicht das alles zu signieren => C.4 und C.5.

4. Zuletzt entferne das bisherige Run-Skript aus dem Runlevel "boot" falls Du IMA bereits im Einsatz hattest:
Code:
# rc-update del loadimapolicy boot



Erstellung initramfs

1. Diese Verzeichnisse und Dateien werden benötigt:
Code:
mkdir /usr/src/initramfs
# nano -w /usr/src/initramfs/initramfs_list
=>
dir /bin        755 0 0
dir /dev        755 0 0
dir /etc        755 0 0
dir /lib        755 0 0
dir /lib64      755 0 0
dir /mnt        755 0 0
dir /mnt/root   755 0 0
dir /proc       755 0 0
dir /root       700 0 0
dir /sbin       755 0 0
dir /sys        755 0 0
dir /usr        755 0 0
dir /usr/bin    755 0 0
dir /usr/lib64  755 0 0
dir /var        755 0 0
nod /dev/console 0600 0 0 c 5 1
file    /init                           /usr/src/initramfs/init         755 0 0
file    /DB.cer                         /etc/ima/DB.cer                 755 0 0
file    /policy.conf                    /etc/ima/policy.conf            755 0 0
file    /bin/busybox                    /bin/busybox                    755 0 0
file    /bin/cat                        /bin/cat                        755 0 0
file    /bin/keyctl                     /bin/keyctl                     755 0 0
file    /usr/bin/evmctl                 /usr/bin/evmctl                 755 0 0
file    /lib64/ld-linux-x86-64.so.2     /lib64/ld-linux-x86-64.so.2     755 0 0
file    /lib64/libc.so.6                /lib64/libc.so.6                755 0 0
file    /usr/lib64/libcrypto.so.1.1     /usr/lib64/libcrypto.so.1.1     755 0 0
file    /lib64/libkeyutils.so.1.10      /lib64/libkeyutils.so.1.10      755 0 0
slink   /lib64/libkeyutils.so.1         /lib64/libkeyutils.so.1.10      777 0 0
file    /usr/lib64/libimaevm.so.3.0.0   /usr/lib64/libimaevm.so.3.0.0   755 0 0
slink   /usr/lib64/libimaevm.so.3       /usr/lib64/libimaevm.so.3.0.0   777 0 0

Falls dieser Post schon etwas älter sein sollte, überprüfe mit "ldd" für die Kommandos "keyctl", "evmctl" und "cat", ob diese noch die obigen Libraries anziehen. Falls sich da was geändert haben sollte, musst Du natürlich die Liste anpassen. Überprüfe auch ob es nicht nur Softlinks auf die eigentliche Library sind (wie z.B. bei "libkeyutils" und "libimaevm"). Diese benötigen dann natürlich auch noch den entsprechenden Link-Eintrag.

2. In diesem init-File musst Du eine Zeile editieren. Ändere NUR die ID selbst ! Benutze NICHT die PARTUUID von Deiner Root Partition. Lasse das UUID großgeschrieben.
Code:
# nano -w /usr/src/initramfs/init
=>
#!/bin/busybox sh

### CHANGE THIS !
myrootpartition="UUID=c75f64b1-a1b1-4527-b996-4b4b9d24456c"

abend() {
    echo "$@"
    echo "You are now in a rescue shell."
    busybox --install -s
    exec /bin/sh
}

echo "Mounting proc, sys, devtmpfs and securityfs ..."
mount -t devtmpfs none /dev || abend "Error: mount /devtmpfs failed !"
mount -t proc none /proc || abend "Error: mount /proc failed !"
mount -t sysfs none /sys || abend "Error: mount /sysfs failed !"
mount -t securityfs securityfs /sys/kernel/security || abend "Error: mount /sys/kernel/securityfs failed !"

echo "Searching root partition device name of $myrootpartition ..."
rootdev=`findfs $myrootpartition` || abend "Error with findfs !"
echo "Found $rootdev as your root partition. Will mount it now ..."
mount -o ro $rootdev /mnt/root || abend "Error mounting root partition !"

### IMA Core routine begin

echo "Loading IMA certificate ..."
ima_id=$(/bin/keyctl newring _ima @u) >> /dev/null || abend "Error creating keyring !"
ima_key=`/usr/bin/evmctl import /DB.cer $ima_id`  >> /dev/null || abend "Error importing certificate !"
/bin/keyctl setperm $ima_key 0x0b0b0000 >> /dev/null
/bin/keyctl setperm $ima_id 0x0b0b0000 >> /dev/null

echo "Loading custom IMA policy ..."
/bin/cat /policy.conf > /sys/kernel/security/integrity/ima/policy || abend "Error loading IMA policy !"

### IMA Core routine end

### Now IMA is activ and therefore a "busybox --install -s" would fail with "permission denied".
### This means, you cannot use abend() anymore here !

echo "Unmounting proc, sys, devtmpfs and securityfs ..."
/mnt/root/bin/busybox umount /proc /sys/kernel/security /sys /dev

echo "All done. Switching to real root."
exec /mnt/root/bin/busybox switch_root /mnt/root /sbin/init


3. ERGÄNZE Deine Kernel Config mit:
Code:
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/usr/src/initramfs/initramfs_list) Initramfs source file(s)
    [*]   Support initial ramdisk/ramfs compressed using gzip
    Built-in initramfs compression mode (Gzip)  --->

Folgendes ...
Code:
Device Drivers  --->
    Generic Driver Options  --->
        -*- Maintain a devtmpfs filesystem to mount at /dev

... müsste bei Verwendung unserer Gentoo Souces bereits automatisch enabled sein, weil:
Quote:
Selected by [y]:
- GENTOO_LINUX_UDEV [=y] && GENTOO_LINUX [=y]

Eine Überprüfung schadet aber sicher nicht. Theoretisch kannst Du jetzt auch in Deiner Built-in Kernel Command Line den Paramter "root=... ro" raussschmeißen. Ist aber nicht nötig - der Kernel ignoriert das einfach.

4. Erstelle nun den neuen Kernel mit dem embedded intitramfs und installiere ihn als Deinen neuen EVERY-DAY-Kernel wie Du es sonst auch immer machst. Zum Beispiel:
Code:
# mount /boot
# cd /usr/src/linux
# make -j8
# sbsign --key ........ --cert /etc/MY/efikeys/DB.crt --output /boot/EFI/Boot/bzImage.efi arch/x86/boot/bzImage
# reboot



Sonstiges

Falls Du mal dieses initramfs ändern möchtest (Dateien oder init) gibt es zwei Möglichkeiten bei einem "make" den Neubau zu erzwingen:
1. Du machst ein "make clean" vorher, ODER
2. Du löscht manuell all das:
Code:
# cd /usr/src/linux/usr
# rm initramfs_data.cpio
# rm initramfs_data.o
# rm initramfs_inc_data
# rm built-in.a
# rm .built-in.a.cmd
# rm .initramfs_data.cpio.*
# rm .initramfs_data.o.cmd
# rm .initramfs_inc_data.cmd


.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Deutsches Forum (German) Deutsche Dokumentation All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum