Add some IMA setup tools

Resolves: https://issues.redhat.com/browse/RHEL-33751
Conflict: Upstream has -libs subpackage

Upstream Status: https://src.fedoraproject.org/rpms/ima-evm-utils.git

commit 8980421a049c776e2b77e534793aafb925b3ad48
Author: Coiby Xu <coiby.xu@gmail.com>
Date:   Mon May 6 17:48:52 2024 +0800

    Add some IMA setup tools

    Some IMA setup tools are added to ease IMA setup which will do
    the following tasks,
       - add IMA signatures to installed packages files
       - load IMA keys and policy
       - enable the dracut integrity module to load IMA keys and policy
         automatically

    Two IMA polices as suggested by Stefan Berger are also provided which
    will be signed automatically with other package files.

    Thanks to Marko Myllynen for coming up with the idea to have a tool
    similar to fips-mode-setup. And thanks to Mimi Zohar and Stefan Berger
    for providing the feedback!

    Signed-off-by: Coiby Xu <coxu@redhat.com>

Signed-off-by: Coiby Xu <coxu@redhat.com>
This commit is contained in:
Coiby Xu 2024-06-08 03:11:20 +08:00
parent 881eecef9e
commit 6760dcea53
7 changed files with 273 additions and 1 deletions

1
dracut-98-integrity.conf Normal file
View File

@ -0,0 +1 @@
add_dracutmodules+=" integrity "

82
ima-add-sigs.sh Executable file
View File

@ -0,0 +1,82 @@
#!/bin/bash
#
# This script add IMA signatures to installed RPM package files
# Usage: add_ima_sigs.sh [[ALL|PACKAGE_NAME] IMA_CERT_PATH]
#
# By default, it will add IMA sigantures to all installed package files. Or you
# can provide a package name to only add IMA signature for files of specicifed
# package. If it detects >=20 packages (or 1 package if you specify a package
# name) missing signatures in the RPM database, it will reinstall the packages
# in order to get the IMA signatures.
#
# With the signing IMA cert path specified, it will also try to verify
# the added IMA signature.
if [[ -z "$1" || $1 == ALL ]]; then
package="--all"
else
package=$1
fi
ima_cert=$2
abort() {
echo "$1"
exit 1
}
# Add IMA signatures from RPM database
add_from_rpm_db() {
if ! command -v setfattr &>/dev/null; then
abort "Please install attr"
fi
# use "|" as deliminator since it won't be used in a filename or signature
while IFS="|" read -r path sig; do
# [[ -z "$sig" ]] somehow doesn't work for some files that don't have IMA
# signatures. This may be a issue of rpm
if [[ "$sig" != "0"* ]]; then
continue
fi
# Skip directory, soft links, non-existent files and vfat fs
if [[ -d "$path" || -L "$path" || ! -f "$path" || "$path" == "/boot/efi/EFI/"* ]]; then
continue
fi
if ! setfattr -n security.ima "$path" -v "0x$sig"; then
echo "Failed to add IMA sig for $path"
fi
[[ -e "$ima_cert" ]] || continue
# TODO
# don't verify the modified files like /etc?
if ! evmctl ima_verify -k "$ima_cert" "$path" &>/dev/null; then
echo "Failed to verify $path"
fi
done < <(rpm -q --queryformat "[%{FILENAMES}|%{FILESIGNATURES}\n]" "$package")
}
# Add IMA signatures by reinstalling all packages
add_by_reinstall() {
[[ $package == "--all" ]] && package='*'
dnf reinstall "$package" -yq >/dev/null
}
if [[ $package == "--all" ]]; then
reinstall_threshold=20
else
if ! rpm -q --quiet $package; then
dnf install "$package" -yq >/dev/null
exit 0
fi
reinstall_threshold=1
fi
unsigned_packages_in_rpm_db=$(rpm -q --queryformat "%{SIGPGP:pgpsig}\n" $package | grep "^(none)$" | wc -l)
if [[ $unsigned_packages_in_rpm_db -ge $reinstall_threshold ]]; then
add_by_reinstall
else
add_from_rpm_db
fi

View File

@ -14,6 +14,14 @@ License: GPLv2
Url: http://linux-ima.sourceforge.net/
Source0: https://github.com/mimizohar/ima-evm-utils/releases/download/v%{version}/%{name}-%{version}.tar.gz
# IMA setup tools
Source2: dracut-98-integrity.conf
Source3: ima-add-sigs.sh
Source4: ima-setup.sh
Source100: policy-01-appraise-exectuables-and-lib-signatures
Source101: policy-02-keylime-remote-attestation
Source200: policy_list
%if 0%{bootstrap}
# compat source and patches
Source10: ima-evm-utils-1.4.tar.gz
@ -29,6 +37,9 @@ BuildRequires: libxslt
BuildRequires: make
BuildRequires: openssl-devel
BuildRequires: tpm2-tss-devel
Requires: rpm-plugin-ima
Requires: keyutils
Requires: attr
%description
The Trusted Computing Group(TCG) run-time Integrity Measurement Architecture
@ -81,13 +92,32 @@ popd
%ldconfig_scriptlets
# IMA setup tools
install -D -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_datadir}/ima/dracut-98-integrity.conf
mkdir -p -m 755 $RPM_BUILD_ROOT%{_datadir}/ima/policies
while IFS= read -r policy_file
do
install -m 644 %{_sourcedir}/policy-"$policy_file" $RPM_BUILD_ROOT%{_datadir}/ima/policies/"$policy_file"
done < %{SOURCE200}
install -D %{SOURCE3} $RPM_BUILD_ROOT%{_bindir}/ima-add-sigs
install -D %{SOURCE4} $RPM_BUILD_ROOT%{_bindir}/ima-setup
%files
%license COPYING
%doc NEWS README AUTHORS
%{_bindir}/evmctl
%{_mandir}/man1/evmctl*
# IMA setup tools
%{_datadir}/ima/policies
%{_datadir}/ima/dracut-98-integrity.conf
%{_bindir}/ima-add-sigs
%{_bindir}/ima-setup
# if you need to bump the soname version, coordinate with dependent packages
%{_libdir}/libimaevm.so.4*
%{_mandir}/man1/evmctl*
%if 0%{bootstrap}
%{_libdir}/libimaevm.so.%{compat_soversion}
%{_libdir}/libimaevm.so.%{compat_soversion}.0.0

