You are on page 1of 10

NFS Servers

Discussion

NFS Mounted Directories

The Network File System (commonly called just "NFS") allows multiple networked
Linux (and Unix) machines to share a common directory. The directory must physically
reside on one machine, which is referred to as the NFS server. Any Red Hat Enterprise
Linux machine may be configured to act as a NFS server by exporting any "normal"
directory via NFS.

In the following diagram, the machine server1 has chosen to export its /var/ftp/pub
directory, which contains the subdirectories RedHat and images (and their contents,
which are not pictured), as well as the regular file README.

Figure 1. NFS Server and Client (Before NFS Mount)

Any Red Hat Enterprise Linux machine may also act as an NFS client, by mounting the
NFS exported directory to an already existing directory on the client. The client side of
NFS is implemented almost entirely as a filesystem in the kernel, so little client
configuration is required. In the following diagram, the machine station7 has mounted
server1's exported NFS directory to its already existing directory /mnt/pub, using a
command such as the following.

[root@station ~]# mount server1:/var/ftp/pub /mnt/pub

Figure 2. NFS Server and Client (After NFS Mount)


After the NFS mount has been established, for all practical purposes, the /mnt/pub
directory on the client appears to contain all of the files contained in the exported
directory, namely the directories RedHat and images and the regular file README. In
reality, the files do not exist on the NFS client (station7), but they may be examined and
edited just as if they did.

In this workbook, we will examine how to configure a Red Hat Enterprise Linux
machine to be a NFS server, discussing how to install, start, and configure the service.

Installing the NFS Server: nfs-utils (and portmap)

The NFS server requires several daemons and command line utilities, which are
provided by the nfs-utils package file. The NFS server also relies on the underlying
RPC mechanism, which is provided by the portmap package. Both packages were
probably installed by default.

Multiple daemons are required to run the NFS server, all of which are fortunately
managed by the single <service>nfs</service> service. In order to start the service, the
underlying <service>portmap</service> service should also be running. Both services
can be started and enabled using the standard service and chkconfig sequence.

[root@station ~]# service portmap start


Starting portmap: [ OK ]
[root@station ~]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS daemon: [ OK ]
Starting NFS mountd: [ OK ]
[root@station ~]# chkconfig nfs on
[root@station ~]# chkconfig portmap on

Exporting Directories: /etc/exports and exportfs

The NFS server uses the line based /etc/exports configuration file to define exported
directories. Although no default or sample configuration file is provided, the syntax is
simple enough to create from scratch. An example configuration file is provided below.

/var/ftp/pub 192.168.0.0/255.255.255.0(ro,async)
/media/usbdrive 192.168.0.0/24(ro,async)
/scratch 192.168.0.0/255.255.255.0(rw,sync) *(ro,async)

The first token on a line is the directory to export. Subsequent tokens define clients
allowed to import (mount) the directory coupled with options which apply to those
clients. If not specified, directories are exported to everyone by default.

Allowed clients may be specified using any of the following techniques.

Table 1. /etc/exports Syntax: Clients

Format Example
IP address 192.168.0.1
Format Example
Subnet (netmask notation) 192.168.0.0/255.255.255.0
Subnet (CIDR notation) 192.168.0.0/24
domain name *.example.com

