kern/161888: nfs -sec=krb5x/ldap/krb5-heimdal fix/upgrade

Harry Coin hcoin at quietfountain.com
Sat Oct 22 00:20:14 UTC 2011


>Number:         161888
>Category:       kern
>Synopsis:       nfs -sec=krb5x/ldap/krb5-heimdal fix/upgrade
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 22 00:20:10 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Harry Coin
>Release:        8stable
>Organization:
Quiet Fountain LLC
>Environment:
amd64
>Description:
Explanation of the reasons for Heimdal/krb5 library patches/enhancements Oct 2011, mostly on Freebsd 8-stable.

Overview:  

Administrators with working ‘single sign on’ networks that use kerberos, LDAP, NFS PAM and more may wish to secure their internal network communications as users with wifi and cell phones with bridges, laptops and so on may be connecting.  These patches identify and overcome shortcomings and problems that otherwise would impose security or functionality regressions blocking the use of nfs and other services wanting krb5 authentication, integrity protection or encryption of network traffic.

Three General Areas of Concern:

1.	Absent these patches: NFS + kerberos authentication, integrity or encryption security (sec=krb5 krb5i krb5p) only is available for those accounts with kerberos principals having the form xxx at REALM --with no /.   However, there is strong pressure to create kerberos principals of the form xxx/box.domain.org at REALM to secure such popular services as nfs (nfs/box.domain.org) and LDAP / openldap via cyrus-sasl (ldap/box.domain.org), nslcd (nslcd/box.domain.org) (GSSAPI RFC).  And most especially root:  it’s not a good idea to have a principal of the form root at REALM, but only root/box.domain.org at REALM. It must be possible to log in locally as root, whether the network is operating or not.  Users and processes operating under these accounts pre-kerberos via NFS presently have the ability to read and write files via NFS with their own username/uid (depending on –maproot and other share parameters). But, when adding kerberos, the NFS server is presently incapable of authenticating t
 hese in any way (owing to the /), forcing all such users reading or writing over the network to map to ‘nobody’ on remote shares.   

2.	System services that are launched as root, but then for security drop root authority, must read their keytabs from the system default keytab mentioned in the krb5.conf file, as ‘taint’ tests cause the library to disregard environment variables allowing for alternate credential storage.  Presently administrators must allow these keytabs to be group readable so the drop root services (nslcd, ldap/slapd) can read them.  However, these also presently must store the host/ and root/ and nfs/ keytabs.  So, any successful exploit of the drop-root service will give the misdoer the ability via the keytab to authenticate as any of the high-authority principals frustrating the whole point of dropping root authority to begin with.  These patches address that problem.

3.	NFS and all other kerberos services such as pam that need to connect kerberos principals with user names and user ids make heavy use of kerberos library procedures krb5_aname_to_lname, and krb5_kuserok.  Presently these services open .k5login and other files on each call, or in some cases just refuse altogether to connect any principal name including a / with any user name at all.  So, root/box.domain.org, ldap/box.domain.org the present routines will fail to associate with user root,ldap, etc.  Worse, the kuserok routine presumes that every user has a default directory specified in the first place, and then looks for a .k5login file to see which principals that user/account will permit access.   What of those accounts with no default directory (/nonexistent)?  What of accounts having default directories not /home/user but /var/db or possibly not only user writable? 




PATCH FUNCTIONALITY DOCUMENTATION:

To address concern 2, the patches implement keytab file system type UIDF.   Here’s an example /etc/krb5.conf fragment:

[libdefaults]
   default_realm= WHATNOT.COM
   default_keytab_name = UIDF:/etc/keytabs/krb5.keytab

The effect of the UIDF is this:  When opening a keytab the system will replace the . with .uid.  So, if the caller has effective uid 33, and the above krb5.conf, the system will first try to open /etc/keytabs/krb5.33.keytab.  If that fails, it will then try /etc/keytabs/krb5.keytab.  

The result is that daemons that drop root privileges now can store usually just the one or few key meant to be readable by only the specific user in just one keytab file in /etc/keytabs—which keytab is owned by the same non-root account and readable only by that account.  

The drop root daemon does not need access to the root’s keys in the root keytab file.  Previously administrators would have to create some new special group and make the root’s keytab readable by that—pretty much defeating the purpose of dropping root authority at all.  This is particularly important for openldap’s slapd server that has so many plugins running it at root authority is a very bad idea.  Securing access to it via SSL and using SASL / GSSAPI to require only non-anonymous authenticated binds with this fix is now meaningful.





To address concern 3:  These patches implement a 5 minute memory cached association for the most recent 1023 lookups trying to determine some connection between user accounts and kerberos principal names.  Calls to krb5_kuserok or krb5_aname_to_lname first try to see if a recent call with the same arguments succeeded, and if so returns that result again almost immediately without checking any of the files. 

