Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
C5 Umstellung auf 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: 5163
Location: Bavaria

PostPosted: Sun Oct 30, 2022 12:21 am    Post subject: C5 Umstellung auf 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)

Hinweis: Diese Beschreibung wurde getestet mit einem signierten, monolithischen, (stub-) Kernel (*) der Version 5.15.75, der per SecureBoot von UEFI direkt geladen wird. (* das bedeutet B.2 und B.3 wurden komplett vorher umgesetzt. Ebenso war mein System bereits nach C.2 und C.3 installiert).



C.5 Umstellung auf Signed IMA


Warum ?

Weil es sicherer ist ! Natürlich verhindert unser IMA bereits jetzt, dass alle automatisierten Angriffe (die erfolgreich waren und Binaries nachladen wollen/müssen) unsere Programme nicht modifizieren, oder neue Programme installieren können. Was ist aber wenn ein Mensch auf der anderen Seite sitzt - mit einer root Shell unserer Kiste - und sich erstmal gemütlich umschaut was wir denn alles auf unserer Kiste haben. Leider kann er dann auch genau das gleiche machen, was wir ja auch können: "evmctl ima_hash ..." anwerfen und Hashes generieren ... außerdem ... es kann ja sein, dass zukünftige automatisierte Angriffe auch das noch überprüfen und so das derzeitige hash-basierte IMA überwinden ...

Klar, unsere Daten sind jetzt sowieso im A...Eimer - also wieso überhaupt noch das System gegen Veränderungen schützen ? Naja, es soll auch "stille" Angriffe geben, die sich nicht für die vorhandenen Daten interessieren, sondern für verschlüsselte Daten, die wir erst per Schlüssel-Eingabe freischalten müssen. Dann braucht man halt einen (Software-) Keylogger, den ein Angreifer aber erstmal installieren müsste. Kann er aber nicht, da selbst wir - als User "root" - den geheimen Schlüssel (Key) benötigen um auch noch irgendeine ausführbare Datei updaten oder installieren zu können ... und dieser befindet sich natürlich nicht auf unserer Kiste, sondern auf dem USB-Stick !

Hinweis: Im folgenden wird der Einfachheit halber der geheime Schlüssel aus /etc/MY/efikeys genommen ...das ist aber NUR für die Umstelllung ! Natürlich kopieren wir ihn zum Schluß auf ZWEI USB-Sticks und löschen ihn da raus. Diese Beschreibung erspare ich mir aber - wie das geht weißt Du eh' (oder lies den 2. Post von B.4)

Ein weiterer, eher persönlicher Grund war meine Verzweiflung mit diversen Anleitungen (die anscheinend nur voneinander abschreiben ohne es selbst getestet zu haben). Den Unterschied zwischen einem .ima (Punkt-ima) und einem _ima (Unterstrich) Keyring kann man schnell finden, und natürlich kenne ich auch die verschieden Key Identifiers (z.B. user @u und session @s). Bevor ich aber meinen PC komplett umstelle, würde ich schon gerne den wichtigsten Vorgang testen. Tja, dieses hier:
Code:
# evmctl import --rsa rsa_public.pem $(keyctl newring _ima @u)

hat mir immer ein "Permission denied" gegeben (als root User natürlich). Da zögert man doch ein wenig, die Empfehlungen aus der Manpage von "evmctl" umzusetzen ... (ganze Story unten).

Lange Rede - kurzer Sinn: Es funktioniert schon - aber nur beim Systemstart ?! Da ich kein Experte für die Keys im Kernel bin, kann ich nicht sagen warum. Falls Du das weißt, würde ich mich natürlich sehr über eine Antwort freuen (gerne hier als Post, oder auch Mail).

Kommt jetzt EVM ?

Nein. EVM kann ALLE erweiterten Attribute per Signatur = asymmetrische Verschlüsselung schützen, wie z.B. die für SELinux und natürlich auch die von IMA. Aaaaber, IMA kann das selbst auch für sich. Da wir kein SELinux haben, benötigen wir kein extra EVM, sondern nehmen das "Eingebaute" von IMA selbst her (Unterschied ist hier die Verwendung der Kommandos "imasign" und "sign" beim "evmctl").

Schlüssel