Multiple whitespace separated clients can be specified for a single exported directory.
The /etc/exports file is unique in supporting the pathname expansion ("file
globbing") style wildcard ("*") as a way to match hostnames. Don't try to get away with
using that syntax in other contexts!

Export options follow client specifications, enclosed in parentheses. There should be no


spaces between the client syntax and the parentheses, nor should there be spaces
between comma separated options within the parentheses.

The following table contains some commonly used export options.

Table 2. /etc/exports: Export Options

Option Effect
<directive>ro</directive> or Clients have read-only (default) or read-write
<directive>rw</directive> access.
For synchronous exports (the default), the
NFS server waits until changes have been
<directive>sync</directive> or
committed to disk before responding to the
<directive>async</directive>
client, sacrificing reliability for speed. For
asynchronous exports it does not.
By default, the NFS server will delay
committing a write if it anticipates a
consecutive follow up request, in hopes of
<directive>wdelay</directive> or combining the requests to improve
<directive>no_wdelay</directive> performance. If writes are generally non-
sequential, this strategy can backfire, so the
<directive>no_delay</directive> option can
be used to disable it.
By default, the root account with uid 0 on the
client is remapped ("squashed") to uid 65534.
<directive>root_squash</directive> or [a]
If root on the client is trusted, this prudent
<directive>no_root_squash</directive>
behavior can be disabled with
<directive>no_root_squash</directive>.
[a]
When user id's were 16 bit integers, the uid "-2" was chosen as the anonymous (root
squash) id, which translated in two's complement to 65534. Now that user id's are 32 bit
integers, the choice of 65534 is merely anachronistic and awkward convention.

Synchronizing Exports: exportfs


Whenever the /etc/exports file has been edited, the NFS server needs to be notified.
Traditionally, an administrator would simply restart the daemon. Although possible, the
NFS servers tend to be sluggish, and take a while to shutdown and restart. Although the
<service>nfs</service> service script, like all service scripts, provides a restart
command, it tends to not allow enough time between the stop half and the start half
of the restart. When restarting the server, it's better to invoke the stop and start
commands directly.

[root@station ~]# service nfs stop


Shutting down NFS mountd: [ OK ]
Shutting down NFS daemon: [ OK ]
Shutting down NFS quotas: [ OK ]
Shutting down NFS services: [ OK ]
[root@station ~]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS daemon: [ OK ]
Starting NFS mountd: [ OK ]

Better yet, however, is to not restart the daemons at all, and instead use the exportfs
command. The exportfs command is used to maintain the NFS server's internal export
table. Called without arguments, the command simply displays the internal table.

[root@station ~]# exportfs


/media/usbdrive
192.168.0.0/24
/var/ftp/pub 192.168.0.0/255.255.255.0
/scratch 192.168.0.0/255.255.255.0
/scratch <world>

The -v command line switch (for "verbose") adds the current options, as well.

[root@station ~]# exportfs -v


/media/usbdrive
192.168.0.0/24(ro,async,wdelay,root_squash)
/var/ftp/pub 192.168.0.0/255.255.255.0(ro,async,wdelay,root_squash)
/scratch 192.168.0.0/255.255.255.0(rw,wdelay,root_squash)
/scratch <world>(ro,async,wdelay,root_squash)

And lastly, the -r command line switch causes the internal export table to be
synchronized with the current /etc/exports file, without comment.

[root@station ~]# exportfs -r

As an example, assume that an administrator decided that exporting the /media/usb


directory should be exported read-write and synchronous, instead of read-only and
asynchronous. The changes are made to the /etc/exports file, re-synced with
exportfs -r, and confirmed with exportfs -v.

[root@station ~]# exportfs -v


/media/usbdrive
192.168.0.0/24(ro,async,wdelay,root_squash)
/var/ftp/pub 192.168.0.0/255.255.255.0(ro,async,wdelay,root_squash)
/scratch 192.168.0.0/255.255.255.0(rw,wdelay,root_squash)
/scratch <world>(ro,async,wdelay,root_squash)
[root@station ~]# cat /etc/exports
/var/ftp/pub 192.168.0.0/255.255.255.0(ro,async)
/media/usbdrive 192.168.0.0/24(rw,sync)
/scratch 192.168.0.0/255.255.255.0(rw,sync) *(ro,async)
[root@station ~]# exportfs -r
[root@station ~]# exportfs -v
/media/usbdrive
192.168.0.0/24(rw,wdelay,root_squash)
/var/ftp/pub 192.168.0.0/255.255.255.0(ro,async,wdelay,root_squash)
/scratch 192.168.0.0/255.255.255.0(rw,wdelay,root_squash)
/scratch <world>(ro,async,wdelay,root_squash)
The /media/usbdrive is currently exported with the <directive>ro</directive>
and <directive>async</directive> options.
In the meantime, an administrator has edited the /etc/exports file, changing the
options from <directive>ro,async</directive> to <directive>rw,sync</directive>.
The exportfs command is used to ask the NFS server to re-sync its internal export
table.
She then confirms the changes. As a quirk, the <directive>sync</directive> option,
which is the default, is not displayed, but the complementary
<directive>async</directive> option is conspicuously absent.

