autofs/automount failing to mount nfs exports from localhost in Debian 12

We have a setup where various systems export scratch directories to each other for convenience. An export is set up like:

/local/scratch -rw,root_squash,no_subtree_check,sync 192.168.2.0/24

Autofs maps come from LDAP – the autofs configuration is:

[autofs]
timeout = 300
browse_mode = no
mount_nfs_default_protocol = 4

ldap_uri = ldap:///dc%3Dldap%2Cdc%3Dyour%2Cdc%3Dserver%2Cdc%3Ddns%2Cdc%3Dname

search_base = ou=maps,ou=subsubunit,ou=subunit,o=organisation

map_object_class = nisMap
entry_object_class = nisObject
map_attribute = nisMapName
entry_attribute = cn
value_attribute = nisMapEntry

[ amd ]
dismount_interval = 300

If server A (ip address 192.168.2.101) exports the directory, server B (ip address 192.168.2.102) that also gets the autofs maps automounts this as expected when accessing the desired directory. The findmnt command shows:

└─/scratch                           auto.scratch    autofs     rw,relatime,fd=25,pgrp=2511731,timeout=300,minproto=5,maxproto=5,indirect,pipe_ino=1385785421
  └─/scratch/serverA                 serverA:/local/scratch     nfs4       rw,nosuid,nodev,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.2.102,local_lock=none,addr=192.168.2.101

If server A is a Debian 11 system and we access /scratch/serverA on this system the resulting findmnt output looks like

└─/scratch                           auto.scratch                              autofs     rw,relatime,fd=25,pgrp=2511731,timeout=300,minproto=5,maxproto=5,indirect,pipe_ino=1385785421
  └─/scratch/serverA                 /dev/nvme0n1p1                            ext4       rw,relatime

The automounter has realised that the export comes from the same system, and does a bind mount instead. In this case /local/scratch is where the partition /dev/nvme0n1p1 is mounted (this appears further up the findmnt tree). The automounter appears to follow the chain back and do a bind mount of the base filesystem to the new location. Note that this behaviour can be changed with the nobind option in the autofs maps – see the auto.master man page.

If server A is then upgraded or reinstalled as Debian 12, the behaviour changes. Initially, the automount fails. When we examine the logs we see:

rpc.mountd[2437]: refused mount request from 127.0.0.1 for /local/scratch (/): not exported

We can add the loopback address to the list of allowed addresses in /etc/exports, and the automount then works. findmnt shows that:

└─/scratch                                               auto.scratch            autofs      rw,relatime,fd=18,pgrp=5367,timeout=300,minproto=5,maxproto=5,indirect,pipe_ino=32005
  └─/scratch/serverA                                     serverA:/local/scratch  nfs4        rw,nosuid,nodev,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=127.0.0.1,local_lock=none,addr=127.0.1.1

So the automount can be made to work as an actual network mount going through the loopback address.

This actually appears to be the expected behaviour for nfs4 – see this bug report from 2006(!). Notably:

Jeff Moyer 2006-04-17 21:52:34 UTC
In the event that you have “fstype=nfs4” in your options, the automounter should
not attempt a bind mount when the server is localhost. The reason for this is
that the automounter would need nfsv4 specific information to determine where
the mount actually comes from. As you noted, it’s not straight-forward as it is
in v2 and v3.

So, for your nfsv2 and nfsv3 mounts, the automounter should continue to use bind
mounts. If you specify -fstype=nfs4, then you should get a mount via nfs4.

Clear as mud?

So the question should probably be – why does the automounter do bind mounts in Debian 11, even if it is nominally dealing with nfs4? Falling back to v3 somehow. Debian-specific patch? Whatever it is I can’t find any Debian-specific discussion of the change (and there was only a minor version bump of autofs from 11 to 12).

Blocking or disabling autofs automounts with the -null map

Suppose you have a linux network setup with automounter maps that come from the network (via nis, sssd, LDAP etc.) and you want to block some of them acting on a particular system. In our case we have an automount map that acts on /opt and mounts various software packages from network shares. The problem with this is that you can’t then install your own stuff locally to /opt, which is what a lot of Debian/Ubuntu packages expect to be able to do.

It turns out there is a option in the automounter for this sort of situation. There is a built-in map called -null that blocks any further automounts to a particular mountpoint. In our case we want to block auto.opt, so we add a line to auto.master (somewhere before the bottom +auto.master line)

/opt  -null

Then restart the autofs service (if stuff was mounted on /opt then unmount it). Or reboot the system. You should find that you can put stuff in the local /opt.

To check the map is blocked you can also run

automount --dumpmaps

(also handy for checking what is actually meant to be mapped where).

Another way of doing this that leaves the system auto.master untouched is to create a file /etc/auto.master.d/opt.autofs (the first part of the name can be anything you want). Put the same contents in the file, e.g.

/opt  -null

Note that using this mechanism normally requires two files – one in /etc/auto.master.d/ and a map file that it refers to. In this case -null is a built-in map.

Unfortunately this option is not well documented. Places where it is referred to are:

There are also other built-in maps, e.g. -passwd, -hosts, -fedfs. Of these only the -hosts map is documented in the auto.master(5) man page.

-null is confirmed to work in CentOS 7, CentOS 8, Ubuntu 20.04, Debian 10.

Notes on getting Ubuntu 16.04 to work with NIS

Note – this only sets up the system to use user and group logons, not automounting home directories. I haven’t figured out how to make this work in Ubuntu 16.

Install package nis

Probably a good idea to set network address statically in /etc/network/interfaces (NetworkManager should recognise this and then leave it alone)

Probably also a good idea to check that /etc/hosts has the domain name for the system, i.e.

127.0.1.1 domain.name.machinename machinename

Add yp server to /etc/yp.conf

Edit /etc/nsswitch.conf to add nis for passwd, group and shadow. Note that compat should include nis by default.

Add a dependency to make the rpcbind service start at boot

systemctl add-wants multi-user.target rpcbind.service

(See this Debian bug report or this Ubuntu one)

Note that this is not a complete fix – it is reported that if the network does not come up fast enough things still break.

For users that need to log on to the system, create home directories

mkhomedir_helper <username>

Remember to reboot to check everything is working:

yptest

if that fails check if the bind services are running

systemctl status rpcbind
systemctl status ypbind