Was wir aber natürlich genauso benötigen sind ein geheimer, privater Schlüssel und der passende, dazugehörende öffentliche Schlüssel. Haben wir aber bereits ... (hehe, Faulheit siegt) ... in B.3 gemacht. Natürlich kann ich den gleichen Schlüssel hernehmen um den Kernel zu signieren UND kann ihn auch für IMA verwenden. Falls Du B.3 nicht gemacht hast: Hole Dir einfach das Skript aus dem 1. Kapitel und lasse Dir alles erstellen. Der ganze Zinnober aus der Manpage von "evmctl" muss wirklich nicht sein. Wir benötigen nur den DB.key - das ist der geheime Schlüssel im PEM Format (Base64) - und DB.cer - der öffentliche Schlüssel/Zertifikat im DER Format (ASN.1). Falls Du andere Verzeichnisse benutzt hast, musst Du natürlich einiges anpassen (muss ich aber eh' nicht mehr sagen - oder?). Falls Du Deinen Key per Passwort sichern willst (statt ihn auf Stick auszulagern) hilft Dir diese Seite weiter: https://en.opensuse.org/SDB:Ima_evm

Voraussetzungen

Nach meinem Dafürhalten ist weder die Umstellung auf SecureBoot nötig (nimm halt nur das Skript), noch ein monolithischer Kernel. Ich habe aber die komplette Kombination (inkl. LOCKDOWN) installiert und so getestet. Für alles andere möchte ich nicht die Hand ins Feuer legen. Was Du aber benötigst:

- Du hast das Package "keyutils" installiert (so wie ich es bereits in A.3 empfohlen habe), und
- Schlüssel DB.key und DB.cer (aus B.3), und
- Du hast C.2 und C.3 bereits komplett gemacht, denn diese Beschreibung macht eine UMSTELLUNG und keine Neu-Installation, ODER
- Du bist in der Lage diesen Artikel mit C.2 und C.3 gedanklich zu mergen und damit alles auf einmal zu machen.


Umstellung

1. Boote in den UNLOCKED Kernel (und melde Dich dort als root an). Wir werden alles Nötige nur dort machen.

2. ERSETZE die derzeitige Policy (komplett) gegen die Neue:
Code:
# cd /etc/ima
# nano -w policy.conf
=>
dont_appraise fsmagic=0x9fa0
dont_appraise fsmagic=0x62656572
dont_appraise fsmagic=0x64626720
dont_appraise fsmagic=0x1021994
dont_appraise fsmagic=0x1cd1
dont_appraise fsmagic=0x42494e4d
dont_appraise fsmagic=0x73636673
dont_appraise fsmagic=0xf97cff8c
dont_appraise fsmagic=0x43415d53
dont_appraise fsmagic=0x27e0eb
dont_appraise fsmagic=0x63677270
dont_appraise fsmagic=0x6e736673
appraise func=MMAP_CHECK mask=MAY_EXEC appraise_type=imasig
appraise func=BPRM_CHECK mask=MAY_EXEC appraise_type=imasig

Falls Du Dich fragst, warum ich die ganzen "dont_measure"-Zeilen rausgeschmissen habe: Sie haben eh' nichts bewirkt ! Wenn ich in den UNLOCKED Kernel boote - wo wir ja den Parameter "fix" haben" - wird aber nichts gefixt, sondern es ist trotzdem notwendig manuell allen neuen (und geänderten) Executables einen Hash - respektive jetzt eine Signatur - zu verpassen. Vielleicht war es mal geplant, dass der Kernel je nachdem welchen Parameter er bekommt, unterschiedlich reagiert ? Stand heute ist aber so, dass man eigentlich zwei verschiedene Policies bräuchte (einmal Alles mit "dont_measure" wenn wir mit "fix" booten und einmal Alles mit "dont_appraise" wenn wir im enforced Modus booten. Wie soll ich die jeweilige Policy beim Booten auswählen ? Egal - es ist jetzt komlett raus - weil Unnütz !


3. ERSETZE das derzeitige Start-Stop-Skript gegen das Neue:
Code:
# cd /etc/init.d
# nano -w loadimapolicy
=>
#!/sbin/openrc-run
# Copyright 1999-2020 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

description="Load in custom IMA policy"

depend()
{
        need sysfs localmount
        before apparmor
}

start()
{
        ebegin "Loading IMA certificate"
                ima_id=$(keyctl newring _ima @u) >> /dev/null
                ima_key=`evmctl import /etc/MY/efikeys/DB.cer $ima_id`  >> /dev/null
                keyctl setperm $ima_key 0x0b0b0000 >> /dev/null
                keyctl setperm $ima_id 0x0b0b0000 >> /dev/null
        eend $?

        ebegin "Loading custom IMA policy"
                cat /etc/ima/policy.conf > /sys/kernel/security/integrity/ima/policy
        eend $?
}

Hinweis: So wie es hier da steht ist es schon richtig. Wir verwenden auf keinen Fall den Parameter "--rsa" beim "evmctl import" weil wir keinen veralteten RSA key type v1 haben.

4. ERGÄNZE Deine Kernel Konfiguration (zusätzlich zu C.2) wie folgt, kompiliere ihn und installiere ihn als Deinen EVERY-DAY-Kernel (wie Du es sonst auch immer machst):
Code:
# cd /usr/src/linux
# make menuconfig
! Do the change and exit with save
# make ... etc ...

mit
Code:
Security options  --->
    [*]   Enable temporary caching of the last request_key() result
    [*]   Enable register of persistent per-UID keyring
    [*]   ENCRYPTED KEYS
            Default template (ima-sig)  --->
            Default integrity hash algorithm (SHA256)  --->

(Ja, wir stellen auch gleich mal auf SHA256 um; hätte man schon länger machen können, aber bei der Gelegenheit passt es doch)

5. Jetzt müssen wir allen Executables eine Signatur verpassen (statt wie in C.3 einen Hash). Ja, ein Hash ist schon schneller erstellt als ein asymmetrisches Chiffrat. Ich rede jetzt nicht mehr von Minuten, sondern Stunden ... (mein Tip: Lass die letzte Zeile über Nacht laufen).
Code:
find  /bin -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /etc -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /lib -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /lib64 -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /opt -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /root -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /sbin -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;
find  /var -fstype ext4 -type f -uid 0 -executable -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;

find  /usr -fstype ext4 -type f -uid 0 -exec evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key '{}' \;

Warum habe ich die letzte Zeile abgesetzt ? Weil hier der Paramter -executable fehlt. Diesen habe ich zuerst benutzt um nicht jede Datei die root gehört zu signieren (=damit es schneller geht / weil wir es eigentlich nicht benötigen). Leider gab es nach dem Neustart die böse Überraschung, dass KDE nicht startete. Sofort in das Systemlog geschaut ... und festgestellt, dass eine LIB.x.y.irgendwas wegen fehlender Signatur nicht geladen wird. Dieses Teil war aber nur ein Link auf die eigentliche Library und hatte kein x-bit gesetzt ... Lange Rede - kurzer Sinn: Machen Sie es so (tm) by Picard ;-)

