15.4 Improving NFS Security
There are many techniques that you can use
to improve overall NFS security:
Limit the use of NFS by limiting the machines to which filesystems
are exported, and limit the number of filesystems that each client
mounts.
Export filesystems read-only if possible.
Use root ownership of exported files and
directories.
Remove group write permissions from exported files and directories.
Do not export the server's executables.
Do not export home directories.
Do not allow users to log into the NFS server.
Use the fsirand program, as described later in
this chapter.
Set the portmon variable so that NFS requests that
are not received from privileged ports will be ignored.
Use showmount -e to verify that you are
exporting only the filesystem you wish to export to the hosts
specified, and with the correct flags.
Use Secure NFS.
These techniques are described in the following sections.
15.4.1 Limit Exported and Mounted Filesystems
The best way to limit the danger of
NFS is by having each computer export and/or mount only the
particular filesystems that are needed.
If a filesystem does not need to be exported, do not export it. If it
must be exported, export it to as few machines as possible by
judiciously using restrictions in the exports list. If you have a
sizeable number of machines to export to, and if such lists are
tedious to maintain, consider careful use of the netgroups mechanism,
if you have it. Do not export a filesystem to any computer unless you
have to. If possible, export filesystems read-only.
If you only need to export part of a filesystem, then export only
that part. Do not export an entire filesystem if you need access to
only a particular directory.
Likewise, your clients should mount only the NFS servers that are
needed. Don't simply have every client in your
organization mount every NFS server. Limiting the number of mounted
NFS filesystems will improve overall security, and will improve
performance and reliability as well.
The above advice may seem simple, but it is advice that is rarely
followed. Many organizations have configured their computers so that
every server exports all of its filesystems so that every client
mounts every exported filesystem. And the configuration gets worse:
some computers on the Internet today make filesystems available
without restriction to every other computer on the Internet.
Carelessness or ignorance is usually to blame: a system administrator
faced with the need to allow access to a directory believes that the
easiest (or only) way to provide the access is to simply enable file
sharing for everybody. One of us once watched a student in a lab in
the Netherlands mount filesystems from more than 25 U.S. universities
and corporations on his workstation—most with read/write
access!
Some versions of NFS enforce the exports file
only during mount, which means that clients that mount filesystems on
a server will continue to have access to those filesystems until the
clients unmount the server's filesystems or until
the filesystems are rebooted. Even if the client is removed from the
server's exports file and the
server is rebooted, the client will continue to have access and can
continue to use a filesystem after unmounting it, unless the
directory is no longer exported at all, or unless
fsirand is run on
the exported filesystem to change the generation count of each inode.
Distinguishing a file handle that is guessed from one that is
returned to the client by the mount daemon is
impossible. Thus, on systems where the exports are examined only upon
mounting, any file on the NFS server can be accessed by an adversary
who has the ability and determination to search for valid file
handles.
Many modern NFS servers check exports on each client access, rather
than only on mount.
|
15.4.1.1 The example explained
In the example we presented earlier in this
chapter, Example 15-1an
/etc/dfs/dfstab file with some
problems," a system administrator made three
dangerous mistakes. On the third line, the administrator exported the
directory /tftpboot. This directory is exported
to any computer on the network that wishes to mount it; if the
computer is on the Internet, then any other computer on the Internet
has access to this server's
/tftpboot directory.
What's the harm? First of all, users of the
/tftpboot directory may not be aware that files
that they place in it can be so widely accessed. Another problem
arises if the directory can be written: in this case, there is a
possibility that the storage space will be hijacked by software
pirates and used as a software pirate
"warez" repository. Perhaps worse,
the software on that partition can be replaced with hacked versions
that may not perform as the real owners expect! (In this case,
/tftpboot is probably used for providing
bootstrap code to machines on the network. By modifying this code, a
resourceful attacker could force arbitrary computers to run password
sniffers, erase their hard drives, or do other unwanted things.)
The last two lines of the sample configuration file have a similar
problem: they export the directories
/usr/lib/X11/ncd and
/usr/openwin freely over the network. Although
the directories are exported read-only, there is still a chance that
a software pirate could use the exported filesystems to obtain copies
of copyrighted software. This scenario could create a legal liability
for the site running the NFS server.
You can make your server more secure by exporting filesystems only to
the particular computers that need to use those filesystems.
Don't export filesystems that
don't have to be exported. And
don't export filesystems to the entire
Internet—otherwise, you will only be asking for trouble.
Here is a revised dfstab file that is properly
configured:
# Place share(1M) commands here for automatic execution
# upon entering init state 3.
#
# This configuration is more secure.
#
share -F nfs -o rw=red:blue:green /cpg
share -F nfs -o rw=clients -d "spool" /var/spool
share -F nfs -o ro=clients /tftpboot
share -F nfs -o ro=clients /usr/lib/X11/ncd
share -F nfs -o ro=clients /usr/openwin
|
Be aware that the options to export commands and configuration files
have different semantics under SVR4 and earlier, BSD-like systems
(including SunOS). Under earlier BSD-like systems, the
-ro option does not take hostnames as
parameters, and there is an -access option to
limit access. If you specified an export list under SunOS as in the
above example:
exportfs -i -o rw=clients /var/spool
then the directory is exported read/write to the members of the
clients netgroup, but it is also exported read-only to
everyone else on the network! You must also specify the
-access option with the -rw
option to limit the scope of the export. Thus, to prevent other
machines from reading exported files, you must use the following
command:
exportfs -i -o rw=clients,access=clients /var/spool
Under SVR4, both the -rw and
-ro options can take a host list to restrict the
export of the files. The directory is exported
only to the hosts named in the union of the two
lists. There is no -access option in
SVR4.
|
|
15.4.2 Export Read-Only
Many filesystems contain information
that is only read—never (or rarely) written. These filesystems
can be exported read-only. Exporting the filesystems read-only adds
to both security and reliability: it prevents the filesystems from
being modified by NFS clients, limiting the damage that can be done
by attackers, ignorant users, and buggy software.
Many kinds of filesystems are candidates for read-only export:
Filesystems containing applications
Organizational reference matter, such as policies and documents
Web server document roots
If you have programs or other files that must be exported read-write,
you can improve your system's overall performance,
reliability, and security by placing these items on their own
filesystem that is separately exported.
To export a filesystem read-only, specify the
ro=clients option in either your
exports file or your dfstab
file (depending on which version of Unix you are using). In the
following example, the /LocalLibrary directory
is exported read-only:
share -F nfs -o ro=clients /LocalLibrary
15.4.3 Use Root Ownership
Because the NFS server maps
root to nobody, you can
protect files and directories on your server by setting their owner
to root and their protection modes to 755 (in
the case of programs and directories) or 644 (in the case of
datafiles). This setup will prevent the contents of the files from
being modified by a client machine.
If you have information on an NFS server that should not be
accessible to NFS clients, you can use the file protection mode 700
(in the case of programs and directories) or 600 (in the case of
datafiles). However, a better strategy is to avoid placing the files
on the NFS server in the first place.
Remember, this system protects only files on the server that are
owned by root. Also, this technique does not
work if you have patched your kernel to set the value of
nobody to 0, or if you export the filesystems to a
particular host with the -root=
option.
|
Protecting an executable file to be execute-only will not work as you
expect in an NFS environment. Because you must read a file into
memory before it can be executed, any file marked executable can also
be read from a server using NFS commands (although it may not be
possible to do so using standard calls through a client). The server
has no way of knowing whether the requests to be read are a prelude
to execution or not. Thus, putting execute-only files on an exported
partition may allow them to be examined or copied from a client
machine.
|
|
15.4.4 Remove Group-Write Permission for Files and Directories
If you are using standard AUTH_UNIX
authentication with NFS, then users can effectively place themselves
in any group. Thus, to protect files and directories that are owned
by root, they must not be
group-writable.
15.4.5 Do Not Export Server Executables
If your server is running the same
operating system on the same CPU architecture as your client
computers, then you might be tempted to have the server export its
own executables (such as the programs stored in
/bin, /usr/bin, etc.) for
use by the clients. Don't do so without careful
thought about the consequences.
At first, exporting a server's own executables seems
like a good way to save disk space: this way, you need to have only
one copy of each program (which is then shared between the clients
and the servers) rather than two copies.
But exporting your server's executables poses
several security problems:
It allows an attacker to easily determine which version of each
executable your server is running, which enables the attacker to
probe for weak spots with greater ease.
If there is an error in your system's configuration,
you may be exporting the binaries on a writable filesystem. An
attacker could then modify the server's own
binaries, and possibly break in (or at least cause you serious
problems).
You can minimize the need for exporting server binaries by using the
dataless client configuration that is
available on some versions of Unix. In this case,
"dataless" means that each client
computer maintains a complete copy of all of its executable files,
but stores all of its data that is subject to change on a central
server.
If you simply must export the
server's binaries, then export the filesystem
read-only.
15.4.6 Do Not Export Home Directories
If you export a filesystem that
has users' home directories on it and you do not use
Secure RPC, then all other clients mounting that directory, as well
as the server itself, can be placed at risk.
If you generally export a filesystem that contains
users' home directories, then there is a risk that
an attacker could alter the information stored on the NFS server.
This is normally a serious risk in itself. However, if the partition
being exported includes users' home directories,
then one of the things that an attacker can do is create files in the
users' home directories.
A simple attack is for an attacker to create a
.rhosts file or an entry in
.ssh/authorized_keys in a
user's home directory that specifically allows
access for the attacker. Having created this file, the attacker can
log onto the server and proceed to look for additional security
holes. Perhaps the greatest danger in this attack is that it can be
aimed against system accounts (such as daemon
and bin) as easily as accounts used by human
users. An attacker can also access email, change the startup files,
and otherwise read or alter sensitive files—including SSH keys
and configuration, and X Window System key files.
Likewise, you should avoid exporting filesystems that contain
world-writable directories (e.g., /tmp,
/usr/tmp,
/usr/spool/uucppublic).
15.4.7 Do Not Allow Users to Log into the Server
NFS and direct logins are two fundamentally different ways to use a
computer. If you allow users to log into a server, the user can use
that access to probe for weaknesses that can be exploited from NFS,
and vice versa.
15.4.8 Use fsirand
One of the security problems with NFS is
that the file handles used to reference a file consist solely of a
filesystem ID, an inode number, and a generation count. Guessing
valid file handles is easy in most circumstances. Filesystem IDs are
normally small numbers; the root directory on
the standard Unix filesystem has the inode number 2,
/lost+found has the inode number 3, and so on.
The only difficulty in guessing a file handle is the generation
count. For many important inodes, including the
root inode, we would expect the generation count
to be very small—we don't normally delete a
filesystem's root entry!
The fsirand program increases the difficulty of
guessing a valid file handle by randomizing the generation number of
every inode on a filesystem. The effect is transparent to the
user—files and directories are still fetched as appropriate
when a reference is made—but someone on the outside is unable
to guess file handles for files and directories anymore.
You can run fsirand on the
root directory while in single-user mode or on
any unmounted filesystem that will fsck without
error.
For example, to run fsirand on your
/dev/sd1a partition, type the following:
# umount /dev/sd1a Unmount the filesystem
# fsirand /dev/sd1a Run fsirand
You might benefit from running fsirand once a
month on your exported partitions. Some people run it automatically
every time the system boots, but this has the disadvantage of making
all legitimate file handles stale, too. Consider your environment
before taking such a drastic step.
The fsirand program is not available on all
versions of Unix. In particular, it is not available under Linux.
|
Older versions of Sun's fsirand
contained buggy code that made the
"random" values quite predictable.
Be sure you have the latest version of fsirand
from your vendor. Most newer versions of the
newfs command automatically run
fsirand, but not all do. The functionality of
fsirand is incorporated into the Solaris 2.5
mkfs command.
|
|
15.4.9 Set the portmon Variable
Normally, NFS servers respond to
requests that are transmitted from any UDP port. However, because NFS
requests are supposed to come from kernels of other computers, and
not from users who are running user-level programs on other
computers, a simple way to improve the security of NFS servers is to
program them to reject NFS requests that do not come from privileged
ports. On many NFS servers, the way that this restriction is
established is by setting the kernel variable
nfs_portmon to 1.
It's important to do this if you want even a minimal
amount of NFS security.
If you are using SunOS, you can set the
nfs_portmon variable to 1 using
the adb debugger:
# adb -k -w /vmunix /dev/mem Changes kernel disk file
nfs_portmon/W1 Changes running kernel
_nfs_portmon: _nfs_portmon: 0 The default setting
?W1 Change to 1
$q Write out the result
#
If you are using
Solaris 2.1-2.4, you can set the
portmon variable by inserting this line into your
/etc/system file:
set nfs:nfs_portmon = 1
If you are using Solaris 2.5 and above, you can set the variable by
inserting this line into your /etc/system file:
set nfssrv:nfs_portmon = 1
On Linux systems, setting the
secure option for an exported directory in
/etc/exports performs the same function as
nfs_portmon.
Unfortunately, restricting NFS requests to those transmitted from a
privileged client port is not as useful a defense against an attacker
as it may seem. If you export to any machine within your organization
(or network), an attacker who is root on another
Unix machine can generate traffic from a privileged port. Worse, an
internal attacker may be running an operating system that has no
concept of privileged ports—such as most
"client" versions of Windows. To be
truly effective, the restriction on client ports must be combined
with strict controls on which clients can access the server.
15.4.10 Use showmount -e
The showmount -e
command (mentioned earlier in this chapter) lists the
host's export lists—that is, the directories
and hosts that can be mounted. The showmount
command allows an optional argument, host. When
this argument is provided, the showmount command
can be used to remotely inspect another computer's
export list. The command is useful for finding NFS servers that are
configured in an unsecure fashion. For example:
% /usr/etc/showmount -e deadly.org
export list for deadly.org:
/bigusers (everyone)
/tmp2 (everyone)
/ (everyone)
/usr (everyone)
/var (everyone)
/usr/public (everyone)
/usr/public/pub (everyone)
%
In this case, the computer deadly.org appears to
be exporting its /bigusers,
/tmp2, /,
/usr, /var,
/usr/public, and
/usr/public/pub directories to every other
computer on the Internet.
Fortunately, things aren't as bad as they seem at
deadly.org. That's because they are
using Secure NFS. Here's what happens when you try
to mount the filesystem:
# mount deadly.org:/ /nfs/tmp
nfs: bad MNT RPC: RPC: Authentication error; why = Client credential too weak
15.4.11 Use Secure NFS
The
biggest security problem with NFS, as it is normally configured, is
that it uses Sun's AUTH_UNIX RPC authentication
system. With AUTH_UNIX, a user simply provides his UID and a list of
GIDs with every request. The NFS server trusts that the user is who
he claims to be.
In a friendly environment, AUTH_UNIX authentication presents no
problems because requests sent out by the NFS client always have the
same UID and GIDs as the person who has logged in and is using the
workstation. However, if the workstation user has
root access, that person can use the
root access to become any other user, with that
other user's corresponding rights and privileges on
the RPC server. A second problem with AUTH_UNIX is that user-written
programs can have their AUTH_UNIX UID and GIDs set to any
value. When reserved port checking
is enabled, AUTH_UNIX offers roughly the same level of security as
the rsh/rlogin trusted-host facility.
Secure NFS overcomes these problems by using
AUTH_DES RPC authentication
instead of AUTH_UNIX. With Secure NFS, users must be able to decrypt
a special key stored on the NIS or NIS+ server before the NFS
filesystem will allow the user to access his files.
To specify Secure NFS, you must specify the
secure option both on the NFS server (in the
exports file or the dfstab)
and on the client (in the /etc/fstab or
/etc/vfstab file).
|
Secure NFS requires Secure RPC to function, and therefore may not be
available on all versions of Unix. If you are in doubt about your
system, check your documentation to see if your NFS
mount command supports the
secure option. Also note that Secure RPC may not
be available on non-Unix implementations of NFS.
|
|
Here is an example of using Secure NFS. Suppose that a server has a
filesystem /Users that it will export using
Secure NFS. The server's
/etc/dfs/dfstab file might contain the following
line:
share -F nfs -o secure,rw=clients /Users
Meanwhile, the clients /etc/vfstab file would
have a matching line:
#device device mount FS fsck mount mount
#to mount to fsck pont type pass at boot options
#
server:/Users - /Users nfs - yes secure
|