redhat:base-redhat:selinux-redhat

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
redhat:base-redhat:selinux-redhat [2018/05/08 11:13] – [Role-Based Access Control (RBAC)] michaelredhat:base-redhat:selinux-redhat [2018/05/08 11:22] (current) – [Multi-Category Security (MCS)] michael
Line 193: Line 193:
 <WRAP center box 100%> <WRAP center box 100%>
 <code> <code>
-sesearch -ACS -t ssh_home_t -c file -p read+sesearch -ACS -t ssh_home_t -c file -p read
 </code> </code>
  
Line 244: Line 244:
 </code> </code>
 ====  Multi-Category Security (MCS) ==== ====  Multi-Category Security (MCS) ====
 +
 +Multi-Category Security provides a way to associate a set or range of **compartments** with SELinux contexts. The targeted policy model implements compartmentalization of types associated with  mcs_constrained_type. To understand how this works, it's required to know how to inspect the MLS part of security contexts. This is the part after the user:role:type section, and includes a range, which indicates a low and high security level.
 +
 +<sxh plain; gutter: false;>
 +system_u:system_r:httpd_t:s0                  s0:c0.c5
 +                          ▼                     ▼
 +                  Low security level,    High security level, also
 +                  associated with no     associated with compartments
 +                  compartments.          c0, c1, c2, c3, c4 and c5.
 +</sxh>
 +
 +One thing that is noticeable above is the lack of compartments on the low security level, as well as both security levels being the same. The first point is an implementation detail of the MCS model in the targeted policy. When an access vector is computed for a process that is associated with mcs_constrained_type, only the MCS compartments of the high level are compared. The second point is due to the fact that MLS is not in use.
 +
 +The compartment part of the above security context is a **category range**, but can also be a set of categories separated by commas. A range of categories results in the context being associated with an inclusive set of categories in that range. Understanding how access is computed for two processes with a set of categories requires looking at the **dominance** rules for SELinux security levels (access is only allowed if the source type's high security level **dominates** the target type's high security level). Those rules are as follows (only accounting for categories, and not MLS security levels)
 +
 +  * Source dominates the target if the categories in the source context are the same as or a superset of those in the target context.
 +  * Source is dominated by the target if the categories in the source context are a subset of the categories of the target context.
 +  * Source and target are equal and dominate each other if the set of categories are the same in each context.
 +
 +With that in mind, we know that a context with a category set of c0.c5 will be granted access to a context with a category set of c0,c3, but not a category set of c0,c6, or c0.c1023. This rule is the reason that sVirt generates a random set of categories, so there will be no overlap where one virt domain will dominate another. The Android project also does the same thing, to put applications in isolated domains.
 +
 +An example use of Multi-Category Security could be using NGINX with multiple vhosts that connect to backend servers that are also running as httpd domains (e.g., PHP-FPM). Normally these instances of the backend servers would be able to modify and manage each others domains simply due to type-enforcement rules. If they're associated with categories, they can only do so if one backend server dominates the other. Since NGINX itself is a HTTPD domain, it should dominate all backend servers, so if we have categories c0 through c5 available for HTTPD domains we would want to run NGINX as ''system_u:system_r:httpd_t:s0-s0:c0.c5'', so it could connect to the upstream servers. Each backend server would run with a single category within c0-c5, and a context such as  ''system_u:system_r:httpd_t:s0-s0:c1''.
 +
 +There are a couple of presequities to achieving this. First, ''httpd_t'' must be associated with the ''mcs_constrained_type'' attribute that is currently only associated with the following types on CentOS 7:
 +
 +<WRAP center box 100%>
 +<code>
 +# seinfo -xamcs_constrained_type
 +</code>
 +<sxh plain; gutter: false;>
 +   mcs_constrained_type
 +      netlabel_peer_t
 +      openshift_t
 +      openshift_app_t
 +      sandbox_min_t
 +      sandbox_x_t
 +      sandbox_web_t
 +      sandbox_net_t
 +      svirt_t
 +      svirt_tcg_t
 +      svirt_lxc_net_t
 +      svirt_qemu_net_t
 +      svirt_kvm_net_t
 +</sxh>
 +</WRAP>
 +
 +To add to this list of types it is necessary to create a local policy module that associates the desired type with the attribute. This is done using the typeattribute statement, and can be done like so:
 +
 +<sxh plain; gutter: false;>
 +policy_module(httpd_mcs, 1.0)
 +gen_require(`
 +    type httpd_t;
 +    attribute mcs_constrained_type;
 +')
 +
 +typeattribute httpd_t mcs_constrained_type;
 +</sxh>
 +
 +See FIXME Customizing Local Policy for instructions on building policy modules.
 +
 +Once the type is associated with mcs_constrained_type each backend server must have their content relabeled to include the respective categories in their file context specifications. This can be achieved by adding the file types to /etc/selinux/targeted/contexts/customizable_types, but this can potentially break on a policy upgrade. An alternative is to add new file contexts specifications that include categories using **semanage-fcontext**:
 +
 +<code>
 +# semanage fcontext -a -t httpd_sys_content_t -r "s0-s0:c1" "/srv/backend1(/.*)?"
 +# semanage fcontext -a -t httpd_sys_content_t -r "s0-s0:c2" "/srv/backend2(/.*)?"
 +</code>
 +
 +The next step is making sure the backend servers are started with the correct security context. On CentOS 7 with systemd this can be achieved with the ''**SELinuxContext=**'' directive in the unit file, and in previous versions can be achieved using the ''**runcon**'' command.
 +
 +<code>
 +# runcon "system_u:system_r:httpd_t:s0-s0:c1" "/usr/local/bin/backend-server"
 +</code>
 +
 +Or in the systemd unit:
 +
 +<sxh plain; gutter: false;>
 +SELinuxContext=system_u:system_r:httpd_t:s0-s0:c1
 +</sxh>
 +
 +Now each backend server should be isolated from the other, while allowing NGINX access to manage and send messages to both of them.
  
  
Line 249: Line 329:
  
 https://wiki.centos.org/HowTos/SELinux https://wiki.centos.org/HowTos/SELinux
- 
  
  
  • redhat/base-redhat/selinux-redhat.txt
  • Last modified: 2018/05/08 11:22
  • by michael