NFS
Part II, Usage
Ron McCarty
In Part I (Sys Admin, October 2001, http://www.sysadminmag.com/articles/2001/0110/0110h/0110h.htm),
I covered NFS at a high level. This month I will cover the NFS protocol
and daemons in more detail, including examples using Linux Red Hat
6.2 and Solaris 2.6.
NFS Penguin Style
Although the Linux coverage here is based upon Red Hat 6.2, the
kernel version is 2.4.9. Red Hat 6.2 shipped with version 0.1.6
of the nfs-utils package, but the system was also upgraded to nfs-utils
version 0.3.1, the latest available at the time the column was written.
Version 0.3.1 is available at:
http://sourceforge.net/project/shownotes.php?group_id=14&release_id=24211
The nfs-utils contains the NFS executables exportfs, lockd, mountd,
nfsd, nfsstat, nhfsstone, rquotad, showmount, and statd.
Unfortunately for Linux administrators, the NFS support has at
times been downright confusing as support for particular features
and versions have been added with different kernel and nfs-utils
packages. Thankfully, things are getting better for Linux administrators.
Current distributions include the latest kernel support and nfs-utils.
For older production systems, the NFS-HOWTO section 2.4 documents
exactly what is available with each combination, and the nfs-utils
authors are keeping the package backward compatible with earlier
versions but providing "...lots of security and bug fixes."
NFS support must be activated when the kernel is compiled. Additionally,
NFS version 3 support must also be added to the kernel if it's needed.
For distributions supporting linuxconf, NFS services for both
servers and clients are easily configured. Although linuxconf gives
a quick way to set up NFS, what files are being created or edited
are much more important for the administrator to understand when
trouble arises and the NFS configuration needs to be analyzed. Linux
NFS' architecture is loosely based upon the BSD version, so the
support files and programs are easy to find for administrators that
have used the BSD or Sun OS 2.5 or earlier NFS versions.
The /etc/exports file, like BSD's earlier version of /etc/exports/,
defines what file systems are allowed to be accessed by NFS clients.
Additionally, it provides extra management and security features
that give necessary granular control for the administrator. The
file is a text file made up on entries, blank lines, or comment
lines that start with the pound (#) symbol.
Let's assume we would like to allow clients read-only access to
the /home directory on Lefty. The following entry would be
created in /etc/exports:
/home (ro)
At this point, we need to tell the system which directories can be
exported and provided access by the mount daemon, rpc.mountd:
[root@lefty /root]# exportfs -r
exportfs: No host name given with /home (ro), suggest *(ro) to avoid warning
[root@lefty /root]#
When run, The exportfs command warns that the /etc/exports
does not limit access to a particular host and creates the appropriate
entry from the /etc/exports in the /var/lib/nfs/etab,
which can be viewed with:
[root@lefty /root]# cat /var/lib/nfs/etab
/home (ro,async,wdelay,hide,secure,root_squash,no_all_squash,subtree_check,sec
ure_locks,mapping=identity,anonuid=-2,anongid=-2)
The other information listed in the etab includes the defaults
used by NFS. The specifics will be covered shortly. To give access
to the /home directory, the NFS-related daemons need to be
started:
[root@lefty /root]# portmap
[root@lefty /root]# rpc.mountd
[root@lefty /root]# rpc.nfsd
[root@lefty /root]# rpc.statd
[root@lefty /root]# rpc.rquotad
At any point after starting the mount daemon (rpc.mountd),
the specific files that are available for output can be viewed by
looking at the /proc/fs/nfs/exports file:
[root@lefty nfs]# cat /proc/fs/nfs/exports
# Version 1.0
# Path Client(Flags) # IPs
/home 192.168.1.252(ro,root_squash,async,wdelay) # 192.168.1.252
[root@lefty nfs]#
The showmount command with the -e parameter can be used
to view the same information:
[root@lefty /root]# showmount -e
Export list for lefty:
/home (everyone)
[root@lefty /root]#
Although we are jumping ahead here, the showmount can also
be used to determine which systems have mounted file systems, or stated
otherwise, which hosts are NFS clients for the system where the showmount
command is running. showmount -a will show all client mounts:
[root@lefty /root]# showmount -a
All mount points on lefty:
192.168.1.252:/home
[root@lefty /root]#
As mentioned in Part I, most implementations of NFS support the various
versions of NFS. The Linux implementation allows you to limit which
versions of NFS to run by excluding specific versions using the -N
with the mount daemon. For example, to only run NFS version 3, use:
[root@lefty /root]# rpc.mountd -N 1 -N 2
Purists may point out that the Linux version of the NFS daemon (rpc.nfsd)
is listening for version 1 and 2 packets; however, the same effect
is gained as if the protocol was not supported by the NFS daemon,
albeit not as elegant as it should be. This will hopefully be corrected
in a future version, with tighter integration of protocol versions
throughout the package.
Swimming with Penguins
Accessing the exported NFS file systems from the Linux system
"Lefty" configured above will depend on the client operating systems.
Most UNIX-like operating systems will either use similar settings
as the original Sun OS and BSD or the newer Solaris style. Because
I am covering both Linux and Solaris in this article, the client
configuration of Solaris 2.6 will now be covered with the intent
of connecting to the Linux NFS covered above.
Due largely to its inheritance, configuring Solaris 2.6 to act
as an NFS client is straightforward and requires only one command
as root:
# mount -F nfs 192.168.1.254:/home /tmp/tmp2
Assuming a successful mount, the mount command will have an
entry for the mount:
# mount
/ on /dev/dsk/c0t0d0s0 read/write/setuid/largefiles on Mon Sep 3 10:17:56 \
2001
...
...
/tmp/tmp2 on 192.168.1.254:/home read/write/remote on Mon Sep 3 23:19:25 \
2001
Let's examine the tcpdump output on Lefty after the user runs ls
/tmp/tmp2 on Sunny:
[root@lefty rc2.d]# tcpdump host lefty and host sunny -s512
06:07:43.490583 sunny.2191983953 > lefty.mcwrite.n.nfs: 128 getattr \
fh Unknown/1 (DF)
06:07:43.490678 lefty.mcwrite.n.nfs > sunny.2191983953: reply ok 112 \
getattr DIR 40755 ids 0/0 sz 0x000001000 (DF)
06:07:43.491397 sunny.2191983954 > lefty.mcwrite.n.nfs: 132 access \
fh Unknown/10001 (DF)
06:07:43.491463 lefty.mcwrite.n.nfs > sunny.2191983954: reply ok 120
access c0001 (DF)
06:07:43.492296 sunny.2191983955 > lefty.mcwrite.n.nfs: 152 readdirplus \
fh 0,1/16777984 1048 bytes @ 0x000000000 (DF)
06:07:43.492417 lefty.mcwrite.n.nfs > sunny.2191983955: reply ok 1000 \
readdirplus (DF)
We see that Sunny asks for a file handle (fh) for the ls
command and Lefty replies with an OK and returns a directory
structure. Sunny then checks permissions within the directory (132
access fh), and Lefty replies with the permissions. Sunny then
uses the readdirplus to read the complete directory. These
remote procedure calls are covered in RFC 1813 and were summarized
in Part I of this article:
http://www.samag.com/articles/2001/0110/0110h/0110h.htm
Although the command sequence is very simple to access remote file
systems, there are numerous things that can keep the mount from functioning
correctly. Before mounting the directory, the mount point must exist
or be created with a mkdir command. Lack of a local directory
for the mount is typically the only thing that goes wrong on the client
side. Most NFS integration problems are associated with a mismatch
between the client and server or incomplete configuration on the server.
The easiest way to troubleshoot the server problems is from the
server; however, sometimes this is not possible when someone else
administers the server. A quick way to ensure the server has the
appropriate services configured is to use the rpcinfo command
with the -p parameter. From Sunny, the Solaris host, we can
see that the Linux host has the following RPC processes registered:
# rpcinfo -p 192.168.1.254
program vers proto port service
100000 2 tcp 111 rpcbind
100000 2 udp 111 rpcbind
100024 1 udp 692 status
100024 1 tcp 694 status
100005 3 udp 1024 mountd
100005 3 tcp 1024 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100021 1 udp 1026 nlockmgr
100021 3 udp 1026 nlockmgr
100021 4 udp 1026 nlockmgr
#
Note that versions are also listed, which comes in handy should you
have an environment that requires support of multiple NFS protocols.
If a particular daemon is not running, then it must be corrected on
the server. After a mount fails, the rpcinfo -p below shows
that the mountd is not running on the server:
# rpcinfo -p 192.168.1.254
program vers proto port service
100000 2 tcp 111 rpcbind
...
...
100021 4 udp 1026 nlockmgr
#
The rpcinfo can be very useful in ensuring that remote processes
are running. The -p parameter is the most useful, but check
the man page for full coverage of rpcinfo.
Another useful tool is the nfsstat command. The nfsstat
can determine whether clients are actually accessing an export,
as well as reporting statistics by protocol version.
tcpdump can also be quite useful for troubleshooting problems:
[root@lefty /]# tcpdump host lefty and host sunny -s512
tcpdump: listening on eth0
06:29:51.773646 sunny.2191984020 > lefty.mcwrite.n.nfs: 140 lookup \
fh Unknown/1"test.c" (DF)
06:29:51.773819 lefty.mcwrite.n.nfs > sunny.2191984020: reply ok 116
lookup ERROR: No such file or directory (DF)
06:29:51.774593 sunny.2191984021 > lefty.mcwrite.n.nfs: 128 getattr \
fh Unknown/1 (DF)
06:29:51.774670 lefty.mcwrite.n.nfs > sunny.2191984021: reply ok 112 \
getattr DIR 40755 ids 0/0 sz 0x000001000 (DF)
06:29:51.775289 sunny.2191984022 > lefty.mcwrite.n.nfs: 140 lookup \
fh Unknown/1"test.c" (DF)
06:29:51.775357 lefty.mcwrite.n.nfs > sunny.2191984022: reply ok 116 \
lookup ERROR: No such file or directory (DF)
06:29:51.776029 sunny.2191984023 > lefty.mcwrite.n.nfs: 184 create \
fh Unknown/1 "test.c" (DF)
06:29:51.776169 lefty.mcwrite.n.nfs > sunny.2191984023: reply ok 120 \
create ERROR: Permission denied (DF)
In the above output from touch test.c, the touch command
tried to access a file by the name of test.c, then it looked
for a directory by the same name. After failing both tests, it then
tried to create test.c, which also fails.
Once the file system is mounted, the most common errors relate
to common UNIX access rights. The use of common uid or Sun's NIS+
can help ensure permissions are implemented globally across file
systems. Some administrators are tempted to "open" directories through
the use of giving world-read permissions; however, this should be
avoided for security reasons. Even ignoring the security implications,
this methodology is a management nightmare because processes or
users seldom create data as world readable.
The root user is given special treatment within NFS mounts. To
avoid the limitless possibilities afforded the super user, root
user requests are treated as if they come from the user "nobody",
which effectively restricts root access to world-readable and write-enabled
files. To add additional security to your NFS implementation, refer
to the "Security Measures and Resources" sidebar.
Solaris NFS Server
Configuring Solaris to run as an NFS server is as straightforward
as the Linux version; however, the commands and file locations are
a bit different. Solaris automatically starts the NFS services and
exports all file systems when run level 3 is reached at boot up.
To manually start the processes, use:
#/usr/lib/nfs/mountd
To start the mount daemon, and to start the NFS server, use:
#/usr/lib/nfs/nfsd
With Solaris 2.6, Solaris no longer uses an export file to identify
the file systems to be exported. Rather, the files are exported using
the share command. Assuming we want to allow remote hosts to
mount /export/home, use the following command run as root:
share -F nfs /export/home
(See the sidebar for the -o parameter to create limitations
with the share command.)
Once the share command is executed to export the file system,
a list of exported shares can be seen with the share command
with no parameters:
# share
- /export/home rw ""
An exported file system can also be removed from export status with
the unshare command:
# unshare -F nfs /export/home
Solaris stores the information concerning NFS in the /etc/dfs
directory. The /etc/dfs/sharetab contains the exported file
systems and is where the share command without parameters gets
its information.
The /etc/dfs/dfstab contains a list of share commands that
are executed during bootup. To have /export/home automatically
exported, the aforementioned share command share -F nfs
/export/home would be added to /etc/dfs/dfstab.
An additional useful command for exporting file systems is the
shareall command. shareall proves most useful when
executed without any parameters, which causes it to execute all
the share commands in the /etc/dfs/dfstab. unshareall
can be used to remove all exported file systems from their export
status.
We Return to Penguin Broadcasting Corporation
Using Linux client NFS capabilities was not presented earlier
in the Linux section to follow the normal flow of exporting a file
system and then mounting it from the client. But to complete the
circle, here is the procedure to mount the exported Solaris file
system.
Mounting an exported system on Linux is straightforward and similar
to the Solaris version with the noticeable exception that -t
as opposed to -F is used to identify the file system type:
[root@lefty /root]# mount -t nfs sunny:/export/home /tmp/tmp2
The status of the mounted file system can then be viewed with the
mount command:
[root@lefty /root]# mount
/dev/hda1 on / type ext2 (rw)
none on /proc type proc (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
sunny:/export/home on /tmp/tmp2 type nfs (rw,addr=192.168.1.252)
Just the Beginning
The Network File System can be used for diskless workstations,
applications, or simple user storage. Whatever the use, I've covered
the basics to get you pointed in the right direction. Enjoy.
Ronald McCarty received his bachelor's degree in Computer and
Information Systems at the University of Maryland's international
campus at Schwaebisch Gmuend, Germany. He works for Sonus Networks
as a senior systems engineer on a customer team responsible for
a major telecommunications carrier. Ronald is co-author New Rider's
Linux Routing (http://www.linuxroutingbook.com/).
He spends his free time with his two best friends in the world:
his daughter, Janice, and his wife, Claudia. He can be reached at:
ronald.mccarty@gte.net.
|