NFS Tutorial

So you want to get your Linux machines talking to each other? There are a number of ways that you can do this but since this article is on NFS, I suppose I will talk about that. I am going to cover what you need to do to share a directory via NFS and to connect to it from another computer.

I am assuming that the systems you are starting on are bare systems. If you have a previous installation of NFS, it won’t hurt, just skip the part where I tell you to install stuff.

Setting up the server:
This is where the files are that you want to access. It could be a big main server somewhere or another workstation across the room. It doesn’t matter which, since most distro’s package the NFS utilities for client and server together, any computer can act as both client and server.

All the necessary files usually come in either one nice package or two depending on where you get them from. You can usually get all the programs you need by installing theses two packages.
– nfs-utils
– nfs-utils-clients
Not everyone will need both packages however. Gentoo for instance packages everything you will need into ‘nfs-utils’. While other RPM based distro’s split up the various functionality into seperate packages. I usually find myself needing the client programs on the server from time to time so I install them also if I have the option. Make sure you check to see what is included in what you are installing.

So now would be the time to install the respective packages for your distro. Go ahead, I’ll wait. Alright, I’m done waiting. Before you go ahead and fire up you new NFS server you might want to take some time now and modify the configuration file for NFS. Oh wait! There isn’t one! No seriously, its really that easy. BUT! Before you can go around touting your new found NFS genius there are a couple of things you might want to do fist.

There are 3 main files that NFS looks to for granting or denying access to your computer. Alright, these 3 files could be akin to what you might consider configuration files for NFS, but that might be stretchin’ it. Here are the 3 files that you are going to be editing:
– /etc/hosts.allow
– /etc/hosts.deny
– /etc/exports

Hosts.allow and hosts.deny control access to services on your machine. When the server gets a request from a machine is does the following:
1st) – It checks hosts.allow, if the request matches a description there, the remote request is granted access.
2nd) – It checks host.deny, fie the request matches a description there, the remote request is denied access.
3rd) – If the request matches nothing in either files, it is granted access.

The order of this check is important, you will see why.

Right, now break out your favorite text editor and lets get started, remember, you will need to be root to edit these files. First up, ‘hosts.allow’. Now you can get down-right paranoid with this file, if you really want to lord over everything that happens on this computer, but we are just going to talk about the basics for now. OK, do you have /etc/hosts.allow open in a text editor? No!? What are you waiting for!? Schneller! Schneller!!

