Bug 2158155

Summary: Package 98integrity, 97masterkey and 96securityfs modules
Product: Red Hat Enterprise Linux 9 Reporter: Coiby <coxu>
Component: dracutAssignee: Pavel Valena <pvalena>
Status: POST --- QA Contact: Frantisek Sumsal <fsumsal>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 9.2CC: dtardon, fsumsal, perobins, pvalena, rlucente, stefanb
Target Milestone: rcKeywords: FeatureBackport, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
boot error with IMA/EVM enabled none

Description Coiby 2023-01-04 11:42:06 UTC
Description of problem:

For RHEL9, once rpm-plugin-ima is installed, the installed package files will have IMA signatures. For the kernel IMA subsystem to be able to verify the signatures, specified IMA policy and the signing key need to be enrolled by 98integrity module (depends on 97masterkey and 96securityfs). So please backport 98integrity, 97masterkey and 96securityfs modules. Note 98integrity is not enabled by default and will be only enabled unless users choose to. 
 
Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 1 David Tardon 2023-01-11 14:30:01 UTC
Huh? These modules have existed for >10 years, hence they are already available in RHEL-9 for sure. Or am I missing something?

Comment 2 David Tardon 2023-01-11 14:47:07 UTC
Ah, we've never installed those modules in Fedora/RHEL. The comment in the spec file says "with systemd IMA and selinux modules do not make sense". I guess that's no longer true then...

Comment 3 Rich Lucente 2023-02-16 19:49:06 UTC
Please correct me if I'm off here. My understanding is that these modules will load the kernel master key (kmk) and evm-key at boot time if the (default) files /etc/keys/kmk-trusted.blob and /etc/keys/evm-trusted.blob exist. Now that RHEL 9 supports keylime, these keys are required for IMA/EVM. Our docs [1] state to manually import the keys to the uid 0 keyring after a reboot which wouldn't be practical. The 97masterkey and 98integrity modules would automate that. Without these modules, is there another way to do the key import that we support?

[1] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/enhancing-security-with-the-kernel-integrity-subsystem_managing-monitoring-and-updating-the-kernel#enabling-integrity-measurement-architecture-and-extended-verification-module_enhancing-security-with-the-kernel-integrity-subsystem

Comment 4 Rich Lucente 2023-02-17 19:39:38 UTC
This workaround will load the keys at boot time. It relies on the default naming conventions within the three dracut modules 96securityfs, 97masterkey, and 98integrity.

# do all this as root (uid 0) and not sudo (uid whatever) so keys are created in the uid 0 keyring.
sudo -i

# install needed and useful tools
dnf -y install attr coreutils keyutils tpm2-tools

# create a primary storage key in the TPM
tpm2_createprimary --key-algorithm=rsa2048 --key-context=key.ctxt
tpm2_evictcontrol -c key.ctxt 0x81000001

# create the kernel master key and evm key
keyctl add trusted kmk-trusted "new 32 keyhandle=0x81000001" @u
keyctl add encrypted evm-key "new trusted:kmk-trusted 64" @u

# save the keys with the expected full path names
mkdir -p /etc/keys
keyctl pipe $(keyctl search @u trusted kmk-trusted) > /etc/keys/kmk-trusted.blob
keyctl pipe $(keyctl search @u encrypted evm-key) > /etc/keys/evm-trusted.blob

# copy the upstream modules into /usr/lib/dracut/modules.d as they haven't changed in ten years
git clone https://github.com/dracutdevs/dracut.git
cd dracut/modules.d
cp -r 96securityfs 97masterkey 98integrity /usr/lib/dracut/modules.d/

# make sure SELinux contexts and ownership is correct
chown -R root: /etc/keys /usr/lib/dracut/modules.d
restorecon -vFr /etc/keys /usr/lib/dracut/modules.d

# save original initramfs and rebuild with the modules
cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
dracut -f -H -a "securityfs masterkey integrity"

# activate EVM and label the entire filesystem
echo 1 > /sys/kernel/security/evm
find / -fstype xfs -type f -uid 0 -exec head -n 1 '{}' >/dev/null \;

Comment 5 Rich Lucente 2023-02-20 20:15:02 UTC
Created attachment 1945362 [details]
boot error with IMA/EVM enabled

The workaround in comment 4 does not work if you set the IMA/EVM policy in the kernel boot parameters. Specifically, the procedure I'm following is to temporarily disable secure boot and then do the following:

# install the packages git and those needed by dracut modules
dnf -y install git ima-evm-utils keyutils