Since having a consistent technique for reloading the configuration of a service is often
helpful, it should be noted that service nfs reload (as opposed to restart) simply runs
exportfs -r. Thus, any of the above examples could also use it.

Exercises

Lab Exercise
Objective: Placeholder Lab

Estimated Time: 10 mins.

Configuring NFS

This exercise will have you share the directory /var/shared/private from your server
to the 192.168.0.0/24 network via NFS. Being private it should not be accessible by any
other networks. Since an important best-practice for any file-sharing service is to never
grant more access than your users need, it will be shared read-only as well. Since write
access is turned off, we'll make things a little more interesting by being more liberal
than normal with root-level access and turning off root-squashing. Once again, though,
in real life this wouldn't be done without a demonstrated need.

1. Create the directory with mkdir -p /var/shared/private.


2. Open /etc/exports and add a line like the following to include
/var/shared/private with the appropriate options in your server's exports list:

/var/shared/private 192.168.0.0/255.255.255.0(ro,no_root_squash)

Note that "ro" is set by default, so technically it can be left out.


3. Reload the NFS exports list with exportfs -r or service nfs reload.
4. Confirm your changes with exportfs -v

Note
If your classroom uses a different network, you may want to include your
classroom network in the shared list. This will allow you to test your
access controls.

Deliverables

1. 1. The directory /var/shared/private should be exported to the


192.168.0.0/24 subnet with the following options:
Read-only mode on
Root squashing off

The Dynamic Host Configuration Protocol

The DHCP Server

Introduction

The Dynamic Host Configuration Protocol (DHCP) is one of the most useful protocols
available in Linux. DHCP is very helpful for a number of situations which network
administrators encounter. There are two main uses of DHCP which most sites will find
helpful. The first is one where a company has, for example, 100 computers but only a
small number of systems need to be on the network at any given time. This is an
excellent use for DHCP. The second use for DHCP is where you are on a network that
needs to control and manage network addresses and parameters for each computer from
a centralized location. This would simplify the task for the users. It also means that
when a large number of systems change, the administrator doesn't have to physically
visit each system. The administrator just changes one file and has each user reboot their
systems and the changes take effect.

DHCP is an extension to the Bootstrap (BOOTP) protocol. BOOTP was the first
configuration protocol to be able to provide, comprehensive information to a client to
allow it to configure itself for TCP/IP use. BOOTP was designed to deliver this
information to a client regardless of whether the client knows its IP address. DHCP
performs the same function and allows a lot more.

The DHCP protocol is defined by RFC 2131. The BOOTP protocol is defined in RFC
951, 1533, and 1542. Additional information about the inter-operation between DHCP
and BOOTP can be found in RFC 1534.

The DHCP Environment


A DHCP environment may consist of DHCP servers, clients, and relay agents. DHCP
servers are hosts with static IP addresses which supply IP configuration to DHCP
clients. DHCP clients are hosts which are not initially configured with any IP
information (such as IP address, netmask, or other network parameters). DHCP relay
agents simply forward DHCP messages between DHCP clients and servers which may
not be on the same physical network.

The communication between DHCP server and client will start with a broadcast. The
client uses a broadcast to initiate contact with the DHCP server. After the client has
been sent an IP address, all communication which follows is unicast traffic. Because the
DHCP client uses broadcast to initiate DHCP communications, the DHCP server is
required to either be on the same physical network or have DHCP relay agents on the
intervening routers.

