Chapter 29. Enhancing security with the kernel integrity subsystem
Chapter 29. Enhancing security with the kernel integrity subsystem You can improve the protection of your system by using components of the kernel integrity subsystem. Learn more about the relevant components and their configuration. 29.1. The kernel integrity subsystem The integrity subsystem is the kernel component that maintains the overall integrity of system data. This subsystem helps in maintaining the system in the same state from the time it was built. Using this subsystem, you can protect executable files, libraries, and configuration files. The kernel integrity subsystem consists of two major components: Integrity Measurement Architecture (IMA) IMA measures file content whenever it is executed or accessed by cryptographically hashing or signing with cryptographic keys. The keys are stored in the kernel keyring subsystem. IMA places the measured values within the kernel's memory space. This prevents users of the system from modifying the measured values. IMA allows local and remote parties to verify the measured values. IMA provides local validation of the current content of files against the values previously stored in the measurement list within the kernel memory. This extension forbids performing any operation on a specific file in case the current and the measures do not match. Extended Verification Module (EVM) EVM protects extended attributes of files (also known as xattr ) related to system security, such as IMA measurements and SELinux attributes. EVM cryptographically hashes their corresponding values or signs them with cryptographic keys. The keys are stored in the kernel keyring subsystem. The kernel integrity subsystem can use the Trusted Platform Module (TPM) to further harden system security. A TPM is a hardware, firmware, or virtual component with integrated cryptographic keys that are built according to the TPM specification by the Trusted Computing Group (TCG) for important cryptographic functions. By providing cryptographic functions from a protected and tamper-proof area of the hardware chip, TPMs are protected from software-based attacks. TPMs provide the following features: Random-number generator Generator and secure storage for cryptographic keys Hashing generator Remote attestation Additional resources Security hardening Basic and advanced configuration of Security-Enhanced Linux (SELinux) 29.2. Trusted and encrypted keys Trusted keys and encrypted keys are an important part of enhancing system security. Trusted and encrypted keys are variable-length symmetric keys generated by the kernel that use the kernel keyring service. You can verify the integrity of the keys, for example, to allow the extended verification module (EVM) to verify and confirm the integrity of a running system. User-level programs can only access the keys in the form of encrypted blobs . Trusted keys Trusted keys need the Trusted Platform Module (TPM) chip, which is used to both create and encrypt (seal) the keys. Each TPM has a master wrapping key, called the storage root key, which is stored within the TPM itself. Note Red Hat Enterprise Linux 8 supports both TPM 1.2 and TPM 2.0. For more information, see the Red Hat Knowledgebase solution Is Trusted Platform Module (TPM) supported by Red Hat? . You can verify the status of TPM 2.0 chip: You can also enable a TPM 2.0 chip and manage the TPM 2.0 device through settings in the machine firmware. In addition to that, you can seal the trusted keys with a specific set of the TPM's platform configuration register (PCR) values. PCR contains a set of integrity-management values that reflect the firmware, boot loader, and operating system. PCR-sealed keys can only be decrypted by the TPM on the system where they were encrypted. However, when you load a PCR-sealed trusted key to a keyring, its associated PCR values are verified. After verification, you can update the key with new or future PCR values, for example, to support booting a new kernel. Also, you can save a single key as multiple blobs, each with a different PCR value. Encrypted keys Encrypted keys do not require a TPM, because they use the kernel Advanced Encryption Standard (AES), which makes them faster than trusted keys. Encrypted keys are created using kernel-generated random numbers and encrypted by a master key when they are exported into user-space blobs. The master key is either a trusted key or a user key. If the master key is not trusted, the security of the encrypted key depends on the user key that was used to encrypt it. 29.3. Working with trusted keys You can improve system security by using the keyctl utility to create, export, load and update trusted keys. Prerequisites For the 64-bit ARM architecture and IBM Z, the trusted kernel module is loaded. For more information about how to load kernel modules, see Loading kernel modules at system runtime . Trusted Platform Module (TPM) is enabled and active. See The kernel integrity subsystem and Trusted and encrypted keys . Note Red Hat Enterprise Linux 8 supports both TPM 1.2 and TPM 2.0. If you use TPM 1.2, skip step 1. Procedure Create a 2048-bit RSA key with an SHA-256 primary storage key with a persistent handle of, for example, 81000001 , by using one of the following utilities: By using the tss2 package: By using the tpm2-tools package: Create a trusted key: By using a TPM 2.0 with the syntax of keyctl add trusted <NAME> "new <KEY_LENGTH> keyhandle= <PERSISTENT-HANDLE> [options]" <KEYRING> . In this example, the persistent handle is 81000001 . The command creates a trusted key called kmk with the length of 32 bytes (256 bits) and places it in the user keyring ( @u ). The keys may have a length of 32 to 128 bytes (256 to 1024 bits). By using a TPM 1.2 with the syntax of keyctl add trusted <NAME> "new <KEY_LENGTH>" <KEYRING> : List the current structure of the kernel keyrings: Export the key to a user-space blob by using the serial number of the trusted key: The command uses the pipe subcommand and the serial number of kmk . Load the trusted key from the user-space blob: Create secure encrypted keys that use the TPM-sealed trusted key ( kmk ). Follow this syntax: keyctl add encrypted <NAME> "new [FORMAT] <KEY_TYPE>:<PRIMARY_KEY_NAME> <KEY_LENGTH>" <KEYRING> : Additional resources the keyctl(1) manual page 29.4. Working with encrypted keys You can improve system security on systems where a Trusted Platform Module (TPM) is not available by managing encrypted keys. Encrypted keys, unless sealed by a trusted primary key, inherit the security level of the user primary key (random-number key) used for encryption. Therefore, it is highly recommended to load the primary user key securely, ideally early in the boot process. Prerequisites For the 64-bit ARM architecture and IBM Z, the encrypted-keys kernel module is loaded: For more information about how to load kernel modules, see Loading kernel modules at system runtime . Procedure Generate a user key by using a random sequence of numbers: The command generates a user key called kmk-user which acts as a primary key and is used to seal the actual encrypted keys. Generate an encrypted key using the primary key from the step: Verification List all keys in the specified user keyring: Additional resources The keyctl(1) manual page 29.5. Enabling IMA and EVM You can enable and configure Integrity measurement architecture (IMA) and extended verification module (EVM) to improve the security of the operating system. Important Always enable EVM together with IMA. Although you can enable EVM alone, EVM appraisal is only triggered by an IMA appraisal rule. Therefore, EVM does not protect file metadata such as SELinux attributes. If file metadata is tampered with offline, EVM can only prevent file metadata changes. It does not prevent file access, such as executing the file. Prerequisites Secure Boot is temporarily disabled. Note When Secure Boot is enabled, the ima_appraise=fix kernel command-line parameter does not work. The securityfs file system is mounted on the /sys/kernel/security/ directory and the /sys/kernel/security/integrity/ima/ directory exists. You can verify where securityfs is mounted by using the mount command: The systemd service manager is patched to support IMA and EVM on boot time. Verify by using the following command: For example: Procedure Enable IMA and EVM in the fix mode for the current boot entry and allow users to gather and update the IMA measurements by adding the following kernel command-line parameters: The command enables IMA and EVM in the fix mode for the current boot entry to gather and update the IMA measurements. The ima_policy=appraise_tcb kernel command-line parameter ensures that the kernel uses the default Trusted Computing Base (TCB) measurement policy and the appraisal step. The appraisal step forbids access to files whose prior and current measures do not match. Reboot to make the changes come into effect. Optional: Verify the parameters added to the kernel command line: Create a kernel master key to protect the EVM key: The kmk is kept entirely in the kernel space memory. The 32-byte long value of the kmk is generated from random bytes from the /dev/urandom file and placed in the user ( @u ) keyring. The key serial number is on the first line of the output. Create an encrypted EVM key based on the kmk : The command uses the kmk to generate and encrypt a 64-byte long user key (named evm-key ) and places it in the user ( @u ) keyring. The key serial number is on the first line of the output. Important It is necessary to name the user key as evm-key because that is the name the EVM subsystem is expecting and is working with. Create a directory for exported keys. Search for the kmk and export its unencrypted value into the new directory. Search for the evm-key and export its encrypted value into the new directory. The evm-key has been encrypted by the kernel master key earlier. Optional: View the newly created keys: Optional: If the keys are removed from the keyring, for example after system reboot, you can import the already exported kmk and evm-key instead of creating new ones. Import the kmk . Import the evm-key . Activate EVM. Relabel the whole system. Warning Enabling IMA and EVM without relabeling the system might make the majority of the files on the system inaccessible. Verification Verify that EVM has been initialized: 29.6. Collecting file hashes with integrity measurement architecture In the measurement phase, you can create file hashes and store them as extended attributes ( xattrs ) of those files. With the file hashes, you can generate either an RSA-based digital signature or a Hash-based Message Authentication Code (HMAC-SHA1) and prevent offline tampering attacks on the extended attributes. Prerequisites IMA and EVM are enabled. For more information, see Enabling integrity measurement architecture and extended verification module . A valid trusted key or encrypted key is stored in the kernel keyring. The ima-evm-utils , attr , and keyutils packages are installed. Procedure Create a test file: IMA and EVM ensure that the test_file example file has assigned hash values that are stored as its extended attributes. Inspect the file's extended attributes: The example output shows extended attributes with the IMA and EVM hash values and SELinux context. EVM adds a security.evm extended attribute related to the other attributes. At this point, you can use the evmctl utility on security.evm to generate either an RSA-based digital signature or a Hash-based Message Authentication Code (HMAC-SHA1). Additional resources Security hardening
cat /sys/class/tpm/tpm0/tpm_version_major 2 modprobe trusted TPM_DEVICE=/dev/tpm0 tsscreateprimary -hi o -st Handle 80000000 TPM_DEVICE=/dev/tpm0 tssevictcontrol -hi o -ho 80000000 -hp 81000001 tpm2_createprimary --key-algorithm=rsa2048 --key-context=key.ctxt name-alg: value: sha256 raw: 0xb ... sym-keybits: 128 rsa: xxxxxx... tpm2_evictcontrol -c key.ctxt 0x81000001 persistentHandle: 0x81000001 action: persisted keyctl add trusted kmk "new 32 keyhandle=0x81000001" @u 642500861 keyctl add trusted kmk "new 32" @u keyctl show Session Keyring -3 --alswrv 500 500 keyring: ses 97833714 --alswrv 500 -1 \ keyring: uid.1000 642500861 --alswrv 500 500 \ trusted: kmk keyctl pipe 642500861 > kmk.blob keyctl add trusted kmk "load `cat kmk.blob`" @u 268728824 keyctl add encrypted encr-key "new trusted:kmk 32" @u 159771175 modprobe encrypted-keys keyctl add user kmk-user "USD(dd if=/dev/urandom bs=1 count=32 2>/dev/null)" @u 427069434 keyctl add encrypted encr-key "new user:kmk-user 32" @u 1012412758 keyctl list @u 2 keys in keyring: 427069434: --alswrv 1000 1000 user: kmk-user 1012412758: --alswrv 1000 1000 encrypted: encr-key mount securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime) grep < options > pattern < files > dmesg | grep -i -e EVM -e IMA -w [ 0.598533] ima: No TPM chip found, activating TPM-bypass! [ 0.599435] ima: Allocated hash algorithm: sha256 [ 0.600266] ima: No architecture policies found [ 0.600813] evm: Initialising EVM extended attributes: [ 0.601581] evm: security.selinux [ 0.601963] evm: security.ima [ 0.602353] evm: security.capability [ 0.602713] evm: HMAC attrs: 0x1 [ 1.455657] systemd[1]: systemd 239 (239-74.el8_8) running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy) [ 2.532639] systemd[1]: systemd 239 (239-74.el8_8) running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=legacy) grubby --update-kernel=/boot/vmlinuz-USD(uname -r) --args="ima_policy=appraise_tcb ima_appraise=fix evm=fix" cat /proc/cmdline BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-167.el8.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet ima_policy=appraise_tcb ima_appraise=fix evm=fix keyctl add user kmk "USD(dd if=/dev/urandom bs=1 count=32 2> /dev/null)" @u 748544121 keyctl add encrypted evm-key "new user:kmk 64" @u 641780271 mkdir -p /etc/keys/ keyctl pipe USD(keyctl search @u user kmk) > /etc/keys/kmk keyctl pipe USD(keyctl search @u encrypted evm-key) > /etc/keys/evm-key keyctl show Session Keyring 974575405 --alswrv 0 0 keyring: ses 299489774 --alswrv 0 65534 \ keyring: uid.0 748544121 --alswrv 0 0 \ user: kmk 641780271 --alswrv 0 0 \_ encrypted: evm-key ls -l /etc/keys/ total 8 -rw-r--r--. 1 root root 246 Jun 24 12:44 evm-key -rw-r--r--. 1 root root 32 Jun 24 12:43 kmk keyctl add user kmk "USD(cat /etc/keys/kmk)" @u 451342217 keyctl add encrypted evm-key "load USD(cat /etc/keys/evm-key)" @u 924537557 echo 1 > /sys/kernel/security/evm find / -fstype xfs -type f -uid 0 -exec head -n 1 '{}' >/dev/null \; dmesg | tail -1 [... ] evm: key initialized echo < Test_text > > test_file getfattr -m . -d test_file file: test_file security.evm=0sAnDIy4VPA0HArpPO/EqiutnNyBql security.ima=0sAQOEDeuUnWzwwKYk+n66h/vby3eD