From: Stefan Berger <stef...@us.ibm.com> Add a script for loading certificates used by the Linux Integrity Measurement Architecture (IMA) for verifying file signatures. The script will first look for the availability of the .ima keyring and load all keys it finds on it. If the .ima keyring is not available, it will try using _ima. The difference between .ima and _ima is that certificates loaded onto the .ima keyring must have been signed by a CA known to the kernel, whereas _ima accepts plain public keys.
Add a script for loading the IMA policy. A configuration file can be provided in /etc/default/ima where the location of the policy can be set. The default location is /etc/default/ima-policy. Signed-off-by: Stefan Berger <stef...@linux.vnet.ibm.com> --- hooks/ima | 22 +++++++++++ scripts/init-top/ima-keys-load | 80 ++++++++++++++++++++++++++++++++++++++++ scripts/init-top/ima-policy-load | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100755 hooks/ima create mode 100755 scripts/init-top/ima-keys-load create mode 100755 scripts/init-top/ima-policy-load diff --git a/hooks/ima b/hooks/ima new file mode 100755 index 0000000..3284707 --- /dev/null +++ b/hooks/ima @@ -0,0 +1,22 @@ +#!/bin/sh + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions +copy_exec /usr/bin/evmctl +copy_exec /bin/findmnt +copy_exec /bin/keyctl +copy_exec /bin/mount +copy_exec /bin/ls diff --git a/scripts/init-top/ima-keys-load b/scripts/init-top/ima-keys-load new file mode 100755 index 0000000..e007d57 --- /dev/null +++ b/scripts/init-top/ima-keys-load @@ -0,0 +1,80 @@ +#!/bin/sh + +# (c) Copyright IBM Corporation 2015, 2016, 2017 +# +# Mimi Zohar <zo...@linux.vnet.ibm.com> +# Stefan Berger <stef...@linux.vnet.ibm.com> +# +# This file has been derived from Dracut's 98integrity/ima-keys-load.sh +# + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +# get pre-requisites +prereqs) + prereqs + exit 0 + ;; +esac + +. /scripts/functions + +SECURITYFSDIR=`findmnt -t securityfs -n -o TARGET` +if [ ! $SECURITYFSDIR ]; then + SECURITYFSDIR="/sys/kernel/security" + mount -t securityfs -o nosuid,noexec,nodev securityfs ${SECURITYFSDIR} >/dev/null 2>&1 +fi + +NEWROOT="${rootmnt}" +IMASECDIR="${SECURITYFSDIR}/ima" +IMACONFIG="${NEWROOT}/etc/default/ima" + +load_x509_keys() +{ + KEYRING_ID=$1 + + # override the default configuration + if [ -f "${IMACONFIG}" ]; then + . ${IMACONFIG} + fi + + if [ -z "${IMAKEYDIR}" ]; then + IMAKEYSDIR="/etc/keys/ima" + fi + + PUBKEY_LIST=`ls ${NEWROOT}${IMAKEYSDIR}/*` + for PUBKEY in ${PUBKEY_LIST}; do + X509ID=$(evmctl import ${PUBKEY} ${KEYRING_ID} 2>/dev/null) + [ $? -ne 0 ] && _log_msg "integrity: IMA x509 cert not loaded on keyring: ${PUBKEY}\n" + done + + [ "$quiet" != "y" ] && keyctl show ${KEYRING_ID} + + return 0 +} + +# check kernel support for IMA +if [ ! -e "${IMASECDIR}" ]; then + [ "$quiet" != "y" ] && _log_msg "integrity: IMA kernel support is disabled\n" + return 0 +fi + +# get the .ima keyring id +line="$(sed -n 's/\([^ ]\+\).*keyring\s\+\.ima:.*/\1/p' /proc/keys)" +if [ -n "$line" ]; then + _ima_id=$(printf "%d" "0x$line") +else + _ima_id=`keyctl search @u keyring _ima` + if [ -z "${_ima_id}" ]; then + _ima_id=`keyctl newring _ima @u` + fi +fi + +# load the IMA public key(s) +load_x509_keys ${_ima_id} diff --git a/scripts/init-top/ima-policy-load b/scripts/init-top/ima-policy-load new file mode 100755 index 0000000..4965db4 --- /dev/null +++ b/scripts/init-top/ima-policy-load @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Licensed under the GPLv2 +# +# Copyright (C) 2010 Politecnico di Torino, Italy +# TORSEC group -- http://security.polito.it +# Roberto Sassu <roberto.sa...@polito.it> +# +# (c) Copyright IBM Corporation 2016, 2017 +# +# Stefan Berger <stef...@linux.vnet.ibm.com> +# +# This file has been derived from Dracut's 98integrity/ima-policy-load.sh +# + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +# get pre-requisites +prereqs) + prereqs + exit 0 + ;; +esac + +. /scripts/functions + +SECURITYFSDIR=`findmnt -t securityfs -n -o TARGET` +if [ ! $SECURITYFSDIR ]; then + SECURITYFSDIR="/sys/kernel/security" + mount -t securityfs -o nosuid,noexec,nodev securityfs ${SECURITYFSDIR} >/dev/null 2>&1 +fi + +NEWROOT="${rootmnt}" +IMASECDIR="${SECURITYFSDIR}/ima" +IMACONFIG="${NEWROOT}/etc/default/ima" +IMAPOLICY="/etc/default/ima-policy" + +load_ima_policy() +{ + # check kernel support for IMA + if [ ! -e "${IMASECDIR}" ]; then + [ "$quiet" != "y" ] && _log_msg "integrity: IMA kernel support is disabled\n" + return 0 + fi + + # override the default configuration + [ -f "${IMACONFIG}" ] && \ + . ${IMACONFIG} + + # set the IMA policy path name + IMAPOLICYPATH="${NEWROOT}${IMAPOLICY}" + + # check the existence of the IMA policy file + if [ -f "${IMAPOLICYPATH}" ]; then + echo -n "${IMAPOLICYPATH}" > ${IMASECDIR}/policy || \ + cat "${IMAPOLICYPATH}" > ${IMASECDIR}/policy + [ $? -ne 0 ] && _log_msg "integrity: Failed to load IMA policy\n" \ + || _log_msg "integrity: Loaded IMA policy\n" + fi + + return 0 +} + +load_ima_policy -- 2.8.3