DHCP IP Address Acquisition

A DHCP client which has no IP parameters negotiates with DHCP servers on its local
network for those parameters. When a DHCP client boots up and has no IP parameters
it sends out a DHCPDISCOVER broadcast. The DHCPDISCOVER broadcast is
encapsulated within a UDP packet with its destination port number set to sixty-seven. It
uses a broadcast address of 255.255.255.0.

After sending out the DHCPDISCOVER broadcast, the DHCP client waits some period
of time for DHCPOFFER messages from any DHCP servers which may be configured
to respond to it. The client will then select one of the responses that it receives. The
DHCPOFFER message contains the network layer information needed by the client
(such as IP address, etc.) along with a predefined lease time. The client then sends back
a DHCPREQUEST message to the DHCP server that it chooses.

The DHCP server will verify that the information is still valid and then must respond to
the client with a DHCPACK as a confirmation. The DHCPACK message from the
server may also contain a full set of configuration parameters (additional information)
for the client. The client must also verify the validity of the information (making sure
that the information is not already in use by some other client) usually by issuing an
ARP broadcast to the network. Once the DHCPACK from the server is accepted, the
client can then begin using network services and is considered to be bound.

Configuring the DHCP Server

The first step in configuring the DHCP server is to install the server software. This can
be done by installing the dhcp rpm package. The dhcp package includes a dhcp server
and a dhcp relay agent. This package can be installed by using the following command:

[root@station etc]# yum install dhcp


...
======================================================================
=======
Package Arch Version Repository
Size
======================================================================
=======
Installing:
dhcp i386 12:3.0.5-3.el5 rha-rhel
874 k
...
Installed: dhcp.i386 12:3.0.5-3.el5
Complete!

The next step is to edit the DHCP server configuration file. The DHCP server
configuration file is /etc/dhcpd.conf. This file is read by dhcpd (the DHCP daemon)
when it starts up and contains information concerning subnets and hosts that the dhcp
server will respond to and what configuration information it will supply to them. This
file is an ASCII text file that is easily readable and should be well commented.

The configuration file contains two different types of data. It begins with a global
section which defines parameters and information which applies to all clients or
controls the behavior of DHCP, such as leasing information and options which will be
passed to all clients. These options might include subnet-masks, routers, broadcast-
addresses, and many other related items which might be needed by the clients.

After the global section might be definitions of subnets or other groups. These are called
declarations and are used for defining the scope of service for the server and the
topology of the network. Each of these declaration sections may also have parameters
and options which are specific to that sub-group. Declarations which describe network
topology are usually either shared-network or subnet statements. Other statements
which may appear here are the host and group statements.

The simplest configuration would be the first situation we described where the DHCP
server is serving up a pool of IP addresses to a larger group of possible systems. This
can be done through the use of the subnet and range statements. The subnet statement
supplies information to the DHCP server so that it may determine if an IP address is on
a particular subnet. It can also contain subnet-specific parameters as well as specifying
what addresses are to be dynamically allocated to clients which may boot on that
subnet. These IP addresses are specified in a range statement. The syntax of the subnet
statement is

subnet subnet-number netmask netmask-number { [ parameters ]


[ declarations ] }

The subnet-number must be an IP address or domain name which resolves to a subnet


number. The netmask-number is an IP address or domain name which resolves to the
netmask of the subnet. The subnet and the netmask taken together are used to determine
if a given IP address is on a specified subnet. A netmask is required for every subnet.
You can also have a subnet-mask option with the subnet which overrides the declared
subnet mask. The parameters and declarations which may be contained within the
subnet statement can be options which can apply to clients or subnet, hosts, or group
statements. A sample subnet statement is shown below:

subnet 192.168.0.0 netmask 255.255.255.0 {


range 192.168.0.1 192.168.0.100;
}

