Many things for not many people

Systemd automounts

Published on: by David Jolley

Updated on: • 7 min read

Today, I learned about systemd autmounts. This is essentially the ability to define a mount point and its target, and have it automount when the directory is first accessed. I used samba mounting, and I'm using a base ubuntu linux operating system, so I had to install the cifs-utils and smbclient packages. Your OS and install packages may be different, but it's the same principle involved. You need to install the packages which install the mount.cifs and smbclient programs/utilities.

The trick is that a systemd based system can define mounts in the normal place, /etc/fstab and add a couple of options which means that the mount isn't processed at the point that local filesystems are mounted (which could be a bad thing if that time is prior to the network coming up - which may have been true a number of years ago) but instead is processed at the point that the directory is first used. This does incur a slight delay on the first use, but it's largely not noticeable, I guess unless your mounted device is on a really slow network (or is a really slow device). My shares are held on my Synology Diskstation, so are locally connected and quite zippy-quick.

So. The way this works is that you create the directories in your filesystem and tell systemd - through your filesystem table file - that you want to mount a network device into that directory. All the advice on the internet is that you should mount the remote filesystems into directories in the /mnt directory; your mileage may vary, etc and if your PC is a single user computer, there may be no advantage in oing this. However, it's good practise to mount things there, and I suppose symlinks exist for a reason...

Test that samba (cifs) shares are accessible in linux

This is optional, but if this is your first time accessing a remote share on a device which is supplying it through samba/windows sharing then you might want to test that things are basically working before you commit to editing system files to add the mount permanently to your setup.

Firstly, you need to create a file containing your remote device's credentials; your username and password. This is because the /etc/fstab file is world readable, and therefore you don't really want your credentials exposed in plaintext in that file.

The solution is to create a directory to hold these credentials in. There will be multiple files if you have more than one user or more than one device supplying the network shares. I created a directory, /etc/samba/credentials, and then in there I created a file per user and remote device pairing. For the purposes of example, lets say I have a machine called diskstation, and that I have a user account on that machine called dave. I would recommend creating a file /etc/samba/credentials/dave-diskstation so that from the filename it is easy to see which credential file is to be used for which remote device and username. In that file, you place the following contents:

username=dave
password=YourReallyLongSecurePasswordWithPunctuationHere.

making the obvious changes to the contents for your setup. You should then use this file to test the connection to your remote device.

An easy way of testing the credentials is using the smbclient program. Rather than making a connection to the computer and having to exit out of smbclient, there's a one-and-done command which will establish that things are working correctly. I use:

smbclient //diskstation/dave -A /etc/samba/credentials/dave-diskstation -m SMB3 -c 'pwd'

This creates the connection to //diskstation/dave (Assuming you have an account "dave" on a machine called "diskstation", which you likely don't, so edit as appropriate. Also, the parameter after the -A should be changed to be your credentials file you created above. This should succeed. If it prints an error, you've made a typo somewhere, or the password or username is wrong. The success case should be the single line printout of the current directory on the remote machine. In my case, this emitted: Current directory is \\diskstation\dave\

This concludes the test.

Securing your credentials file

This step shouldn't be skipped. Just like you didn't want your username and password in clear plaintext in a world readable file, you likewise want to restrict access to the credentials file to the user which needs it. To do this, use:

chown root:root /etc/samba/credentials/dave-diskstation
chmod 750 /etc/samba/credentials/dave-diskstation
chmod 710 /etc/samba/credentials

These three commands, in order:

  1. Set the owner of the credentials file to root and the group owner to root.
  2. Set the permissions for accessing the file to the owner (all access) and group (only read)
  3. Sets the permissions of the directory to be fully accessable to root, and only traversable by the root group. This latter permission means that the root group must know the name of the file which is to be used, they can't ls the directory.

With that done, the credentials are as secure as they're going to be.

Making the automount

With all the groundwork out the way, we can proceed to the main event; this is what you're here for, afterall. But first. You need to know your user ID and group ID. This is so that the mount can appear to be owned by your user and group and so maps all the remote permissions to your local user. To do this, issue the command: grep $(whoami) /etc/passwd | awk -F: '{print "user: "$3", group: "$4}' On most single user systems, this is likely to lead to the user id of 1000 and group id also 1000. If yours is different, substitute your values into the following text. Also, don't forget I've given the example with my hostname, username and credentials file. You need to substitute them for yours.

As root, edit the file /etc/fstab, to add the single line:

//diskstation/dave /mnt/dave cifs iocharset=utf8,rw,seal,credentials=/etc/samba/credentials/dave-diskstation,uid=1000,gid=1000,file_mode=0660,dir_mode=0770,nosuid,nodev,nofail,x-systemd.automount,_netdev,x-systemd.mount-timeout=30 0 0

Your edit should look different. Your first parameter should be your server and share name. The second parameter should be your mount point in your local filesystem. The parameter after credentials= should be the path to your credentials file. uid=1000 and gid=1000 may look different in your file, but may not, depending on the output of your user id and group id above.

The remainder of the parameters are magic, but are documented in the manpage for mount.cifs. In brief, the important ones are:

  • nofail
  • x-systemd.automount
  • _netdev
  • x-systemd.mountr-timeout=30

nofail means not to fail the boot if the share isn't available. x-systemd.automount is the magic which makes systemd mount the directory upon first use. _netdev tells systemd that this is a remote (network) filesystem. x-systemd.mount-timeout tells systemd to abort the operation if it doesn't complete within 30 seconds, otherwise the command triggering the mount operation will appear to hang forever. In practise, 30 seconds is a long time; the mount operation should succeed a lot quicker than this, use your best skill and judgement to have a timeout value that works for you in failure cases.

Verifying the changed system file

It is quite important to check, having made changes to the really important system file which tells your computer where all its disks should be put in the filesystem, that there aren't any syntax errors in there which will prevent your computer working correctly. The command for this is:

sudo findmnt --verify

This should indicate that everything is fine. If it reports an error, go back to /etc/fstab and correct the issue(s).

systemd housekeeping

Having changed /etc/fstab, you now need to tell systemd that this has happened:

sudo systemctl daemon-reload

will cause systemd to reload all of its configuration, and it will notice that a new mount has appeared. Systemd will - for every mount point defined in /etc/fstab - define a mount target which can be used to manipulate that mount point. In the case of an automount, such as the one you've added, this target is named for the directory in which the remote device is to be mounted, modified to replace / with - and append .automount. For the example above, the directory mount point is /mnt/dave and so the automount target created is mnt-dave.autmount.

Finally mounting the device

This happens by starting the mount target (as named, explained above). This is achieved simply by:

sudo systemctl start mnt-dave.automount

This triggers systemd to monitor the /mnt/dave directory for accesses. If that directory is accessed, systemd will mount the device and let the access continue. As mentioned before, this does slow down the first access to the device, but for subsequent accesses it is as fast as a normal mount, with no slowdown. For normal - i.e. local network devices - operation, this delay is almost imperceptible and isn't a problem.

To trigger the mount, issue the command:

ls /mnt/dave

You have now configured an automounted network device into /mnt/dave (or wherever you really mounted it). I would normally at this point create a symlink to this from a place in my home directory so that it's less awkward to navigate to. This is totally optional though.