2009-07-12
A brief history of NFS server access restrictions
In the beginning, NFS servers had no access restrictions. No, really.
In the early versions of NFS, the kernel NFS code had no access checks;
if you had a valid filehandle, the kernel
was happy to talk to you, regardless of who you were. What NFS access
restrictions existed were all done during the NFS mount process; if you were not authorized to mount the particular thing
you were asking for, mountd
would not give you a filehandle for
it. This was, of course, secure only as long as you couldn't get a
filehandle in some other way, and pretty soon it was painfully clear
that you could.
(And once you had the filehandle for the top of a filesystem, that was pretty much it, because it wasn't as if that filehandle could easily be changed.)
This sparked a rush to put some sort of NFS access restrictions in
the kernel itself. However, Sun had made NFS export permissions very
flexible and full of user-level concepts like NIS netgroups; it was
clear that you couldn't just push /etc/exports
lines into the kernel
and be done with it.
At first people tried having mountd
add specific permissions (this
IP address, this sort of access to this filesystem) to the kernel
either when it started or when client machines made (successful) mount
requests. There were at least two problems with this; first, for a
sufficiently big and permissive NFS server, this could be too much
information for the kernel to store, and second, there are situations
where this sort of static permission adding isn't good enough and valid
clients will get improper access denials.
As a result, all modern systems have moved to some sort of 'upcall'
mechanism; when the kernel gets a NFS request that it doesn't already
have permissions information for, it pokes mountd
to find out if
the client is allowed the specific access. The kernel's permission
information is effectively only a cache (hopefully big enough to avoid
upcalls under normal usage). This allows mountd
to have whatever crazy
permissions schemes it wants to without complicating the kernel's life.
Of course, this adds a new NFS mount failure mode. At least some kernels cache negative
permissions entries (this IP address is not allowed to access this
filesystem) so that they don't upcall to mountd
all the time for bad
clients. Under some situations valid clients can get stuck with such
a negative entry, and they can be very persistent. Until the negative
entry is cleared somehow, the client is not going to have access to the
filesystem, although everything will swear up and down that it has all
the necessary permissions, mountd
will give it a valid filehandle, and
so on.
(We had one client that couldn't mount a crucial filesystem from a Solaris 8 NFS server for months. Fortunately it was a test system.)