118
ima-setup.sh Executable file
View File

@ -0,0 +1,118 @@
#!/bin/bash
#
# This script helps set up IMA.
#
IMA_SYSTEMD_POLICY=/etc/ima/ima-policy
IMA_POLICY_SYSFS=/sys/kernel/security/ima/policy
usage() {
echo "Set up IMA."
cat <<EOF
usage: $0 --policy=IMA_POLICY_PATH
--policy
The path of IMA policy to be loaded. Sample polices are inside
/usr/share/ima/policies or you can use your own IMA policy
The path of IMA policy to be loaded. Sample polices are inside
/usr/share/ima/policies or you can use your own IMA policy
EOF
exit 1
}
for _opt in "$@"; do
case "$_opt" in
--policy=*)
ima_policy_path=${_opt#*=}
if [[ ! -e $ima_policy_path ]]; then
echo "$policy_file doesn't exist"
exit 1
fi
;;
*)
usage
;;
esac
done
if [[ $# -eq 0 ]]; then
usage
fi
# Add IMA signatures
if test -f /run/ostree-booted; then
echo "You are using OSTree, please enable IMA signatures as part of the OSTree creation process."
else
echo "Adding IMA signatures to installed package files"
if ! ima-add-sigs; then
echo "Failed to add IMA signatures, abort"
exit 1
fi
fi
load_ima_keys() {
local _key_loaded
if line=$(keyctl describe %keyring:.ima); then
_ima_id=${line%%:*}
else
echo "Failed to get ID of the .ima keyring"
exit 1
fi
for i in /etc/keys/ima/*; do
if [ ! -f "${i}" ]; then
echo "No IMA key exist"
exit 1
fi
if ! evmctl import "${i}" "${_ima_id}" &>/dev/null; then
echo "Failed to load IMA key ${i}"
else
_key_loaded=yes
fi
done
if [[ $_key_loaded != yes ]]; then
echo "No IMA key loaded"
exit 1
fi
}
load_ima_policy() {
local ima_policy_path
ima_policy_path=$1
if ! test -f "$ima_policy_path"; then
echo "$ima_policy_path doesn't exist"
return 1
fi
if ! echo "$ima_policy_path" >"$IMA_POLICY_SYSFS"; then
echo "$ima_policy_path can't be loaded"
return 1
fi
# Let systemd load the IMA policy which will load LSM rules first so IMA
# policy containing rules like "appraise obj_type=ifconfig_exec_t" can be
# loaded
[[ -e /etc/ima ]] || mkdir -p /etc/ima/
if ! cp --preserve=xattr "$ima_policy_path" "$IMA_SYSTEMD_POLICY"; then
echo "Failed to copy $ima_policy_path to $IMA_SYSTEMD_POLICY"
return 1
fi
}
echo "Loading IMA keys"
load_ima_keys
# Include the dracut integrity module to load the IMA keys and policy
# automatically when there is a system reboot
if ! lsinitrd --mod | grep -q integrity; then
cp --preserve=xattr /usr/share/ima/dracut-98-integrity.conf /etc/dracut.conf.d/98-integrity.conf
echo "Rebuilding the initramfs of kernel-$(uname -r) to include the dracut integrity module"
dracut -f
fi
if ! load_ima_policy "$ima_policy_path"; then
echo "Failed to load IMA policy $ima_policy_path!"
exit 1
fi

View File

@ -0,0 +1,2 @@
appraise func=MMAP_CHECK mask=MAY_EXEC appraise_type=imasig
appraise func=BPRM_CHECK appraise_type=imasig

View File

@ -0,0 +1,37 @@
# PROC_SUPER_MAGIC
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC
dont_measure fsmagic=0x01021994
# DEVPTS_SUPER_MAGIC
dont_measure fsmagic=0x1cd1
# BINFMTFS_MAGIC
dont_measure fsmagic=0x42494e4d
# SECURITYFS_MAGIC
dont_measure fsmagic=0x73636673
# SELINUX_MAGIC
dont_measure fsmagic=0xf97cff8c
# SMACK_MAGIC
dont_measure fsmagic=0x43415d53
# CGROUP_SUPER_MAGIC
dont_measure fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC
dont_measure fsmagic=0x63677270
# NSFS_MAGIC
dont_measure fsmagic=0x6e736673
# EFIVARFS_MAGIC
dont_measure fsmagic=0xde5e81e4
# OVERLAYFS_MAGIC
# when containers are used we almost always want to ignore them
dont_measure fsmagic=0x794c7630
# Measure and log keys loaded onto the .ima keyring
measure func=KEY_CHECK keyrings=.ima
# Measure and log executables
measure func=BPRM_CHECK
# Measure and log shared libraries
measure func=FILE_MMAP mask=MAY_EXEC

2
policy_list Normal file
View File

@ -0,0 +1,2 @@
01-appraise-exectuables-and-lib-signatures
02-keylime-remote-attestation