IMA Namespacing design considerations
Our goals are to enable IMA-measurement, IMA-appraisal, and IMA-audit inside a container using Linux namespaces. The intention is to introduce an IMA namespace.
IMA-measurement is about logging files that were read or executables that were started on a machine. Current IMA supports for example measuring root's activities in the TCB, such as which programs were started by root. Which files are measured can be configured using an IMA policy.
IMA-appraisal is about only allowing files to be accessed that have been properly signed. This allows to lock down a machine if only signed files are allowed to be read or executed. Which files are appraised can be configured using an IMA policy. File signatures are found in the security.ima extended attribute. The keys for verifying the signature are found in IMA specific keyrings .ima or _ima.
IMA-audit is about reporting accesses to files and generating audit records of file hash measurements. Which file activity is audited can be configured using an IMA policy.
IMA Namespacing Considerations
When namespacing IMA we certainly want to prevent the abuse of namespaces by users doing things that go undetected. A primary concern are activities of root in the TCB. Since root has all the rights on the system he could try to abuse his power by spawning new IMA namespaces and do things there that affect the TCB but now would go undetected due to weaknesses in the IMA namespacing implementation. The following enumeration of IMA namespacing design points is supposed to guide the implementation and prevent such problems:
Support for IMA in namespaces should enable the following:
- IMA policy for container (similar to the host): - there should be an initial default policy for every IMA namespace that measures activities inside the container - the policy can be overwritten once with a user-defined policy that may activate appraisal - CAP_SYS_ADMIN is currently gating the setting of the IMA policy; - setting the policy should be possibly without the almighty CAP_SYS_ADMIN - we may want to gate this with a new capability CAP_INTEGRITY_ADMIN that allows a user to set the IMA policy during container runtime - IMA policy extensions due to namespacing: - an IMA policy should allow rules that define whether activities in (all) child namespaces is to be measured (huge logs on the host) and audited or 'not'; a use case for not measuring may be found in cloud environments where containers come and go and the log on the host could possibly eat up a lot of memory - to prevent (host) root from spawning new IMA namespaces and doing things undetected in the TCB, all activities of root must be measured and audited in all IMA namespaces independent of whether the policy enables logging or auditing in child namespaces - IMA-measurement: - to prevent (host) root from spawning new IMA namespaces and doing things undetected in the TCB, all activities of root must be measured and audited in all IMA namespaces independent of whether the policy enables logging or auditing in child namespaces - activities of all other users, including container-root user, would only be subject to the policy set in the IMA namespace - IMA-audit: - to prevent (host) root from spawning new IMA namespaces and doing things undetected in the TCB, all activities of root must be measured and audited in all IMA namespaces independent of whether the policy enables logging or auditing in child namespaces - activities of all other users, including container-root user, would only be subject to the policy set in the IMA namespace - IMA-appraisal and keys: - each IMA namespace should have its own keyring so that each container can have its files signed with different keys - the keys (certificates) for verifying signatures may be found inside containers - it should be possible to enforce that only certified keys are loaded onto a keyring, similar to .ima on the host - the CA public key used for verifying that public keys (certificates) used for verifying signatures may be found inside the container or could be known to the container management stack - IMA-appraisal and namespacing: - If IMA-appraisal is active on the host (per policy rules on the host), what is supposed to happen when (host) root executes files in a (nested) IMA namespace where an empty IMA policy has been set? We would measure and audit root's activities as described above. What about appraising? Would we traverse all the IMA namespaces back to the init_ima_ns and evaluate signatures against the appraisal policy set there and assume we would always find the keys in the init_user_ns? - TPM and measurements: - The IMA namespace that holds the logs should be configurable to extend PCRs; since the single TPM of the host cannot be shared by containers, each IMA namespace would have to be associated with its own TPM instance (vTPM); measurement in the initial IMA namespace are extended into the hardware TPM as done already - Extended attribute security.ima: - A container should be able to set the security.ima extended attribute - this should be possibly without the almighty CAP_SYS_ADMIN; - we may want to gate this with a new capability CAP_SECURITY_XATTR_ADMIN that allows setting security extended attributes inside a container, possibly only during container build-time - Extended attribute security.ima and bind mounting - It may be necessary that different namespaces be able to sign the same bind-mounted file with different keys (I am thinking of bind-mounted files that the container management stack modifies and that may need to be signed for the container to be able to access them.) - Extended attributes, such as seucrity.ima) may need to be virtualizeable (security.ima vs. security.ima@uid=1000 etc.)
A concrete 'ab-use' case that we have to to avoid is the following:
A user creates a privileged container that shares the host's mount namespace: it would be unexpected if there was an IMA policy active on the host that enforces file appraisal but in this case the IMA policy is not enforced since a (hypothetical) IMA namespace of the host was not joined because only the mount namespace of the host was joined. Now we have two choices here: We tie the mount and IMA namespaces together via single clone flag (as proposed in RFC patches) and joining the mount namespace automatically joins the associated IMA namespace (single setns()). Or we make user space responsible for it and say if a mount namespace is joined, find the associated IMA namespace and join both of them (2 setns() calls). Well, I think the former would be preferred over the latter.
So either we tie the IMA namespace to some other existing namespace, preferably mount namespace, or we have it be independently created (new clone flag or by writing into a sysfs/securityfs file).
MNT and IMA Namespaces tied together
Let's assume we tie MNT and IMA namespaces together, then there are other scenarios with switching through the other namespaces (UTS, PID, IPC, NET, USER, CGROUP). I am not sure what is supposed to happen other than logging the activity active in the current IMA namespace:
What should happen with IMA logging, appraisal, and auditing if we setns() through all available - PID namespaces and send signals: log, appraise, and audit file activity following IMA policy - IPC namespaces and send messages via IPC: same as for PID - UTS namespaces and setting hostname: same as for PID - NET namespaces and sending network traffic: same as for PID? - CGROUP namespaces and configuring cgroups: same as for PID? - USER: should now the keys of this USER namespace be active or the keys of the original user namespace used during the clone()? other than that, same as for PID?
Independent IMA Namespace
If we create an IMA namespace independently from any other mount namespace, what are we to gain from this or loose? The above ab-use case shows some problem associated with it. Do we have a solution for the item "IMA-appraisal and namespacing" above? In the worst case, would it matter if root spawned a new IMA namespace, set a NULL policy, and only have its activities measured and audited but not appraised?