# add the modules to dracut
git clone https://github.com/dracutdevs/dracut.git
pushd dracut/modules.d
cp -r 96securityfs 97masterkey 98integrity /usr/lib/dracut/modules.d/
popd

# remove local copy of dracut source
rm -fr dracut

# back up existing initramfs
cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
chown -R root: /usr/lib/dracut/modules.d /boot/initramfs-$(uname -r).img*
restorecon -vFr /usr/lib/dracut/modules.d /boot/initramfs-$(uname -r).img*

# make sure needed modules are available
dracut --list-modules | \
    grep -i -e securityfs -e masterkey -e integrity

# initramfs should automatically load kmk and evm-key into the uid 0 keyring
dracut -f -a "securityfs masterkey integrity"
restorecon -vFr /boot/initramfs-$(uname -r).img*

# set IMA/EVM policy at boot
grubby --update-kernel=/boot/vmlinuz-$(uname -r) \
    --args="ima_policy=appraise_tcb ima_appraise=fix evm=fix"

# reboot so policy changes are in effect
reboot

# install packages for TPM2 and reviewing file attributes
dnf -y install attr tpm2-tools

# create a primary storage key in the TPM
tpm2_createprimary --key-algorithm=rsa2048 --key-context=key.ctxt
tpm2_evictcontrol -c key.ctxt 0x81000001

# add a trusted kernel master key and evm-key to the uid 0 keyring
keyctl add trusted kmk-trusted "new 32 keyhandle=0x81000001" @u
keyctl add encrypted evm-key "new trusted:kmk-trusted 64" @u

# persist the keys using expected naming convention so they are reloaded at boot
mkdir -p /etc/keys
keyctl pipe $(keyctl search @u trusted kmk-trusted) > /etc/keys/kmk-trusted.blob
keyctl pipe $(keyctl search @u encrypted evm-key) > /etc/keys/evm-trusted.blob
chown -R root: /etc/keys
restorecon -vFr /etc/keys

# enable EVM
echo 1 > /sys/kernel/security/evm

# add IMA/EVM extended attribute labels to the whole filesystem
find / -fstype xfs -type f -uid 0 -exec head -n 1 '{}' >/dev/null \;

I then power off, re-enable secure boot, and reboot. This fails at the pivot from initramfs to disk as seen in the attached error.

Drilling into the kernel source code, missing-HMAC means that there is no security.evm extended attribute for the file /lib/systemd/systemd.

