Integrity Measurement Architecture/Recipes
This article introduces Integrity Measurement Architecture recipes for the Linux kernel.
The two default policies included the in kernel, tcb and tcb_appraise are not very useful on a general-purpose machine, it is recommended to create custom rules.
The format of the rules is in the Linux kernel documentation is located in Documentation/ABI/testing/ima_policy. To obtain the magic numbers for the "fsmagic" condition see /usr/include/linux/magic.h or include/uapi/linux/magic.h in the kernel sources.
Built-in policies
The built-in policies are current as of Linux 4.19. Comments have been added to the policies to make it easier to understand.
tcb
# PROC_SUPER_MAGIC = 0x9fa0
dont_measure fsmagic=0x9fa0
# SYSFS_MAGIC = 0x62656572
dont_measure fsmagic=0x62656572
# DEBUGFS_MAGIC = 0x64626720
dont_measure fsmagic=0x64626720
# TMPFS_MAGIC = 0x01021994
dont_measure fsmagic=0x1021994
# DEVPTS_SUPER_MAGIC=0x1cd1
dont_measure fsmagic=0x1cd1
# BINFMTFS_MAGIC=0x42494e4d
dont_measure fsmagic=0x42494e4d
# SECURITYFS_MAGIC=0x73636673
dont_measure fsmagic=0x73636673
# SELINUX_MAGIC=0xf97cff8c
dont_measure fsmagic=0xf97cff8c
# SMACK_MAGIC=0x43415d53
dont_measure fsmagic=0x43415d53
# CGROUP_SUPER_MAGIC=0x27e0eb
dont_measure fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC=0x63677270
dont_measure fsmagic=0x63677270
# NSFS_MAGIC=0x6e736673
dont_measure fsmagic=0x6e736673
measure func=MMAP_CHECK mask=MAY_EXEC
measure func=BPRM_CHECK mask=MAY_EXEC
measure func=FILE_CHECK mask=MAY_READ uid=0
measure func=MODULE_CHECK
measure func=FIRMWARE_CHECK
The policy excludes some "pseduo" filesystem from measurement, and measures every file mapped for execution, directly executes, read by root, all modules loaded and all firmware loaded
tcb_appraise
# PROC_SUPER_MAGIC = 0x9fa0
dont_appraise fsmagic=0x9fa0
# SYSFS_MAGIC = 0x62656572
dont_appraise fsmagic=0x62656572
# DEBUGFS_MAGIC = 0x64626720
dont_appraise fsmagic=0x64626720
# TMPFS_MAGIC = 0x01021994
dont_appraise fsmagic=0x1021994
# RAMFS_MAGIC
dont_appraise fsmagic=0x858458f6
# DEVPTS_SUPER_MAGIC=0x1cd1
dont_appraise fsmagic=0x1cd1
# BINFMTFS_MAGIC=0x42494e4d
dont_appraise fsmagic=0x42494e4d
# SECURITYFS_MAGIC=0x73636673
dont_appraise fsmagic=0x73636673
# SELINUX_MAGIC=0xf97cff8c
dont_appraise fsmagic=0xf97cff8c
# SMACK_MAGIC=0x43415d53
dont_appraise fsmagic=0x43415d53
# NSFS_MAGIC=0x6e736673
dont_appraise fsmagic=0x6e736673
# CGROUP_SUPER_MAGIC=0x27e0eb
dont_appraise fsmagic=0x27e0eb
# CGROUP2_SUPER_MAGIC=0x63677270
dont_appraise fsmagic=0x63677270
appraise fowner=0
As above, some "pseduo" filesystem are excluded, and anything owned by root is appraised
secure_boot
appraise func=MODULE_CHECK appraise_type=imasig
appraise func=FIRMWARE_CHECK appraise_type=imasig
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
appraise func=POLICY_CHECK appraise_type=imasig
This policy requires all modules, firmware, kexec kernels and IMA policies to have an IMA signature.
Kernel options affecting IMA policies
The kernel has a few option append to add IMA policies, if IMA build time configured policy rules or Enable multiple writes to the IMA policy is selected
# IMA build time configured policy rules
CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS=n
CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=n
CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS=n
CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS=n
# Enable multiple writes to the IMA policy
CONFIG_IMA_WRITE_POLICY=n
If any of these are set to "Y" they already all default and custom policies by adding the following rules:
# CONFIG_IMA_APPRAISE_REQUIRE_FIRMWARE_SIGS
appraise func=FIRMWARE_CHECK appraise_type=imasig
# CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
# CONFIG_IMA_APPRAISE_REQUIRE_MODULE_SIGS
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
# CONFIG_IMA_APPRAISE_REQUIRE_POLICY_SIGS
# CONFIG_IMA_WRITE_POLICY
appraise func=POLICY_CHECK appraise_type=imasig
Custom policies
Excluding log files
Measurement and appraisal of log files is not useful and generate kernel spam every time one is opened. It would be useful to exclude known log files, and with the help of SELinux, it is possible to so. List the log file types SELinux knows about:
user $
seinfo -alogfile -x
Type Attributes: 1 attribute logfile; auth_cache_t cron_log_t dirmngr_log_t dracut_var_log_t faillog_t fsadm_log_t getty_log_t initrc_var_log_t lastlog_t nscd_log_t portage_log_t rsync_log_t user_cron_spool_log_t var_log_t wtmp_t
With this in hand, known log files can be excluded from appraisal and measurement by including this snippet before any "appraise" or "measure" rules
dont_measure obj_type=auth_cache_t
dont_appraise obj_type=auth_cache_t
dont_measure obj_type=cron_log_t
dont_appraise obj_type=cron_log_t
dont_measure obj_type=dirmngr_log_t
dont_appraise obj_type=dirmngr_log_t
dont_measure obj_type=dracut_var_log_t
dont_appraise obj_type=dracut_var_log_t
dont_measure obj_type=faillog_t
dont_appraise obj_type=faillog_t
dont_measure obj_type=fsadm_log_t
dont_appraise obj_type=fsadm_log_t
dont_measure obj_type=getty_log_t
dont_appraise obj_type=getty_log_t
dont_measure obj_type=initrc_var_log_t
dont_appraise obj_type=initrc_var_log_t
dont_measure obj_type=lastlog_t
dont_appraise obj_type=lastlog_t
dont_measure obj_type=nscd_log_t
dont_appraise obj_type=nscd_log_t
dont_measure obj_type=portage_log_t
dont_appraise obj_type=portage_log_t
dont_measure obj_type=rsync_log_t
dont_appraise obj_type=rsync_log_t
dont_measure obj_type=user_cron_spool_log_t
dont_appraise obj_type=user_cron_spool_log_t
dont_measure obj_type=var_log_t
dont_appraise obj_type=var_log_t
dont_measure obj_type=wtmp_t
dont_appraise obj_type=wtmp_t