MLS System with Single Level Networks

One of the most common complaints I hear about the labeled networking access controls in Linux is that users don’t know how to configure them for their given scenario. To help solve that problem I’m going to try and document some basic use cases and the associated labeled networking “configuration recipes”.

To start off, I’m going to tackle a fairly common use case: a SELinux system with different MLS/MCS labels connected to multiple, single label networks. Imagine a SELinux based system providing services, e.g. a web server, to multiple different networks, each consisting of label un-aware clients, e.g. Windows desktops, operating at different securit labels. For this example, we will assume that the SELinux system is connected to two single label networks, one labeled at s1:c3,c5 (eth0,10.0.0.0/24) and the other labeled at s2:c4,c6 (eth1,10.0.1.0/24). To complete the example, we will also assume that the SELinux system is running at least one application which needs to connect to the local system (localhost) at different levels.

The first step is to configure NetLabel to label incoming traffic on the unlabeled, single label networks.

# netlabelctl unlbl add interface:eth0 address:0.0.0.0/0 label:system_u:object_r:netlabel_peer_t:s1:c3,c5
# netlabelctl unlbl add interface:eth1 address:0.0.0.0/0 label:system_u:object_r:netlabel_peer_t:s2:c4,c6

In general we don’t have to worry about the outbound traffic in this case since NetLabel sends all traffic unlabeled by default, but let’s go ahead and assume that isn’t the case for the sake of demonstration. The commands below remove the default mapping and instruct NetLabel to send unlabeled traffic to both of the single label networks as well as any networks not explicitly specified (both IPv4 and IPv6).

# netlabelctl map del default
# netlabelctl map add default address:10.0.0.0/24 protocol:unlbl
# netlabelctl map add default address:10.0.1.0/24 protocol:unlbl
# netlabelctl map add default address:0.0.0.0/0 protocol:unlbl
# netlabelctl map add default address:::/0 protocol:unlbl

Next we want to configure the system to send labeled traffic to itself, so we need to tell NetLabel to send CIPSO labeled traffic to all of the system’s addresses (in this case that would be 10.0.0.2, 10.0.1.2, and 127.0.0.0/8). However, first we need to configure a CIPSO DOI for this local traffic labeling; in this example we will use DOI #32 and the pass through DOI type with the enumerated (tag #2) and restricted bitmaps (tag #1) tags.

# netlabelctl cipsov4 add pass doi:32 tags:2,1
# netlabelctl map add default address:10.0.0.2 protocol:cipsov4,32
# netlabelctl map add default address:10.0.1.2 protocol:cipsov4,32
# netlabelctl map add default address:127.0.0.0/8 protocol:cipsov4,32

Now we should have all of the labeling configuration in place and it is just a matter of making sure your SELinux configuration/policy is correct for the accesses you want to allow. One important thing to remember is that you likely will want to use the semanage tool to set the SELinux label for the single label interfaces; this will ensure that only traffic labeled as s1:c3,c5 can traverse the eth0 interface and only traffic labeled as s2:c4,c6 can traverse the eth1 interface.

# semanage interface -a -t netif_t -r s1:c3,c5 eth0
# semanage interface -a -t netif_t -r s2:c4,c6 eth1

At this point, if you haven’t already, you should double check your SELinux policy as you will most likely need to add some custom policy modules to match your new labeled networking configuration, but thankfully that is something which has gotten much easier the past few years and already has plenty of good documentation available. You may also want to start investigating the xinetd LABELED configuration option as a way of starting server applications at the label of the incoming connection request; it can be a very useful option for systems like this where you have client requests coming in at different levels.