Comment 7 Coiby 2023-06-06 08:09:57 UTC
(In reply to Rich Lucente from comment #5)
> Created attachment 1945362 [details]
> boot error with IMA/EVM enabled

Hi Rich,

For the above error, it may be a bug (I think it's IMA's caching mechanism prevents fixing the EVM HMAC) . But if you create the trusted kernel master key and evm-key first and then let the integrity dracut module automatically load the keys and enable EVM for you, you won't have this boot error. Even "find / -fstype xfs -type f -uid 0 -exec head -n 1 '{}' >/dev/null \;" isn't needed if merely for a successful boot because all accessed files that are covered by ima_policy=appraise_tcb will be automatically fixed with "ima_appraise=fix evm=fix".

Comment 8 Coiby 2023-06-06 08:18:40 UTC
Hi David,

Do you have a plan to backport this integrity module? Btw, I've confirmed with the upstream kernel IMA maintainer Mimi Zohar that currently there is no plan to re-implement the features we need in a systemd module.

Comment 9 David Tardon 2023-06-07 12:28:40 UTC
(In reply to Coiby from comment #8)
> Do you have a plan to backport this integrity module?

Not "backport", but rather stop removing it. Yes, it is planned, but no, I won't be doing it myself.

Comment 10 Stefan Berger 2023-06-19 20:35:31 UTC
FYI: The following rpm spec extensions to the fedora 38 dracut.spec file has helped me a lot to start a fedora 38 system with IMA key loaded and an appraise policy enabled later on by systemd:

Command line used to rebuild the initramfs:

dracut --kver $(uname -r) --force --add integrity

[ For appraisal support I had to build a CA into the kernel. ]


From 09f2f8c0ba7978ccc9742aeec49024ca894006ee Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb.com>
Date: Mon, 19 Jun 2023 16:15:26 -0400
Subject: [PATCH] Enable EVM and IMA dracut scripts

Signed-off-by: Stefan Berger <stefanb.com>
---
 dracut.spec | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/dracut.spec b/dracut.spec
index efa3056..88cd183 100644
--- a/dracut.spec
+++ b/dracut.spec
@@ -182,6 +182,16 @@ This package provides a dracut module to build an initramfs, but store most file
 in a squashfs image, result in a smaller initramfs size and reduce runtime memory
 usage.

+%package integrity
+Summary: dracut module for IMA and EVM integrity support
+Requires: %{name} = %{version}-%{release}
+
+%description integrity
+This package provides dracut modules for support of IMA and EVM integrity. It
+includes support for mounting securityfs, loading a master key, loading of
+EVM and IMA keys, activating EVM, and loading an IMA policy contained in the
+initramfs.
+
 %prep
 %autosetup -n %{name}-%{version} -S git_am
 cp %{SOURCE1} .
@@ -213,13 +223,6 @@ rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/00dash
 # we do not support mksh in the initramfs
 rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/00mksh

-%if %{defined _unitdir}
-# with systemd IMA and selinux modules do not make sense
-rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/96securityfs
-rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/97masterkey
-rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/98integrity
-%endif
-
 %ifnarch s390 s390x
 # remove architecture specific modules
 rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/80cms
@@ -377,11 +380,6 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/
 %{dracutlibdir}/modules.d/95zfcp
 %{dracutlibdir}/modules.d/95zfcp_rules
 %endif
-%if %{undefined _unitdir}
-%{dracutlibdir}/modules.d/96securityfs
-%{dracutlibdir}/modules.d/97masterkey
-%{dracutlibdir}/modules.d/98integrity
-%endif
 %{dracutlibdir}/modules.d/97biosdevname
 %{dracutlibdir}/modules.d/98dracut-systemd
 %{dracutlibdir}/modules.d/98ecryptfs
@@ -447,6 +445,11 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/
 %{dracutlibdir}/modules.d/90dmsquash-live-ntfs
 %{dracutlibdir}/modules.d/90livenet

+%files integrity
+%{dracutlibdir}/modules.d/96securityfs
+%{dracutlibdir}/modules.d/97masterkey
+%{dracutlibdir}/modules.d/98integrity
+
 %files tools
 %if %{with doc}
 %doc %{_mandir}/man8/dracut-catimages.8*
--
2.41.0

Comment 12 Coiby 2023-08-01 13:31:23 UTC
(In reply to Stefan Berger from comment #10)
> FYI: The following rpm spec extensions to the fedora 38 dracut.spec file has
> helped me a lot to start a fedora 38 system with IMA key loaded and an
> appraise policy enabled later on by systemd:
> 
> Command line used to rebuild the initramfs:
> 
> dracut --kver $(uname -r) --force --add integrity
> 
> [ For appraisal support I had to build a CA into the kernel. ]
> 
> 
> From 09f2f8c0ba7978ccc9742aeec49024ca894006ee Mon Sep 17 00:00:00 2001
> From: Stefan Berger <stefanb.com>
> Date: Mon, 19 Jun 2023 16:15:26 -0400
> Subject: [PATCH] Enable EVM and IMA dracut scripts
> 
> Signed-off-by: Stefan Berger <stefanb.com>
> ---
>  dracut.spec | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/dracut.spec b/dracut.spec
> index efa3056..88cd183 100644
> --- a/dracut.spec
> +++ b/dracut.spec
> @@ -182,6 +182,16 @@ This package provides a dracut module to build an
> initramfs, but store most file
>  in a squashfs image, result in a smaller initramfs size and reduce runtime
> memory
>  usage.
> 
> +%package integrity
> +Summary: dracut module for IMA and EVM integrity support
> +Requires: %{name} = %{version}-%{release}
> +
> +%description integrity
> +This package provides dracut modules for support of IMA and EVM integrity.
> It
> +includes support for mounting securityfs, loading a master key, loading of
> +EVM and IMA keys, activating EVM, and loading an IMA policy contained in the
> +initramfs.
> +
>  %prep
>  %autosetup -n %{name}-%{version} -S git_am
>  cp %{SOURCE1} .
> @@ -213,13 +223,6 @@ rm -fr --
> $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/00dash
>  # we do not support mksh in the initramfs
>  rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/00mksh
> 
> -%if %{defined _unitdir}
> -# with systemd IMA and selinux modules do not make sense
> -rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/96securityfs
> -rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/97masterkey
> -rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/98integrity
> -%endif
> -
>  %ifnarch s390 s390x
>  # remove architecture specific modules
>  rm -fr -- $RPM_BUILD_ROOT/%{dracutlibdir}/modules.d/80cms
> @@ -377,11 +380,6 @@ echo 'dracut_rescue_image="yes"' >
> $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/
>  %{dracutlibdir}/modules.d/95zfcp
>  %{dracutlibdir}/modules.d/95zfcp_rules
>  %endif
> -%if %{undefined _unitdir}
> -%{dracutlibdir}/modules.d/96securityfs
> -%{dracutlibdir}/modules.d/97masterkey
> -%{dracutlibdir}/modules.d/98integrity
> -%endif
>  %{dracutlibdir}/modules.d/97biosdevname
>  %{dracutlibdir}/modules.d/98dracut-systemd
>  %{dracutlibdir}/modules.d/98ecryptfs
> @@ -447,6 +445,11 @@ echo 'dracut_rescue_image="yes"' >
> $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/
>  %{dracutlibdir}/modules.d/90dmsquash-live-ntfs
>  %{dracutlibdir}/modules.d/90livenet
> 
> +%files integrity
> +%{dracutlibdir}/modules.d/96securityfs
> +%{dracutlibdir}/modules.d/97masterkey
> +%{dracutlibdir}/modules.d/98integrity
> +
>  %files tools
>  %if %{with doc}
>  %doc %{_mandir}/man8/dracut-catimages.8*
> --
> 2.41.0

Hi Stefan,

I'm curious to ask what's the benefit of packaging the integrity module in a subpackage. integrity is not enabled by default and undo deleting the lines that remove the integrity module and its dependent package seems to be a simpler solution.

Comment 13 Stefan Berger 2023-08-01 15:14:41 UTC
(In reply to Coiby from comment #12)

> > 2.41.0
> 
> Hi Stefan,
> 
> I'm curious to ask what's the benefit of packaging the integrity module in a
> subpackage. integrity is not enabled by default and undo deleting the lines
> that remove the integrity module and its dependent package seems to be a
> simpler solution.

There's not necessarily any benefit. You may choose to package them into an existing package.

Comment 14 Stefan Berger 2023-08-01 20:17:49 UTC
FYI: When IMA appraisal kernel support is enabled then the IMA policy should probably be loaded by systemd since initramfs does not carry IMA signatures in extended attributes (xattrs). 

Per dracut code at  https://github.com/dracutdevs/dracut/blob/master/modules.d/98integrity/ima-policy-load.sh  the policy is loaded from /etc/sysconfig/ima-policy.  [ IMAPOLICY="/etc/sysconfig/ima-policy" ]
This would only work for an IMA policy that has measurement or audit rules.

Per systemd code here https://github.com/systemd/systemd/blob/main/src/core/ima-setup.c#L21  the IMA policy is loaded from /etc/ima/ima-policy [ #define IMA_POLICY_PATH "/etc/ima/ima-policy" ].
This could then be an IMA appraisal/measurement/audit policy.

Comment 15 Coiby 2023-08-01 22:43:58 UTC
(In reply to Stefan Berger from comment #13)
> (In reply to Coiby from comment #12)
> 
> > > 2.41.0
> > 
> > Hi Stefan,
> > 
> > I'm curious to ask what's the benefit of packaging the integrity module in a
> > subpackage. integrity is not enabled by default and undo deleting the lines
> > that remove the integrity module and its dependent package seems to be a
> > simpler solution.
> 
> There's not necessarily any benefit. You may choose to package them into an
> existing package.

I see, thanks for the clarification!

Comment 16 Peter Robinson 2023-08-02 12:40:33 UTC
I've filed this PR: https://gitlab.com/redhat/centos-stream/rpms/dracut/-/merge_requests/24

Comment 19 Pavel Valena 2023-08-15 17:18:03 UTC
Do you also need commit
https://github.com/dracutdevs/dracut/commit/90585c624af15ba0abb7f32b0c2afc2b122dd019

- that's the only difference from our dracut I could identify (apart from cosmetic code changes).

Comment 20 Coiby 2023-08-16 03:27:18 UTC
(In reply to Pavel Valena from comment #19)
> Do you also need commit
> https://github.com/dracutdevs/dracut/commit/
> 90585c624af15ba0abb7f32b0c2afc2b122dd019
> 
> - that's the only difference from our dracut I could identify (apart from
> cosmetic code changes).

Thanks for the reminder! I expect some users may want to use EVM to catch offline tampering with mutable files. So please backport this commit as well! Thanks!

Comment 21 Pavel Valena 2023-08-16 18:40:58 UTC
Inspected the code, backported one missing commit. Looks sane.