6. Das war es auch schon ... Für den folgenden Reboot (in unser Produktiv-System) hilft möglicherweise ein bischen beten ... :lol:

Natürlich musst Du jetzt noch Dein Cheat-Sheet anpassen, da unser geheimer Schlüssel DB.key zukünftig nicht mehr in /etc/MY/efikeys sein wird (habe ich ja oben schon gesagt) wirst Du zuküntig vermutlich diese Zeile nach einem "emerge -u @world" ausführen:
Code:
find / -fstype ext4 -type f -uid 0 -executable -mtime 0 -exec evmctl ima_sign -a sha256 -k /mnt/stick/DB.key '{}' \;

... oder so ähnlich

Natürlich habe ich auch getestet, ob ein Hashen noch genügt. Dafür verwende ich mein Firewall-Skript ;-)
Code:
/etc/MY # ./fwrules-big.sh
/etc/MY #
/etc/MY # evmctl ima_hash -a sha256 fwrules-big.sh
hash(sha256): 040441b89bc862f6e116029ac9672b462cb808cb0f343f50fc93323fbfc7e736f3bf
/etc/MY #
/etc/MY # ./fwrules-big.sh
-bash: ./fwrules-big.sh: /bin/sh: Defekter Interpreter: Keine Berechtigung
/etc/MY #
/etc/MY # evmctl ima_sign -a sha256 -k /etc/MY/efikeys/DB.key fwrules-big.sh
hash(sha256): 41b89bc862f6e116029ac9672b462cb808cb0f343f50fc93323fbfc7e736f3bf
evm/ima signature: 264 bytes
030204f270394501 .... [usw. usw.]
/etc/MY #
/etc/MY # ./fwrules-big.sh
[erfolgreich]

Falls Dir jemand ein "keyctl show" empfohlen hat. Da findest Du Deinen Schlüssel nicht, denn es ist eigentlich ein "keyctl show @s".
Code:
# keyctl show
Session Keyring
 351318639 --alswrv   1000   100  keyring: _ses
 549921754 ---lswrv   1000 65534   \_ keyring: _uid.1000
#
# keyctl show @s
Keyring
 351318639 --alswrv   1000   100  keyring: _ses
 549921754 ---lswrv   1000 65534   \_ keyring: _uid.1000
