Auto-mounting Udrive on Linux2017-05-182018-07-03Richard Ketcham

Mounting UDrive “Single-Sign-On”

Context: ‘UW‘ is the University of Washington, Seattle, WA, USA.  ‘UDrive‘ is a UW brand name for a unit of CIF network storage (a.k.a. a cloud drive) provided to each member of the UW community, identified by her UW NetID.  ‘NetID‘ is the campus-wide network ID assigned to each community member, with associated network authentication services.

 

Elsewhere I described the configuration of Centos 7 with System Security Services Daemon (sssd) to enable logins using UW NetID. With NetID login via kerberos, the users automatically obtain a kerberos Ticket Granting Ticket (TGT) which should allow them to access other resources without further authentication. I explored alternatives for automatically mounting the user’s UDrive using this “single-sign-on” feature of kerberos, but discovered a non-kerberos method using pam_mount in the process.

 

In traditional unix, root privilege is required to mount a file system. A variety of strategies evolved to enable mounting to be initiated by un-privileged users as removable devices became common. These typically involve either an executable with setuid root permission or a daemon with root privileges that services user mount requests.

If the root user calls mount.cifs with the sec=krb5 option on behalf of a NetID user, then that user’s kerberos credentials must be passed (by default the caller’s creds would be used, which is root in this case). This is provided for by the option cruid=$(USER), where $(USER) is the user whose kerberos credentials will be used for the kerberos transactions prerequisite to mounting.

The user’s kerberos ticket must first be locally cached, which can be obtained by “kinit <username>”, but this is unnecessary in our configuration, since the ticket was already obtained at NetID login as shown by klist:

[ketcham@c7-nmr-15 ~]$ klist
Ticket cache: FILE:/tmp/krb5cc_720424681_OtXcyK
Default principal: ketcham@NETID.WASHINGTON.EDU

Valid starting       Expires              Service principal
05/16/2016 22:28:40  05/17/2016 08:28:39  krbtgt/NETID.WASHINGTON.EDU@NETID.WASHINGTON.EDU
    renew until 05/17/2016 08:28:39

If I su to root I can mount UDrive with NetID “ketcham”:

[ketcham@c7-nmr-15 ~]$ su
Password: 
[root@c7-nmr-15 ketcham]# /sbin/mount.cifs  //udrive.uw.edu/udrive /home/netid.washington.edu/ketcham/udrive -ousername=ketcham,sec=krb5,cruid=ketcham


[root@c7-nmr-15 ketcham]# findmnt -t cifs
TARGET                                         SOURCE                  FSTYPE OPTIONS
/home/netid.washington.edu/ketcham/udrive       //udrive.uw.edu/udrive/ cifs   rw,relatime,vers=1.0,sec=krb5,cache=strict,username

So as root we are able to mount the NetID user’s UDrive with the user’s NetID kerberos creds. Then can’t we do the usual unix trick of setting the suid bit on “/sbin/mount.cifs”? No. I set “chmod +s /sbin/mount.cifs”, but mounting as user failed. I dug up this explanation: https://bugzilla.samba.org/show_bug.cgi?id=6853#c23

The makers of mount.cifs added code to detect if it is being run suid and fail. They took this extreme measure in reaction to a well known exploit and the failure of distro packagers to heed their warnings against setting suid. That was cerca 2009 and the major security issues have been fixed. It seems in Centos 7 the suid prohibition has been relaxed but there still remain safety checks. In particular, the following requirement is problematic: Allowing User Mounts: [requires]…an entry for the share in /etc/fstab indicating that a user may unmount it e.g. //server/usersharename /mnt/username cifs user 0 0

To test this, I put this line in my /etc/fstab:

//udrive.uw.edu/udrive  /home/netid.washington.edu/ketcham/udrive cifs user,sec=krb5 0 0

Indeed, after that addition to fstab I was able to mount my UDrive calling mount.cifs as my non-privileged NetID user. However, it would not be feasible to put a separate entry in /etc/fstab for each NetID user’s mount point. Perhaps this could be worked around with some tricky use of soft links, or perhaps through automount. I have not explored those avenues.

If you compile mount.cifs from source, there are flags you can set to configure/unconfigure setuid restrictions. Fully enabling suid on mount.cifs might be an acceptable solution. As I understand, security issues would be of the local user privilege elevation type, and in our setup, we know who our local users are since they are authenticating with their UW NetIDs, and we can restrict them to console logins, that is, disallow network logins.

pam_mount Method

The pam module, pam_mount.so, can provide a variety of mounting tasks at login or session initiation. In my previous article I documented the standard usage of pam_mount to mount the UDrive during NetID login. The pam_mount module is placed first in the pam stack so that pam_mount issues the prompt for the user’s password. As configured in pam_mount.conf.xml, pam_mount calls mount.cifs with the user’s NetID login and password for authentication to the UDrive server, and then pam_mount passes the user’s password down the pam stack to the next module that performs the local login authentication.

This is what the pam_mount documentation calls “single-sign-on”, but it does not involve kerberos. It must happen at the start of the pam login sequence in order to capture the user’s netid password for authentication to the remote file server and then reuse it for login authentication.