Here are a few quick rules for editing these files:
– A newline character is ignored when it is preceded by a backslash character. This permits you to break up long lines so that they are easier to edit.
– Blank lines or lines that begin with a `#’ character are ignored. This permits you to insert comments and whitespace so that the tables are easier to read.
– Since I use DHCP, I like to let anyone on my local network access my shares. Here is the entry in my hosts.allow that does this:

ALL: 192.168.1.*

Please understand that this is not the safest method, since it will allow ANYONE with an internal IP access to your shares. But since we are more interested in getting NFS working first, we can forgo security until we get everything up and running. After you get it working, you can go
back an begin tweaking the settings to provide more security. For instance you can provide per-service access in your hosts.allow by specifying each service and address explicitly.

portmap:  192.168.1.104, 192.168.1.105
lockd:	  192.168.1.104, 192.168.1.105
rquotad:  192.168.1.104, 192.168.1.105 
mountd:   192.168.1.104, 192.168.1.105
statd:	  192.168.1.104, 192.168.1.105

Now on to the ‘hosts.deny’ file. Again, this can be relatively simple or complex based on the amount of control you want over your machine. For me, unless I explicitly enable access I want the request denied. Here is my hosts.deny:

ALL:ALL

Remember the sequence of checking outlined above? Unless a request matches a service and address in the hosts.allow, it will be denied access because ALL:ALL denies all services and all addresses. If you ever add a service to the server you have to be sure to add it to the hosts.allow or else any requests will be denied if you use ALL:ALL in your hosts.deny.

Last file! Open up /etc/exports, its time to define what people can access. Entries in here follow the syntax ‘directory address(option,option)’, one per line. Lets take a look at mine:

/mnt/share	  *(rw,no_root_squash,sync) 192.168.1.105(ro) 
/var/ftp	  *(rw,no_root_squash,sync)
/home/jeffrey/tmp 192.168.1.104(ro,all_squash,sync)

The first entry is the directory you want to share. All directories under this directory will be share as well. Next are the addresses that have access to this share. I put an (*) for this entry, I am giving everyone access since I already weeded out most undesirables during the hosts.allow checking. You can specify machine DNS names here also, like machine.domain.com. Or, like the last entry, I am only giving access to a specific IP with a rather restrictive set of permissions.

The options for each share require a bit more explanation. Here are some of the available options:
ro – The share is read only. No one will be able to write to it. This is the default setting.
rw – The share is read write. Write access is granted.
no_root_squash – If this option is selected, then root on the remote machine will have the same access rights as the root on the server. Needless to say this can have serious security implications.
all_squash – Map all requests to the anonymous user (UID) and group (GID) ID. The default setting is ‘no_all_squash’.

‘man exports’ will give you all of the options.

Now you will need to get the proper services running. You will need to start the following services:
rpc.portmap
rpc.nfsd
rpc.mountd
rpc.statd
rpc.lockd
rpc.rquotad < --only needed if you have file quotas Or, if you are if you have the System V init scripts, just issue the command:

service nfs start

Check to see if everything is running by querying the portmapper with the command:

rpcinfo -p

You should get a listing along the lines of:

   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp    999  status
    100024    1   tcp   1002  status
    391002    2   tcp  32768  sgi_fam
    100003    2   udp   2049  nfs
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100003    2   tcp   2049  nfs
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100021    1   udp  33790  nlockmgr
    100021    3   udp  33790  nlockmgr
    100021    4   udp  33790  nlockmgr
    100021    1   tcp  37488  nlockmgr
    100021    3   tcp  37488  nlockmgr
    100021    4   tcp  37488  nlockmgr
    100005    1   udp    671  mountd
    100005    1   tcp    674  mountd
    100005    2   udp    671  mountd
    100005    2   tcp    674  mountd
    100005    3   udp    671  mountd
    100005    3   tcp    674  mountd

See that? Good, you done! The server is set up and ready to accept connections from the client.

Setting up the client:
Before starting to set up the NFS client programs you need to be sure your installed mount program is new enough to support mounting network filesystems. Just issue:

mount --version

If the version is older than 2.10m you will need to upgrade. Second you will need to double-check that your kernel supports NFS mounting. Run the following command to check: ‘lsmod | grep nfs’. This should return something along the lines of:

nfsd                  189408  8
exportfs                4736  1 nfsd
lockd                  58344  2 nfsd

If not, there is the possibility that NFS support is statically compiled into you kernel. You can check this with ‘less /boot/config | grep NFS’ hopefully you get:

CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_NCPFS_NFS_NS=y

Otherwise, you probably compiled your kernel yourself and didn’t include any form of NFS support. A quick reconfig, recompile, and restart will fix that.

Setting up the client is far easier than the server. Essentially all the needs to be done is ensure that all the same packages are installed on the client as are on the server. You do remember what packages are installed on the server right? If not, check out the first paragraph in ‘Setting up the Server’, that should fill you in.

Now that you have everything installed on the client. You will need to actually start those services. Since you are only going to be using the client as a, well, client, you won’t need ALL the same services running here as on the server. The only ones you will need running are:
– portmap
– rpc.lockd
– rpc.statd

Alright, everything installed and running? Good your done, go to the next section.

Connecting to the server:
In order to mount filesystems you need root access, so go ahead and drop to a root shell now.

Server set up? Check. Client set up? Check. Good. Now lets check to make sure we can see the shares on the server from the client. In order to mount filesystems you need root access, so go ahead and drop to a root shell now. Now issue the command:

showmount -e server.name.or.IP

Remember the share I defined for my server in the “Setting up the Server” section? Here is what the previous command displayed for me:

Export list for blackbox:
/home/jeffrey/tmp *
/var/ftp          (everyone)
/mnt/share      (everyone)

Are you able to see the shares you set up on the server? If not, you most likely don’t have the permissions correct for the client you are running, or not all the correct services are started on the either the client or the server.

With postmap, lockd, and statd running you should be able to mount the NFS shares like you would a hard drive, with the mount command. So lets try:

mount -t nfs blackbox:/var/ftp /mnt/ftp

This is assuming that you have a created the empty directory /mnt/ftp beforehand.

If everything works correctly you should be able to cd to that directory and see the content of your share, congratulations!

You can unmount the directory as if were any other device:

umount /mnt/ftp

Connecting to the server on start-up
Now I suppose you don’t want to have to issue the mount command every time you reboot, which probably isn’t often, your running Linux afterall. So it would probably be a good idea to add an entry to your fstab, so the share is mounted automatically on boot. To do this for the entry above use the follwing entry in your /et/fstab file:

blackbox:/var/ftp	/mnt/ftp       nfs         rw           0    0

You should check out the man page on fstab if you are unfamiliar with the syntax.

Alright, thats it. Have fun sharing files. One last thing to mention, however. If you need to restart the server for any reason. You are going to need to unmount any share on client computers before you restart. NFS gets really weird when a server restarts and the share is still mounted. Usually I find I have to just restart the client too if I forget to unmount the shares. I have been searching for a resolution to this issue but it seems that the only response I have gotten is, ‘don’t restart the server’ or ‘unmount before the restart’. It appears to be a kernel level issue, and I haven’t seen a fix on the horizon. If anyone has an idea how to get around this I would be most greatful to hear it.