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:
parent
881eecef9e
commit
6760dcea53
1
dracut-98-integrity.conf
Normal file
1
dracut-98-integrity.conf
Normal file
@ -0,0 +1 @@
|
||||
add_dracutmodules+=" integrity "
|
||||
82
ima-add-sigs.sh
Executable file
82
ima-add-sigs.sh
Executable 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
|
||||
@ -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
118
ima-setup.sh
Executable 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
|
||||
2
policy-01-appraise-exectuables-and-lib-signatures
Normal file
2
policy-01-appraise-exectuables-and-lib-signatures
Normal file
@ -0,0 +1,2 @@
|
||||
appraise func=MMAP_CHECK mask=MAY_EXEC appraise_type=imasig
|
||||
appraise func=BPRM_CHECK appraise_type=imasig
|
||||
37
policy-02-keylime-remote-attestation
Normal file
37
policy-02-keylime-remote-attestation
Normal 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
2
policy_list
Normal file
@ -0,0 +1,2 @@
|
||||
01-appraise-exectuables-and-lib-signatures
|
||||
02-keylime-remote-attestation
|
||||
Loading…
Reference in New Issue
Block a user