The example shows that the DHCP server is setting up a pool of IP addresses ranging
from 192.168.0.1 to 192.168.0.100 for a subnet of 192.168.0.0/255.255.255.0. These
addresses will be handed out to clients on the subnet which request an address from the
DHCP server.

A range statement must be included in any subnet which will assign IP addresses
dynamically. This statement indicates the lowest and highest IP addresses within a
range of IP addresses which may be dynamically allocated to clients which request them
from the DHCP server. Any IP addresses defined within a range statement must be
within the subnet in which the range is declared. If you are specifying a single IP
address, the highest IP address can be left off. The syntax of the range statement is

range low-address [high-address];

The host statement is used to define any BOOTP clients that are to be served. The host
statement can also be used to specify fixed-addresses for DHCP clients. Host
declarations are matched to DHCP clients by either using the hostname used in the host
declaration or by matching up the network hardware address (MAC address) with the
hardware parameter listed in the host declaration. BOOTP clients don't usually have a
hostname so generally use the hardware address only. The syntax of the host statement
is

host hostname {
[ parameters ]
[ declarations ]
}

The hostname is an identifier which is associated with the client. The parameters are the
same as before. The declarations which are contained in the host statement may include
the fixed-address option to give the host a specific IP address. This IP address should
not be a member of any range statement. It may also include the hardware ethernet
option to associate a particular network hardware address with this host. A sample host
statement might be

host station1 {
fixed-address 192.168.0.1;
hardware ethernet 00:07:D4:44:F5:20;
}

The above example shows a host statement which defines a fixed address of
192.168.0.1 for station1 whose MAC address is 00:07:D4:44:F5:20. This assures that
the system whose MAC address is shown will always get the same IP address.

As noted earlier, additional information can be passed to the clients through the use of
option statements. These can be passed to all clients (by defining them in the global
section) or to only clients in a certain subnet (by placing them in the subnet statements).
There are many options which can be passed. These options include default routers,
static routes, dns servers netmasks, and many other useful information. The syntax of
the option statement is

option option-name option-items;

The option name is the name of the item that is to be passed to the client. The option-
item is the actual information to be passed. A sample option statement might be
option routers 192.168.0.254;

This example would pass the default router address of 192.168.0.254 to the client. A
complete list of options can be found in the dhcp-options (5) man page.

Once the configuration file has been completed the server must be started. This can be
done by typing:

service dhcpd start

When it starts up, the dhcpd daemon reads the /etc/dhcpd.conf file and stores the list of
available IP addresses for each subnet in memory. It then sits and waits for a client to
request an IP address using the DHCP protocol. The dhcpd daemon then allocates an IP
address for the client. Each client is also assigned a lease. This lease expires after a
particular amount of time which is defined by the DHCP administrator. If a client
wishes to continue using the IP address assigned to it, they must renew the lease prior to
its expiration. Once the lease expires, the client is no longer permitted to use the
assigned IP address.

After the dhcpd service has been started you can check its status by typing:

service dhcpd status

In addition, you may want to periodically take a look at the /var/lib/dhcp/dhcpd.leases


file. This is where the server stores the lease information which it has given out to each
client. The dhcpd daemon writes the leases as ASCII text. This makes it easy to see
what leases have been assigned. The entries in this file have the following syntax:

lease IP-address { statements }

where the keyword lease is followed by the IP address and this information is then
followed by a set of statements which give additional details about the lease. A typical
dhcpd.leases file might look like

lease {
interface "eth1";
fixed-address 192.168.0.254;
option subnet-mask 255.255.255.0;
option time-offset -18000;
option routers 192.168.0.1;
option dhcp-lease-time 21600;
option dhcp-message-type 5;
option domain-name-servers 192.168.1.1;
option dhcp-server-identifier 192.168.0.52;
option nis-domain "domain.org";
option domain-name "domain.org";
renew 2 2005/9/6 16:26:16;
rebind 2 2005/9/6 18:44:20;
expire 2 2005/9/6 19:29:20;
}

You might also like