Next Previous Contents

6. Security and NFS

I am by no means a computer security expert. But I do have a little advice for the security conscious. But be warned: This is by no means a complete list of NFS related problems and if you think you're safe once you're read and implemented all this I have a bridge I want to sell you.

This section is probably of no concern if you are on a closed network where you trust all the users, and no-one you don't trust can get access to machines on the network. I.e., there should be no way to dial into the network, and it should in no way be connected to other networks where you don't trust everyone using it as well as the security. Do you think I sound paranoid? I'm not at all paranoid. This is just basic security advice. And remember, the things I say here is just the start of it. A secure site needs a diligent and knowledgeable admin that knows where to find information about current and potential security problems.

NFS has a basic problem in that the client, if not told otherwise, will trust the NFS server and vice versa. This can be bad. It means that if the server's root account is broken into it can be quite easy to break into the client's root account as well. And vice versa. There are a couple of coping strategies for this, which we'll get back to.

Something you should read is the CERT advisories on NFS, most of the text below deals with issues CERT has written advisories about. See ftp.cert.org:/01-README for a up to date list of CERT advisories. Here are some NFS related advisories:


CA-91:21.SunOS.NFS.Jumbo.and.fsirand                            12/06/91
     Vulnerabilities concerning Sun Microsystems, Inc. (Sun) Network
     File System (NFS) and the fsirand program.  These vulnerabilities
     affect SunOS versions 4.1.1, 4.1, and 4.0.3 on all architectures.
     Patches are available for SunOS 4.1.1.  An initial patch for SunOS
     4.1 NFS is also available. Sun will be providing complete patches
     for SunOS 4.1 and SunOS 4.0.3 at a later date.

CA-94:15.NFS.Vulnerabilities                                    12/19/94
     This advisory describes security measures to guard against several
     vulnerabilities in the Network File System (NFS). The advisory was
     prompted by an increase in root compromises by intruders using tools
     to exploit the vulnerabilities.

CA-96.08.pcnfsd                                                 04/18/96
     This advisory describes a vulnerability in the pcnfsd program (also
     known as rpc.pcnfsd). A patch is included.

6.1 Client Security

On the client we can decide that we don't want to trust the server too much a couple of ways with options to mount. For example we can forbid suid programs to work off the NFS file system with the nosuid option. This is a good idea and you should consider using this with all NFS mounted disks. It means that the server's root user cannot make a suid-root program on the file system, log in to the client as a normal user and then use the suid-root program to become root on the client too. We could also forbid execution of files on the mounted file system altogether with the noexec option. But this is more likely to be impractical than nosuid since a file system is likely to at least contain some scripts or programs that needs to be executed. You enter these options in the options column, with the rsize and wsize, separated by commas.

6.2 Server security: nfsd

On the server we can decide that we don't want to trust the client's root account. We can do that by using the root_squash option in exports:


/mn/eris/local apollon(rw,root_squash)

