How to see and flush the Linux kernel NFS server's authentication cache
We're going to be running some Linux NFS (v3) servers soon (for
reasons beyond the scope of this entry), and we want to control
access to the filesystems that those servers will export by netgroup,
because we have a number of machines that should have access. Linux
makes this a generally very easy process, because unlike many systems
you don't need
in order to use netgroups. All you need to do is change
/etc/nsswitch.conf to say '
netgroup: files', and then you can
just put things in
However, using netgroups makes obvious the important question of how you get your NFS server to notice changes in netgroup membership, as well as more general changes in authorizations such as changes in the DNS. If you add or delete a machine from a netgroup, or change a IP's PTR record in DNS, you want your NFS server to notice and start using the new information.
I will skip to the conclusion: the kernel maintains a cache of mappings from IP addresses to 'authentication domains' that the IP address is a member of. When it needs to know information about an IP address that it doesn't already have, the kernel asks mountd and mountd adds an entry to the cache. Entries are generally added with a time-to-live, after which they'll be automatically expired and then re-validated; mountd hard-codes this TTL to 30 minutes.
(You can read more information about this and several other interesting
things in the nfsd(7) manpage,
which describes what you'll find in the special NFS server related
/proc and associated virtual filesystems.)
You can see the contents of this cache by looking at
/proc/net/rpc/auth.unix.ip/content. Note that the cache includes
both positive entries and negative ones (where mountd has declined
to authorize a host, and so it's had mount permissions denied). To
clear this cache and force everything to revalidate, you write a
sufficiently large number to
So, what is a sufficiently large number?
The nfsd(7) manpage describes
flush this way:
When a number of seconds since epoch (1 Jan 1970) is written to this file, all entries in the cache that were last updated before that file become invalidated and will be flushed out. Writing 1 will flush everything. [...]
That bit about writing a
1 is incorrect and doesn't work (perhaps
this is a bug, but it's also the reality on all of the kernels that
you'll find on systems today). So you need to write something that
is a Unix timestamp that's in the future, perhaps well in the future.
If you feel like running a command to get such a number, the simple
thing is to use GNU date's relative time feature:
$ date -d tomorrow +%s 1486620251
The easier way is just to stack up
9s until everything gets
flushed. Of course there have been so many seconds since the Unix
epoch that you need quite a lot of 9s by now.
Probably we're going to wrap this up in a script and put a big comment
at the start of
/etc/netgroup (and possibly
/etc/exports) about it.
Fortunately I don't expect our netgroups to change very often for these
fileservers. Their export lists will likely be mostly static, but we'll
slowly add some additional machines to the netgroup.