The upshot is that removing or deleting a principal from a .k5login file or otherwise will take up to five minutes before these routines will reflect that change.  Adding associations will not create any problem as the system will check the files if the cache doesn’t contain a record of the desired association.   This change has also called for the creation of another krb5 library function, one that simply flushes the caches and frees associated resources.   Users that do not call these routines do not suffer any wasted memory overhead, the caches are created on the first call and are multi-thread safe.

The new library call is:

void KRB5_LIB_FUNCTION krb5_luser_principal_cache_free(krb5_context context)

This call can be completely ignored.  Deleting a context will automatically flush the cache if any was created at all.  Calling this function then calling either krb5_kuserok or krb5_aname_to_lname will recreate an empty cache then begin to use it going forward.  So, if its really important that deleting the ability of a principal to act as a local user can’t wait five minutes, there’s this call for you.




To address concern 1: 

These patches add the ability of the krb5_kuserok and krb5_aname_to_lname routines to do exactly as they did before, except not fail to associate principals having one or more / in their names to local accounts.   They also allow for users with no ‘home directory’ or no .k5login files to match principals.  This is accomplished by the creation of directory

/etc/k5login.d

That directory must be world readable.  The files in that directory are user names, and the content of those files are principal names except regular expressions are allowed.  For example if the file

/etc/k5login.d/ldap

had the content

ldap/*.domain.com at DOMAIN.COM

then any principal using the GSSAPI format ldap/anyboxname.domain.com would be associated with the local user ldap.  Calls to kuserok asking whether principal ldap/foo.domain.com matched ldap would return ok.  Calls asking aname_to_lname what local user should be associated with ldap/whatnot.domain.com at DOMAIN.COM would get ldap.

Notice this gives significant new power to system administrators.  Creating an entry in /etc/k5login.d will prevent users and other dubious actors from somehow creating .k5login files with vast lists of dubious principals who would then be allowed local access.

If any file in /etc/k5login.d includes the line
#STOP
then kuserok processing will be unchanged and will continue to process principals, but aname_to_lname lookups will not look further in that file.  This not only offers some speedup, but makes it possible to prevent principals access who by happenstance appear in a user account for login purposes but who aren’t meant to suggest the given local user is the one best to be returned.

This facility is meant to be more flexible than the MIT kerberos’ similar facility that encodes the forgoing in an elaborate aname_to_lname regular expression / substitution mechanism in the krb5.conf file, but does not provide a way for users with no home directory or with a directory inappropriate for a .k5login file to exist access.

So, if file /etc/k5login.d/root had
  Entries:
root/box1.foo.com
root/admin?.foo.com
root
#STOP
myoffsite/principal/somewhere

then only root users on box1, admin(one letter/number) and local root could log in as root as well as principal myoffsite/prinicipal/somewhere.

But, when asking the system what local account ought be associated with myoffsite/principal/somewhere the system will not consider returning ‘root’. 

Note that pattern matching against principals only happens in the /etc/k5login.d files, not the user’s typical ~/.k5login files. This to avoid the antisocial possibilities of a file having * matching all principals.

To effect these changes, modifications have been made to these files, against what’s in Freebsd 8-Stable:

Aname_to_localname.c
context.c
keytab_file.c
krb5-private.h
krb5-protos.h
krb5.h
krb5_locl.h
kuserok.c
misc.c


>How-To-Repeat:
Connect as a nfs client to any nfs share using a kerberos principal name with a /.  You'll see you only have 'nobody:nogroup' access.  Try to protect a keytab read-only to a non-root account and put a daemon key in it, absent these patches the only way you'll be able to see it is to change krb5.conf-- breaking anything else that relied on the root/host default keytab (unless you want to make the keytab group readable).  For more, see above.
>Fix:
Updated source files and patches and doc against 8stable at: 

http://www.quietfountain.com/krb5nfspatches.tbz

It has all the sources, patches against freebsd 8stable, and doc.  I'll leave it there for a few weeks only.

Also, it won't work unless you also:

/usr/src/kerberos5/lib/libgssapi_krb5/pname_to_uid.c.   In line 40:
-40 char lname[MAXLOGNAME + 1], buf[128];
+40 char lname[MAXLOGNAME + 1], buf[1204];

/usr/src/kerberos5/lib/libgssapi_krb5/gss_kb5.c.  Add
#include <roken.h>
+#include <der.h>

and make,make install there and also ...lib/libkrb5

Somehow the online bug report form rejected the tbz above.



Somehow the uploading thing wouldn't accept a .tbz

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list