Kroon Information Systems
       
    
Howto: CIFS + pam_mount

Last updated 5 July 2012

Background

The more traditional way of setting up distributed UNIX/Linux labs has always been to use NFS+NIS, possibly NIS+. Sometimes ldap and or kerberos also gets chucked into the equation.

This has several drawbacks, the biggest being that NFS uses the hosts IP address for authentication, thus should host gets compromised and a cracker obtain root on such a host, your entire root exported file system is compromised.

In this howto the author will attempt to provide an alternative method for mounting user's home directories, that is slightly slower, butmuch more secure in the sense that authentication is user based. Yes kerberized NFS (NFSv4) can give us this, but on Linux at least, NFSv4 is still highly experimental at the time of writing.

Samba

Recently Samba3 has been released. The samba project can be found at http://www.samba.org. The samba project aims to provide a mapping between UNIX file permissions and windows file permissions, with the orriginal intent of allowing UNIX workstations to share files for Windows work stations. Very quickly, I think, people realised the potential power of Samba, so UNIX extensions were built, allowing for symbolic links, unix file permissions, ownership and groups, making a Samba export look excactly like a unix file system to the end user.

The way samba works we need to have a username and password to mount each share. Samba also exports each home directory on a per-user basis. Meaning there is a share for each users home directory. For example, on my system (pug) I have three users, fred, foo and bob. If I then have a [homes] section, as described in the smb.conf(5) man page then my system would have the following shares:

//pug/fred
//pug/foo
//pug/bar

For fred to access //pug/fred, he needs to supply his credentials, fred being his username and his password, whatever that may be. This can be done using smbmount as a normal user, or using mount with -t smbfs as root.

The unix extensions is part of the CIFS standard. In order to use CIFS we need to use mount.cifs instead, or mount with -t cifs. This will automatically use unix extensions if available.

Samba automatically swithces on unix extensions, but I like doing things explicitly (makes it easier to spot problems). So add "unix extensions = yes" to /etc/samba/smb.conf in the [globals] section.

pam_mount

Pluggable Authentication Modules (PAM) is a very powerfull feature of GNU/Linux. It allows a system administrator to plug in authentication modules at will, allowing to use practically anything as authentication, and to perform a various actions at login. In this case we will be using pam_mount to create a user's home directory, and then to mount his samba exported home directory upon that directory during login. pam_mount automatically detects whether it has already been mounted, and automatically umounts it when the user's last session ends (ie, upon logging out).

Minimum requirements

I may be wrong on one or two of these, but I suspect you need at least the following:

  • Kernel with CIFS support (2.6.x Linux kernel).
  • Samba3.
  • pam_mount (Any version should work, I'm using 0.9.9).

The architecture

I'm not going to bother too much with this, basically we have a server, I'll call it pug for the purpose of this discussion, and some client, which I'll call lab for the purpose of this discussion. The idea is to have an export on pug that contains the home directories for all our users. [homes] works very nicely for this as each users home directory is then available as //pug/${USER}, and only ${USER}, with the correct password has access to that.

I assume that each users home directory is /home/${USER}. I don't know how to make pam_mount handle a more complicated case. For example in some of our labs we have undergrad and postgrad students, along with admins where we then have undergrad students in /home/students/undergrad, postgrads in /home/students/postgrad and the admins are in /home/admin. I hope I'm wrong but I don't see how to handle that with pam_mount.

Configuring PAM

This may well be the hardest part. Seriously. You need to edit some files in /etc/pam.d, in my case I edited the login and kde. We are allowing logins on the console and using kdm (part of kde). You probably also want to get hold of gdm if you are using gdm (my personal preference but I'm not the only person who has a say as to what happens in the labs), or xdm.

You need to add two lines to each of these, one for auth (not sure excactly why this is needed, I suspect pam_mount mounts the home directory at this point) and for session (to actually perform mounting and umounting of shares).

auth       optional /lib/security/pam_mount.so use_first_pass

This line should probably be the last of your auth lines. I'm not sure whether it is actually here that the mounting happen or whether the password only gets cached. Either way, it is required, so put it in.

session    optional     /lib/security/pam_mount.so

Lets pam_mount knows when a sessions starts and when a session ends, this allows pam_mount to also umount home directories when a user logs out.

After adding these lines my /etc/pam.d/login file looks like:

#%PAM-1.0

auth       required    /lib/security/pam_securetty.so
auth       required    /lib/security/pam_stack.so service=system-auth
auth       required    /lib/security/pam_nologin.so
auth       optional    /lib/security/pam_mount.so use_first_pass

account    required    /lib/security/pam_stack.so service=system-auth

password   required    /lib/security/pam_stack.so service=system-auth

session    required    /lib/security/pam_stack.so service=system-auth
session    optional    /lib/security/pam_console.so
session    optional    /lib/security/pam_mount.so

This is sufficient for pam_mount to work.

pam_mount.conf

The first thing to note is that pam_mount does not have internal support for CIFS. I just picked the next closest (smbfs) and hacked the config file to use CIFS instead. Below I will explain how I did this. The config file we want to edit is /etc/security/pam_mount.conf.

Hacking CIFS support into pam_mount via the config file

This is actually much simpler than it would initially appear. Look for a line such as:

smbmount /bin/mount -t smbfs

and replace it with:

smbmount /bin/mount -t cifs

or

smbmount /usr/bin/mount.cifs

One thing to note is that for the first option to work /sbin/mount.cifs must exist and work properly. In the first case mount.cifs might also be installed elsewhere. Either one of these two should work, I have opted for the econd as my distribution (Gentoo Linux) has not installed /sbin/mount.cifs when orriginally testing this and I did not yet know how to make mount -t cifs work.

Creating a volume line for home directories

The only thing that remain is to make pam_mount actually mount something. This is also easier than falling out of a tree. Simply add a line such as

volume * smb pug & /home/& uid=& - -

Replace pug with the name of your server. The uid=& part is not really needed but due to some bug in pam_mount I couldn't get things working with a - (meaning no options) in that field.

Testing

At this point everything should work

I would suspect that by now you probably already tested this. If you can log in on the client then everything should be ok. I suggest having a root console open on tty1 and then logging in and out on other consoles as various users, executing mount after each action to see what is mounted and to see if it acts as expected.

Things to note

  • The users UNIX password and his SAMBA password should match. It may actually be advisable to use pam_smb for user authentication which will enforce this password "synchronisation".
  • KDM doesn't always play nice - it tries to read stuff from the users home directory before the user has provided a password. I recommend using GDM - although I haven't checked yet whether it does the same thing or not.
  • A users ID on the client and the server should match. So should his primary group. I recommend using NIS or LDap to export this information on the server and import it on the client. When using NIS, make sure that you don't export even the hashed passwords, when using LDap, it is possible to authenticate both the client and the server, even though a previous root compromise on the client may leave your users vulnerable (but this cannot be avoided).
  • As far as I know there is no way to to have a non-flat /home structure. If there was it would have been very cool for our situation where I have different "types" of users such as staff, students, techteam and others, then staff could've gone under /home/staff/??, students under /home/students/?? and techteam members under /home/techteam/?? and these could then be handled differently by other system processes. For example, I could run our quota checking system only in /home/students.

I am personally trying to get a setup going where I want to use pam_mount along with CIFS (like explained above). This I have achieved. Samba should store its user information inside an LDap tree (This I have got working under experimental conditions). User information should be exported to client machines using LDap + nss_ldap (Theory only at this point). Then I'm either going to get kerberos going along with ldap authentication of some sorts (still thinking about this one), or I'm going to use pam_smb for authentication. Using all this together should give us a much more secure solution than NIS along with NFS.