Managing NFS and NIS, 2nd Edition - Mike Eisler [159]
The first time, and on every subsequent contact to the server, the client encrypts the current time using the session key. It sends its RPC request to the server.
The server decrypts the timestamp, using the same session key, and verifies that it is accurate. If the decrypted timestamp falls outside of the time to live window, the server rejects the request.
So far we've described how RPC/DH does authentication. We will now look at how identity works in RPC/DH. Recall that AUTH_SYS sends a UID, GID, and a list of supplementary GIDs. The first time RPC/DH contacts the server to establish the session key, it sends no UIDs or GIDs. Instead it sends a string, called a netname, which identifies two items:
The user (albeit, the username is a UID expressed in ASCII-decimal)
The domain name of the user (usually this is an NIS domain name)
The server does three things with the netname:
Locates an NIS server serving the specified domain that knows about the user.
Looks up the user's netname in the NIS netid map for the user's UID, GID, and list of supplementary groups.
Looks up the user's netname in the NIS publickey map for the user's Diffie-Hellman public key. With that, and the server's private key, the server can determine the common key, then the shared secret key, then decrypt the session key, and use that to verify that the request came from a user corresponding to the netname.
By the way, notice that AUTH_DH doesn't have the "too many groups" problem of AUTH_SYS that was discussed in Section 12.4.1, since no GID list is sent on the wire.
RPC/DH state and NFS statelessness
The title of the section says it all. How can we reconcile the fact that NFS is stateless, and yet RPC/DH clearly establishes state in the form of a session key, with a time to live? This state has to be kept on the server. The answer is that this is not state that has to be recovered in the event of a server crash, which is in stark contrast to file locking state. If the server reboots, or if it even decides to throw away an RPC/DH session, it is not a disaster. The client simply gets an error indicating that the server has no knowledge of the session, and the client establishes a new session key as if it was the first contact between the client and server.
We'll now look at how NFS/dh works by first seeing how to add the security features to NFS, and then seeing how the public and private keys are managed within this system.
Enabling NFS/dh
Enabling NFS/dh on a filesystem is quite simple: export and mount the filesystem with the sec=dh option. On the NFS server, the /etc/dfs/dfstab entry looks like this:
share -o sec=dh,rw /export/home/thud
When a filesystem is exported with the sec=dh option, clients using NFS Version 2 must mount it with the sec=dh option if they are to enjoy normal user access privileges in the filesystem. On the NFS client, add the sec=dh option in the automounter map entry, or the /etc/vfstab entry for the filesystem:
automounter auto_home entry:
thud -sec=dh bonk:/export/home/thud
vfstab entry:
bonk:/export/home/thud - /thud nfs - no sec=dh,rw
If the client is using NFS Version 3, it will use Version 3 of the MOUNT protocol. MOUNT Version 3 will return the RPC security flavor that the directory is exported with, along with the filehandle of the directory. Thus, with NFS Version 3, the sec=dh mountoption is not necessary.
If a user accessing the filesystem can generate a session key with the NFS server, it is used to encrypt the timestamps sent with that user's NFS requests. If the server decrypts the timestamps successfully, the netname presented by the user is trusted and is used to derive normal Unix-style credentials for the purpose of file access.
It's possible, though, that the user can't exchange a session key with the server. This will be the case if the user doesn't have a public key defined, or if the user cannot supply the proper private key to generate a common key using Diffie-Hellman key exchange. When there is no valid common key, some NFS servers