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 server.
Use the fsirand program, as described below.
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 only exporting the filesystem you wish to export to the hosts specified with the correct flags.
Use Secure NFS .
These techniques are described below.
The best way to limit the danger of NFS is by having each computer only export and/or mount 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 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, as we'll describe in the next section.
If you only need to export part of a filesystem, then export only that part. Do not export an entire filesystem if you only need access to a particular directory.
Likewise, your clients should only mount 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, and so that every client mounts every exported filesystem. And the configuration gets worse: many computers on the Internet today make filesystems available without restriction to any other computer on the Internet. Usually, carelessness or ignorance is 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.
Not too long ago, one of us 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!
In the example we presented earlier in this chapter, Example 20.1 An /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 would wish! (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 only exporting filesystems 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 # on 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
NOTE: Be aware that the options on 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 such as in the above example:
exportfs -i -o rw=clients /var/spoolthen 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/spoolUnder 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 .
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
Netnews (if you do not read news with NNTP )
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
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 mode to 755 (in the case of programs and directories) or 644 (in the case of data files). 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 data files). However, a better strategy is not to place 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.
NOTE: 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 if 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.
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.
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 only need to have 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.
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 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 in a users's home directory that specifically allows access to the attacker. Having created this file, the attacker could now 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.
Likewise, you should avoid exporting filesystems that contain world-writable directories (e.g., /tmp, /usr/tmp, /usr/spool/uucppublic) .
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.
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.
NOTE: 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.
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.[10]
[10] The value of 1 is not the default because some vendors' NFS implementations don't send requests from ports <1024. If you set portmon , those vendors' machines will not be able to be NFS clients from this NFS server.
If you are using SunOS, you can set the nfs_portmon variable to 1 using the adb debugger:[11]
[11] If you rebuild the kernel, these modifications will be lost. You may want to consider adding them to /etc/rc/local. (A version of this command is in /etc/rc/* on some systems.)
# 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 the result out #
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
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 which are insecurely configured. 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
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 users are who they claim 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.[12] When reserved port checking is enabled, AUTH_UNIX offers roughly the same level of security as the rsh/rlogin trusted-host facility.
[12] We have seen several "NFS shells" that allow a user to make such accesses in a largely automated way.
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 or her 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).
NOTE: 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 , either.
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 moun to fsck pont type pass at boot options # server:/Users - /Users nfs - yes secure