#
# keyctl show @u
Keyring
 297417218 --alswrv      0 65534  keyring: _uid.0
 530423627 ----s-rv      0     0   \_ keyring: _ima
 275641455 ----s-rv      0     0       \_ asymmetric: MY SECURE BOOT KEYS DB: 1069b2f05a2bd3c9a677af53a7c7f6b3f2703945
#
# keyctl show @us
Keyring
 975279667 --alswrv      0 65534  keyring: _uid_ses.0
 297417218 --alswrv      0 65534   \_ keyring: _uid.0
 530423627 ----s-rv      0     0       \_ keyring: _ima
 275641455 ----s-rv      0     0           \_ asymmetric: MY SECURE BOOT KEYS DB: 1069b2f05a2bd3c9a677af53a7c7f6b3f2703945

Alle keys findest Du in
Code:
# cat /proc/keys
106df46f I--Q---     1 perm 39010000     0     0 asymmetri MY SECURE BOOT KEYS DB: 1069b2f05a2bd3c9a677af53a7c7f6b3f2703945: X509.rsa f2703945 []
11ba3a02 I--Q---     2 perm 1f3f0000     0 65534 keyring   _uid.0: 1
14f0b26f I--Q---   144 perm 3f030000  1000   100 keyring   _ses: 1
1f9d9f4b I--Q---     2 perm 0b0b0000     0     0 keyring   _ima: 1
20c723da I--Q---     3 perm 1f3f0000  1000 65534 keyring   _uid.1000: empty
25d3dadc I--Q---     1 perm 0c030000     0 65534 keyring   .user_reg: 4
3a219633 I--Q---     1 perm 1f3f0000     0 65534 keyring   _uid_ses.0: 1



Ganze Story - nur persönlicher Kram - nicht wichtig

Wie bereits gesagt, sind alle Anleitungen die ich gefunden habe entweder veraltet oder nicht sehr ausführlich (für mich; Experten würden das sicher verneinen). Ich konnte zwar in meinem Terminal (als root) den Keyring _ima mit @u erstellen, aber keinen Schlüssel reinladen (egal mit welcher Anleitung). Also habe ich versucht einen Keyring _ima als Session-Keyring (@s) zu erstellen ... und hier konnte ich dann den Key einfügen (mit "evmctl import") ... Hurra ! Also ans Werk. Man hat ja noch den UNLOCKED kernel als Rescue ... der war dann auch notwendig ... denn ein Boot in den IMA ENFORCED Kernel hat nach dem Starten von "loadimapolicy" mir alles um die Ohren gehauen was nur gibt ... an die tausend Zeilen denied wegen "integrity: no _ima keyring: -126" ... und ein komplettes Hängen im Boot-Vorgang (Kaltstart notwendig).

Tja, also einen Session-Keyring mit @s zu verwenden geht anscheinend beim Systemstart nicht. @u hat er mir zwar nicht in einem laufenden System akzeptiert, aber bevor ich alles zurückstelle, probiere ich es trotzdem noch aus. Im Skript also @s mit @u ersetzt und ein neuer Reboot ... und es ging (bis auf KDE) ... strange ... aber Hurra ! Natürlich habe ich auch in der Manpage von "keyctl" nachgelesen, warum ich in einem laufenden System bei der Verwendung eines User-Keyrings ein Permission denied bekommen, aber das hat mir leider nicht geholfen:
Quote:
"Permission denied" - permission was denied by a UID/GID/mask combination.

Wenn Du Dich da auskennst ... :D
Back to top
View user's profile Send private message
pietinger
Moderator
Moderator


Joined: 17 Oct 2006
Posts: 5163
Location: Bavaria

PostPosted: Tue Nov 01, 2022 12:28 pm    Post subject: Reply with quote

Oh je ... ich habe ganz vergessen, dass Du bis jetzt möglicherweise noch gar keine Verschlüsselung benutzt hast (also kein B.4 gemacht hast) ...

Die bisherige Kernel Konfiguration funktioniert zwar, sollte aber noch ergänzt werden, wenn Du eine (einigermaßen) neuere CPU hast die das kann:
Code:
Cryptographic API  --->
 [*]   CRC32c INTEL hardware acceleration
 [*]   SHA1 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)
 [*]   SHA256 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)
 [*]   SHA512 digest algorithm (SSSE3/AVX/AVX2)
 [*]   AES cipher algorithms (AES-NI)

(Bei mir war es halt wegen "fscrypt" (aus B.4) bereits enabled ... Sorry ... alter Mann vergißt immer mal was.)

