Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!bloom-beacon!athena.mit.edu!wesommer From: wesommer@athena.mit.edu (William Sommerfeld) Newsgroups: comp.protocols.tcp-ip Subject: Re: Ethernet Bridge (really: NFS "security") Message-ID: <1761@bloom-beacon.MIT.EDU> Date: Sat, 7-Nov-87 12:15:37 EST Article-I.D.: bloom-be.1761 Posted: Sat Nov 7 12:15:37 1987 Date-Received: Mon, 9-Nov-87 06:51:51 EST References: <8711062349.AA04106@ucbvax.Berkeley.EDU> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: wesommer@athena.mit.edu (William Sommerfeld) Organization: Massachusetts Institute of Technology Lines: 80 Summary: It's bad, folks (but there's hope) In article <8711062349.AA04106@ucbvax.Berkeley.EDU> snorthc@NSWC-OAS.ARPA writes: >OK, I'll bite. We have been looking at NFS as a UNIX/VMS server solution >for PCs. From the begining of the investigation we were looking for >things like the 'huge security holes'. Huge security holes is correct. [I won't even talk about vulnerability to malformed packets] At least in the implementations that I have seen (the "portable NFS release"), the NFS server daemon does not look at the client's IP address at all; thus, it will permit access to anyone who can send you UDP packets on port 2049. There is a minor complication, which is that to do anything meaningful, you need to know a "file handle" for a directory on one filesystem. Once you have the file handle, you can do anything you want to the file system, because you can claim an arbitrary user-id in the packet, and the server will trust you. The idea that you have to be "root" on the client to do this is incorrect. It is possible to write a user-level program, using the Sun RPC library, which talks directly to the NFS server of your choice (I know.. it took me about a day to do this, working from the NFS protocol spec). Anyway, back to the weak spot. You can get a file handle from the mount daemon (/usr/etc/rpc.mountd). It reads /etc/exports to find out which hosts it can give out file handles to. Unfortunately, in some versions, it trusts the client to name itself (there is a hostname in the request packet, filled in by the client). In addition, it is possible to make up a valid file handle from whole cloth. In the current implementations, the file handle is the tuple of {device_id, inode_number, generation_number}. The device_id is the UNIX major and minor device number of the device the partition is on. The inode number is just a simple index into the inode table of the filesystem (inode number 2 is the root of the partition, for historical reasons), and the generation number is there to ensure that if an inode is reused for a new file, the new file doesn't get confused with the old. These are initialized to all zero by the standard (non-NFS) newfs. There is a program, called "fsirand", which randomizes the generation numbers of all the inodes on a partition. It is important to run this for _all_ partitions mounted on the server, not just the ones which you want exported, because otherwise someone will be able to use the {device_id, 2, 0} file handle, and get at the root of one of your other filesystems. Thus, the generation numbers become almost as critical as the root password to the server. Is any effort exerted to keep them secret? No. They fly around on the ethernet in the clear. They can also be extracted if you have access to read kernel memory (/dev/kmem or /dev/mem) on the server (typically allowed on pre-4.3 BSD unix systems). There is light at the end of this tunnel, fortunately. Here at Athena, we implemented a very small patch to NFS which gets around this chain of security holes. We modified the NFS server to maintain a hash table which maps {client IP address, user_id} to {local uid, group set}. Map entries are controlled by a modified rpc.mountd which uses the Kerberos authentication system to verify the authenticity of the client. Rather than trusting the client machine to give the user id and group set of the user, the server instead looks for a mapping in the hash table. If no mapping is found, the request is either remapped to uid -2, or rejected immediately, depending on how the server is configured. This has been in use for about five or six months (and in heavy use since September), with very few problems. This is not as secure as Sun's experimental secure NFS system, which includes an authenticator on each request, but our approach involves a minimal performance overhead (when you use VAX 11/750's as servers, you need all the help you can get...), and requires no modifications to the client kernel, and also doesn't require any protocol changes to NFS itself. Bill Sommerfeld wesommer@athena.mit.edu