Friday, February 24, 2006

Real Authentication in NFS

I get asked a lot about what can be done to prevent the following:

nfs client% cd /home/jim
/home/jim: Permission denied
nfs client% ls -ld /home/jim
drwx------ 2 jim grp1 117 Feb 24 07:48 /home/jim/
nfs client% su
nfs client# su jim
nfs client% cd /home/jim

What is happening is that user jim has set the permissions on his data to 0700 meaning only he, the owner, should get access. But someone on the NFS client with knowledge of the super-user password can become root (user id 0), and then become jim and circumvent jim's protections. The reason why this works is that the NFS server is accepting AUTH_SYS credentials, which are basically, a user id, and 1 to 17 group ids. Simply su'ing to jim causes the NFS client in the kernel to pick up jim's user id and group ids.

Some people have suggested if a more secure directory service like LDAP is used, especially if its configured to use Kerberos V5 authentication, that this is providing Kerberos authentication and so will defeat the attack. No, that is not the case. All that does is make sure the user using LDAP is authenticated via Kerberos (and the LDAP server is authenticated to the user via Kerberos). While this is a good thing, it does absolutely nothing to prevent the scenario above.

The only thing today that prevents the scenario is to use Kerberos V5 (or some other strong authentication system, but Kerberos V5 is what most vendors have) authentication in the NFS traffic itself. This means exporting the volume with option sec=krb5 (or krb5i, or krb5p), and without anon=0 and without root=.

What happens is that even if the attacker su'es to jim, unless he knows jim's Kerberos password, he cannot become user jim over the NFS connection. Even attempting to access /home/jim as super-user, even with Kerberos credentials for super-user, is defeated, because super-user, uid 0, will be mapped to user nobody (since anon=0 and root= are absent in the export options).

Restricting access knowledge of the super-user password, while an excellent practice, is no panacea either. This is because synthetic, user-level NFS clients aren't rocket science to write, and they can be written so that any uid can be specified in the AUTH_SYS credential. There are "nfs shell" programs out there for anyone to download. While the one I've tried isn't written to allow arbitrary user ids to be inserted into the credentials of the NFS requests, it wouldn't be hard to change it.

You might find the following links interesting:

Connectathon is next week Feb 27-March 3, 2006

I'll be presenting on "NFS over TCP, again" (the "again" is because this will be the third time I'll have presented on this topic) on Wednesday. Unfortunately, the talks aren't open to non-registrants as they were in past years. However, the Connectathon folks are usually very good about getting slides posted within days of the event ending. After Connectathon, I plan to blog more about it, my presentation and other presentations.