Network Ingress/Egress Controls

I've already talked about Fallback Labels and Network Peer Controls now I'm going to explain the last major labeled networking feature included in the 2.6.25 release of the Linux Kernel, the network ingress/egress controls. One of the longstanding problems with the SELinux network access controls was that they lacked any ability to control packets at the network interface level, limiting our ability to provide access control based on the physical network and making it impossible to provide access control for forwarded packets. The network ingress/egress controls were designed to solve these problems by placing SELinux network access controls at the network interface level.

The new ingress/egress controls are fairly simple: each packet entering the system must pass an ingress access control and each packet leaving the system must pass an egress access control. Forwarded packets must also pass an additional forwarding access control, but I'm going to leave that for another time and focus on the ingress/egress cases. In both the ingress and egress access controls the network packet is subjected to network interface and network address checks. In order to allow incoming network traffic to enter the system you need the following two allow rules (where network_if_t is the network interface's label, network_addr_t is the remote host's network address label and peer_t is the traffic's peer label):

allow peer_t network_if_t:netif ingress;
allow peer_t network_addr_t:node recvfrom;

Network traffic leaving the system requires similar allow rules:

allow peer_t network_if_t:netif egress;
allow peer_t network_addr_t:node sendto;

As a reminder the peer labels, peer_t in the above examples, are derived from the original sender's security label. In the case of incoming network traffic the peer label is taken from the network labeling protocol, if available, and in the case of outgoing network traffic the peer label is taken from the application/socket which generated the traffic. The network interface and address labels are defined as part of the SELinux policy and can be modified on-the-fly using the semanage tool.

Moving on to a more concrete example, imagine a web server running Apache with the eth0 network interface labeled as "wwwsrv_if_t", no explicitly labeled network addresses (which means addresses will be represented by the default address label, "node_t") and a "private_net_t" fallback label defined for addresses that match 192.168.0.0/16. If we want to allow network traffic from 192.168.0.0/16 over the eth0 interface into the system and allow responses back from Apache we need to write the following allow rules:

allow private_net_t wwwsrv_if_t:netif ingress;
allow private_net_t node_t:node recvfrom;
allow apache_t wwwsrv_if_t:netif egress;
allow apache_t node_t:node sendto;

Like the new network peer controls, the ingress/egress controls are currently not enabled, protected by the same policy capability flag which protect the peer controls, "network_peer_controls". I am currently testing a small patch which should solve the remaining policy issues and allow us to finally enable this new functionality. In the meantime if you want to try it yourself you need to uncomment the "policycap network_peer_controls;" line in the policy_capabilities file found in the SELinux Reference Policy sources and rebuild the policy. Good luck, and if you hit any snags don't hesitate to drop a comment below and I'll help you sort it out.