As I mentioned in my last post, I just built out a dedicated server at home, and I'm migrating a bunch of services to it. One reason I build this server in the first place was so that I could set up roaming home directories for all my Linux PCs in the house.
I tried a few configurations before landing on the one described here. I had problems where Ubuntu 12.04 would fail to boot if the system failed to mount the network drive properly when the mount was in the fstab
. Ubuntu 10.04 would error on boot, but give you the opportunity to skip the mount and continue booting. However, if the share was mounted to /home
on the client machine, logging into a desktop environment would fail on account of none of the config files being available. Even when the mount worked properly, having it mounted at /home
caused performance problems. Relying on the network for processes like booting and logging into a desktop ended up being a deal-breaker for me having automounted network home directories.
But I did settle on a solution that works well. In brief, I servicized the mounting and unmounting of the network drive, and the control script I wrote for it also places netdrive
symbolic links in each non-system user's home directory if a directory on the share exists in their name. Here's how it's done.
There are two parts to this configuration - a server and some clients. Let's set up the server.
My server is running Debian Squeeze, but these instructions should translate well to other distributions. First, install the NFS server:
sudo apt-get install nfs-kernel-server
Then set the config to share the /home
directory over the network. Add this to the end of /etc/exports
:
/home 192.168.0.0/255.255.255.0(rw,sync,fsid=0,no_subtree_check)
You should modify that to suit your specific needs. /home
is the directory on the server to share. 192.168.0.0/255.255.255.0
means that the only systems who are allowed to access it will be on the 192.168.0.x
subnet, which, for me, means everything behind my router. This share won't be accessible to anyone on the public side of my router. Finally, the (rw,sync,fsid=0,no_subtree_check)
part are options that say, respectively, "Mount it read/write so users can save files here," "Write files to disk synchronously so there aren't sudden unmounting problems," "If the NFS server is NFS4, treat this directory as the root of all shared directories," and "Speed things up by allowing all subdirectories of the share to be accessed."
Restart the NFS server:
sudo service nfs-kernel-server restart
If you encounter problems, check /var/log/daemon.log
for something to Google with.
I had firewall problems here. Mounting an NFS share on a remote server uses lots of different ports, and I was unable to identify them all. I ended up adding a rule to my firewall to let anything behind my router (that 192.168.0.x
subnet) access any ports on the server. For me, this isn't a security issue. You should consider your situation and make that decision for yourself. At any rate, here's my command to make that firewall rule:
sudo ufw allow from 192.168.0.0/24 to any
Now get onto a client machine and try to mount it manually just to be sure it works:
sudo mount -t nfs -o proto=tcp,port=2049 192.168.0.100:/home /mnt
If you get no errors, try...
ls /mnt
...and check if what you see is what you expect. If so, unmount it:
sudo umount /mnt
Assuming that everything works, it's time to set up a control script. The script below is hardcoded to mount the NFS share to /mnt/netdrive
. You should probably read through it and understand it before running it to be sure it won't interfere with things on your system. If it's going to work for you, paste it into /etc/init.d/netdrive
or wherever else you decide.
safe_start () {
if [ ! -d /mnt/netdrive ]; then
mkdir /mnt/netdrive
fi
if grep -qs '/mnt/netdrive' /proc/mounts; then
echo "Something is already mounted at /mnt/netdrive [ FAIL ]"
exit 1
else
mount -t nfs -o proto=tcp,port=2049 192.168.0.100:/home /mnt/netdrive
fi
for u in `grep '/home' /etc/passwd | cut -d: -f1`; do
if [ -d /mnt/netdrive/$u ]; then
HOME=`grep "$u" /etc/passwd | cut -d: -f6`
if [ -e $HOME/netdrive ]; then
rm $HOME/netdrive
fi
ln -s /mnt/netdrive/$u $HOME/netdrive
fi
done
}
safe_unmount () {
FILES_IN_USE=`lsof | grep '/mnt/netdrive' | awk '{print $9}'`
if [ ! "$FILES_IN_USE" = "" ]; then
echo "The following files are located on the netdrive and are still in use:"
echo $FILES_IN_USE
exit 1
fi
unmount
}
unmount () {
umount /mnt/netdrive
for u in `ls /home`; do
if [ -d /home/$u/netdrive ]; then
rm $u/netdrive;
fi
done
}
show_status () {
if grep -qs '/mnt/netdrive' /proc/mounts; then
echo "Netdrive is mounted."
else
echo "Netdrive is not mounted."
fi
}
show_help () {
echo "This script accepts the following commands: start, stop, forcestop, status, help"
}
case $1 in
"start" )
safe_start ;;
"stop" )
safe_unmount ;;
"forcestop" )
unmount ;;
"status" )
show_status ;;
* )
show_help ;;
esac
exit 0
Apply permissions:
sudo chmod 755 /etc/init.d/netdrive
Now you can run...
sudo /etc/init.d/netdrive start
...to mount it, or give it stop
instead to stop it safely. The script will refuse to unmount the drive if it has files open still. If you want to override that check, use forcestop
. status
will tell you if the network drive is mounted or not. help
will give you a basic usage message. When mounting, this script will also place the netdrive
symlink in users' home directories, so, for example, /home/ryan/netdrive
is mapped to /mnt/netdrive/ryan
.
Now, I still wanted my drive to mount on boot. So I threw a symlink in the startup:
sudo ln -s /etc/init.d/netdrive /etc/rc2.d/S10netdrive
That's my Ubuntu 12.04 machine. I can't remember at what point in the startup procedure I placed in on my Ubuntu 10.04 box, but it's somewhat discretionary anyway.
So reboot your client and make sure you boot with a working netdrive
symlink in your home directory. And done!