Now, if a user with UID 0 on the client attempts to access (read, write, delete) the file system the server substitutes the UID of the servers `nobody' account. Which means that the root user on the client can't access or change files that only root on the server can access or change. That's good, and you should probably use root_squash on all the file systems you export. "But the root user on the client can still use 'su' to become any other user and access and change that users files!" say you. To which the answer is: Yes, and that's the way it is, and has to be with Unix and NFS. This has one important implication: All important binaries and files should be owned by root, and not bin or other non-root account, since the only account the clients root user cannot access is the servers root account. In the NFSd man page there are several other squash options listed so that you can decide to mistrust whomever you (don't) like on the clients. You also have options to squash any UID and GID range you want to. This is described in the Linux NFSd man page.

root_squash is in fact the default with the Linux NFSd, to grant root access to a filesystem use no_root_squash.

Another important thing is to ensure that nfsd checks that all it's requests comes from a privileged port. If it accepts requests from any old port on the client a user with no special privileges can run a program that's is easy to obtain over the Internet. It talks nfs protocol and will claim that the user is anyone the user wants to be. Spooky. The Linux nfsd does this check by default, on other OSes you have to enable this check yourself. This should be described in the nfsd man page for the OS.

Another thing. Never export a file system to 'localhost' or 127.0.0.1. Trust me.

6.3 Server security: the portmapper

The basic portmapper, in combination with nfsd has a design problem that makes it possible to get to files on NFS servers without any privileges. Fortunately the portmapper that most Linux distributions use is relatively secure against this attack, and can be made more secure by configuring up access lists in two files.

Not all Linux distributions were created equal. Some seemingly up-to-date distributions does not include a securable portmapper, even today, many years since the vulnerability became common knowledge. At least one distribution even contains the manpage for a securable portmapper but the actual portmapper is not secureable. The easy way to check if your portmapper is good or not is to run strings(1) and see if it reads the relevant files, /etc/hosts.deny and /etc/hosts.allow. Assuming your portmapper is /usr/sbin/portmap you can check it with this command: strings /usr/sbin/portmap | grep hosts. On my machine it comes up with this:


/etc/hosts.allow
/etc/hosts.deny
@(#) hosts_ctl.c 1.4 94/12/28 17:42:27
@(#) hosts_access.c 1.20 96/02/11 17:01:27

First we edit /etc/hosts.deny. It should contain the line


portmap: ALL

which will deny access to everyone. While it is closed thus run rpcinfo -p just to check that your portmapper really reads and obeys this file. rpcinfo should give no output, or possebly a errormessage. Restarting the portmapper should not be necessary.

Closing the portmapper for everyone is a bit drastic, so we open it again by editing /etc/hosts.allow. But first we need to figure out what to put in it. It should basically list all machines that should have access to your portmapper. On a run of the mill Linux system there are very few machines that need any access for any reason. The portmapper administrates nfsd, mountd, ypbind/ypserv, pcnfsd, and 'r' services like ruptime and rusers. Of these only nfsd, mountd, ypbind/ypserv and perhaps pcnfsd are of any consequence. All machines that needs to access services on your machine should be allowed to do that. Let's say that your machines address is 129.240.223.254 and that it lives on the subnet 129.240.223.0 should have access to it (those are terms introduced by the networking HOWTO, go back and refresh your memory if you need to). Then we write


portmap: 129.240.223.0/255.255.255.0

in hosts.allow. This is the same as the network address you give to route and the subnet mask you give to ifconfig. For the device eth0 on this machine ifconfig should show


...
eth0      Link encap:10Mbps Ethernet  HWaddr 00:60:8C:96:D5:56
          inet addr:129.240.223.254  Bcast:129.240.223.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:360315 errors:0 dropped:0 overruns:0
          TX packets:179274 errors:0 dropped:0 overruns:0
          Interrupt:10 Base address:0x320 
...

and netstat -rn should show


Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
...
129.240.223.0   0.0.0.0         255.255.255.0   U     0      0   174412 eth0
...

(Network address in first column).

The hosts.deny and hosts.allow files are described in the manual pages of the same names.

IMPORTANT: Do not put anything but IP NUMBERS in the portmap lines of these files. Host name lookups can indirectly cause portmap activity which will trigger host name lookups which can indirectly cause portmap activity which will trigger...

The above things should make your server tighter. The only remaining problem (Yeah, right!) is someone breaking root (or boot MS-DOS) on a trusted machine and using that privilege to send requests from a secure port as any user they want to be.

6.4 NFS and firewalls

It's a very good idea to firewall the nfs and portmap ports in your router or firewall. The nfsd operates at port 2049, both udp and tcp protocols. The portmapper at port 111, tcp and udp, and mountd at port 745 and and 747, tcp and udp. Normally. You should check the ports with the rpcinfo -p command.

If on the other hand you want NFS to go through a firewall there are options for newer NFSds and mountds to make them use a specific (nonstandard) port which can be open in the firewall.

6.5 Summary

If you use the hosts.allow/deny, root_squash, nosuid and privileged port features in the portmapper/nfs software you avoid many of the presently known bugs in nfs and can almost feel secure about that at least. But still, after all that: When an intruder has access to your network, s/he can make strange commands appear in your .forward or read your mail when /home or /var/spool/mail is NFS exported. For the same reason, you should never access your PGP private key over nfs. Or at least you should know the risk involved. And now you know a bit of it.

NFS and the portmapper makes up a complex subsystem and therefore it's not totally unlikely that new bugs will be discovered, either in the basic design or the implementation we use. There might even be holes known now, which someone is abusing. But that's life. To keep abreast of things like this you should at least read the newsgroups comp.os.linux.announce and comp.security.announce at a absolute minimum.


Next Previous Contents