I wanted to see if the UDrive can be mounted using our kerberos authentication mechanism instead of password authentication. I worked out an alternate configuration of pam_mount that mounts UDrive with users’ NetID kerberos cached credentials. I move the pam_mount.so module to the end of the session section of the pam files (system-auth, gdm-password and password-auth):

session     optional      pam_mount.so disable_interactive

The “disable_interactive” modifier is necessary to suppress prompting for password. In my modified /etc/security/pam_mount.conf.xml, I override the default mount.cif command options with

<volume fstype="cifs" server="udrive.uw.edu" path="udrive/" mountpoint="~/udrive"
options="username=%(USER),sec=krb5,cruid=%(USERUID),uid=%(USERUID),domain=NETID.WASHINGTON.EDU" >
<not> <uid>0-5000</uid> </not> </volume>

This is essentially the same mount.cifs command that I excecuted from the root command line as described above. “sec=krb5” specifies kerberos auth mechanism and “cruid” points to the user whose cached krb5 ticket to use. I also specify the uid range 0-5000 to exclude root and local account logins from attempting to mount a udrive.

The pam_mount succeeds, after which we see the udrive server service ticket has been added to the user’s kerberos cache:

[ketcham@c7-nmr-15 ~]$ klist
Ticket cache: FILE:/tmp/krb5cc_720424681_1upA9v
Default principal: ketcham@NETID.WASHINGTON.EDU

Valid starting       Expires              Service principal
05/17/2016 14:06:54  05/18/2016 00:06:54  krbtgt/NETID.WASHINGTON.EDU@NETID.WASHINGTON.EDU
    renew until 05/18/2016 14:06:54
05/17/2016 14:06:54  05/18/2016 00:06:54  cifs/udrive.uw.edu@
    renew until 05/18/2016 14:06:54
05/17/2016 14:06:54  05/18/2016 00:06:54  cifs/udrive.uw.edu@NETID.WASHINGTON.EDU
    renew until 05/18/2016 14:06:54

There are no doubt many variations on pam_mount configuration. But I noticed a couple of problems with this pam_mount method.

  1. The user does not have privilege to unmount his udrive.
  2. If the user logs in multiple times, say first with ssh and then through gdm/gnome, his udrive will be mounted multiple times on the same mount point, or more precisely, the subsequent mount is mounted over the previous mount.

Here is an example of multiple over-mounts:

[root@neon ~]# findmnt -t cifs
TARGET SOURCE FSTYPE OPTIONS
/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
└─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
  └─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
    └─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
      └─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
        └─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f
          └─/home/ketcham/udrive //udrive.uw.edu/udrive cifs rw,relatime,vers=1.0,cache=strict,username=ketcham,domain=NETID,uid=654321,f

Pam_mount provides for monitoring and unmounting the udrive when the user logs out, which works in the normal case. However, in case of duplicate mounts pam_mount only unmounts the last one, leaving the previous, underlying mount still mounted after logout. The multiple mounts bug has been reported and an un-official patch is offered here: https://sourceforge.net/p/pam-mount/feature-requests/29/.

I applied the patch and recompiled pam_mount, and installed it on a group’s workstations and it did fix the over-mount problem. We have since had few problems with this method of udrive auto-mounting.

gvfs Method

Gvfs (Gnome Virtual Filesystem) implements userland mounting in the Gnome Desktop environment. In the Gnome Desktop Environment one can access the UDrive from the Gnome filemanager (“Files”, a.k.a. Nautilus) by typing the URL smb://udrive.uw.edu/udrive in “Connect to Servers”. This mounts the udrive with the user’s NetID kerberos credentials (when logged in with NetID). The same can be done from the command line in a shell window by the command:

gvfs-mount smb://udrive.uw.edu/udrive

However, only within the Gnome Desktop Environment. It also may work in other gnome-derived enviroments. (I have tested it in Xfce, and it also works.) This results in mounting the udrive under /run/user/<userid>/gvfs, where “<userid>” represents the numeric uid of the user.

It is reported that gvfs-mount can be made to run without the graphical environment by first starting up the dbus daemon: http://unix.stackexchange.com/questions/44127/samba-mount-with-password-prompt-as-non-root-user

To cause the udrive to be mounted automatically when the user logs in, I create a file /etc/xdg/autostart/udrive.desktop which executes a trivial shell script consisting of:

gvfs-mount smb://udrive.uw.edu/udrive

Optionally, we might add a soft link so that the UDrive appears under the user’s home directory. This method seems to reliably mount the UDrive with user privilege and without the issues seen with mount.cifs and pam_mount. The gvfs mount seems to reliably unmount upon logout or reboot and attempting to mount over an existing mount fails with an error message, as it should:

[ketcham@c7-nmr-15 ~]$ gvfs-mount smb://udrive.uw.edu/udrive
Error mounting location: Location is already mounted

But it does require a gnome session login (or leaving the beaten path to experiment with starting a dbus session from the command line or script).