Edit 2023-03-09: In Kernel Version 6.1 sind diese verschoben worden in:
Code:
Cryptographic API  --->
    Accelerated Cryptographic Algorithms for CPU (x86)  --->
        [*] Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTR, XTS, GCM (AES-NI)
        [*] Hash functions: SHA-1 (SSSE3/AVX/AVX2/SHA-NI)
        [*] Hash functions: SHA-224 and SHA-256 (SSSE3/AVX/AVX2/SHA-NI)
        [*] Hash functions: SHA-384 and SHA-512 (SSSE3/AVX/AVX2)
        [*] CRC32c (SSE4.2/PCLMULQDQ)


Last edited by pietinger on Thu Mar 09, 2023 12:36 pm; edited 1 time in total
Back to top
View user's profile Send private message
pietinger
Moderator
Moderator


Joined: 17 Oct 2006
Posts: 5163
Location: Bavaria

PostPosted: Fri Nov 04, 2022 4:01 pm    Post subject: Implementierung von IMA auf einem Server Reply with quote

Implementierung von IMA auf einem Server

Wie ich bereits an anderer Stelle in diesem Guide erklärt habe, ist dieser Guide für den Einsatz auf einem Desktop zugeschnitten. Für einen Einsatz auf einem Server muss daher immer einiges in Frage gestellt werden.

Vorab:

Ja, man kann einwenden, dass ein Angreifer mit einer Root-Shell ja auch die Möglichkeit hat, mittels "efibootmgr" die Boot-Order zu ändern um dann mittels "reboot" unseren Unlocked-Kernel zu starten. Noch einfacher wäre es, das Run-Skript "loadimapolicy" mittles "rc-update delete loadimapolicy boot" zu entfernen und dann einfach einen Reboot durchzuführen. IMA wäre dann tot gestellt.

Aaaaber ... in jedem Fall ist ein Reboot nötig um sich IMA zu entledigen ... und genau das sollte eigentlich immer sofort einen "Red Alert" auslösen. Wenn mir meine Kiste gerade "unter den Händen wegbooten" würde, würde ich sicherlich als erstes den Ethernet-Anschluß ziehen (und danach von einem sicheren USB-Stick booten). In größeren Unternehmen ist es ebenfalls so, dass alle Server an einen zentralen Log-Server protokollieren, der 24x7 vom Operating überwacht wird und ein Reboot eines Servers ebenfalls mit Prio. 1 untersucht werden würde. Was macht man aber mit einem nicht überwachten Server - Wo ein Reboot gar nicht auffallen würde (oder erst viel zu spät) ?

IMA auf einem Server

Die einfachste Lösung - die aber sicherlich keinen Gefallen finden wird - ist dafür zu sorgen, dass ein Reboot keinen Neustart des Systems bewirken würde. Sprich, es gibt KEINEN Kernel auf der Festplatte (weder Unlocked noch Produktiv); das System wird/wurde mit einem Kernel auf/von einem USB-Stick gestartet - der sofort nach dem Booten abgezogen wird/wurde. Ein Reboot würde also dazu führen, dass UEFI sich dann bei einem Neustart beschwert, dass es nichts zu booten findet ;-) Dies ist aber keine Lösung für Server die aus der Ferne administriert werden.

Es wurde eine Kombination von IMA mit FS-Verity vorgeschlagen. Ich habe mir das angesehen und bin (noch) nicht davon überzeugt. Warum ? Weil ich für diese Lösung sowieso ein Initramfs benötige. Wenn ich aber eh' ein initramfs benötige, dann kann ich doch sehr einfach den Start von IMA ( = Schlüssel laden + IMA Policy laden) in dieses einbauen (natürlich embedded und nicht als extra Archiv File: https://wiki.gentoo.org/wiki/Custom_Initramfs#Embedding_into_the_Kernel ). Ein Starten von IMA nach einem Neustart kann dann nicht mehr verhindert werden. Die Lösung sieht also so aus:

1. Der Unlocked-Kernel muss wirklich auf einen USB-Stick und darf nicht mehr auf der Platte liegen.
2. Es gibt kein dediziertes "loadimapolicy" Run-Skript mehr, sondern es wird direkt im initramfs ausgeführt (siehe auch: https://wiki.gentoo.org/wiki/Early_Userspace_Mounting ). Man sollte nur nicht vergessen, neben "proc" und "sysfs" auch noch "securityfs" vorher zu mounten ... ;-)

... Siehe C.6 ... 8)
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