March 24th, 2011

10 things you probably did not know about SELinux.. #3

SELInux versus nsswitch.conf

Many confined domains call getpwnam, getpwuid, getpwent functions.  Traditionally these function calls just read the the /etc/passwd file.  In a modern Linux system the glibc has added nsswitch.

man nsswitch.conf
       nsswitch.conf - System Databases and Name Service Switch configuration file

       Various functions in the C Library need to be configured to work correctly in the local environment.  Tra‐
       ditionally, this was done by using files (e.g., /etc/passwd), but other  nameservices  (like  the  Network
       Information  Service  (NIS)  and the Domain Name Service (DNS)) became popular, and were hacked
       into the C library, usually with a fixed search order.

nsswitch functionality allows multiple back-ends for the getpw*. These back-ends can change the access required by a process, and SELinux has to allow for these different back-ends.

If you have setup your system with your passwd data in ldap, SELinux is forced to allow all confined domains that call getpw* to connect to the ldap_port_t ports in order to get passwd data.

# semanage  port -l | grep ldap
ldap_port_t                    tcp      389, 636, 3268
ldap_port_t                    udp      389, 636

Also since the confined application needs to resolve the hostname of the ldap server, the confined application needs to be able to connect to dns_port_t.

# semanage  port -l | grep dns
dns_port_t                     tcp      53
dns_port_t                     udp      53

Even worse if you are using NIS all of these applications have to be able to connect all ports and bind to all ports.

We have had a boolean allow_ypbind since RHEL5, luckily this is turned off by default and eliminates a lot of access.  You only need to turn it on if you are using NIS.

sssd (System Security Services Daemon) to the rescue.

sssd provides a new back end for nsswitch.  This backend causes all callers of getpw* functions to used a named socket, /var/lib/sss/nss.  The beauty of the sssd backend is the sssd daemon does all of the ldap communications for the confined applications, rather then the confined applications needing to connect directly to the ldap server/port.

In Fedora 15 we added a new boolean authlogin_nsswitch_use_ldap that allows you to turn off this access. 

NOTE:  You can turn off this boolean even if you are using ldap for passwd entry resolution if you are using sssd.

How many rules does this eliminate?

Using sesearch to look for rules tat allow a domain to connect to the ldap_port_t.

# sesearch -A -t ldap_port_t -p name_connect -C | wc -l

If we eliminate the allow_ypbind boolean

# sesearch -A -t ldap_port_t -p name_connect -C | grep -v allow_ypbind | wc  -l

Now if we further eliminate authlogin_nsswitch_use_ldap

# sesearch -A -t ldap_port_t -p name_connect -C | grep -v allow_ypbind | grep -v authlogin_nsswitch_use_ldap | wc -l

Meaning we have eliminate over 600 rules that allow confined domains to connect to the ldap_port_t.

You can turn off both booleans by executing.

# setsebool -P allow_ypbind=0 authlogin_nsswitch_use_ldap=0

I plan on turning both booleans off by default in Fedora 16.