13.1 Remote Procedure Call (RPC)

The fundamental building block of all network information systems is a mechanism for performing remote operations. Abstractly, this can be done via either messages or procedure calls; systems have been developed using both paradigms, and the capabilities are equivalent. Sun's software engineers chose to use the abstraction of procedure calls. This mechanism, usually called RPC, allows a program running on one computer to more or less transparently execute a function that is actually running on another computer.

RPC allows programs to be distributed so that a computationally intensive algorithm can be run on a high-speed computer, a remote sensing device can be run on another computer, and the results can be compiled on a third. RPC also makes it easy to create network-based client/server programs. The clients and servers communicate with each other using remote procedure calls.

The RPC system was developed by Sun Microsystems for use with NIS and NFS. Sun's RPC uses a system called XDR (external data representation) to represent binary information in a uniform manner and bit order. XDR allows a program running on a computer with one byte order, such as a SPARC workstation, to communicate seamlessly with a program running on a computer with an opposite byte order, such as a workstation with an Intel x86 microprocessor. RPC messages can be sent with either the TCP or UDP IP protocols (currently, the UDP version is more common). After their creation by Sun, XDR and RPC were reimplemented by the University of California at Berkeley and are now freely available.[2]

[2] And all of those implementations were found to have a buffer overflow vulnerability in 2002 (see http://www.cert.org/advisories/CA-2002-25.html for more information). Fortunately, vendors quickly released patched XDR code.

Sun's RPC is not unique. A different RPC system is used by the Open Software Foundation's Distributed Computing Environment (DCE). Yet another RPC system was proposed by the Object Management Group. Named CORBA (Common Object Request Broker Architecture), this system is optimized for RPC between object-oriented programs written in C++ or SmallTalk. Java programmers use Remote Method Invocation (RMI). There have also been a number of research RPC systems developed before and after Sun's.

In the following sections, we'll discuss the Sun RPC mechanism, as it seems to be the most widely used. The continuing popularity of NFS (described in Chapter 15) suggests that Sun RPC will be in widespread use for some time to come.

13.1.1 Sun's portmap/rpcbind

For an RPC client to communicate with an RPC server, many things must happen:

  • The RPC client must be running.

  • The RPC server must be running on the server machine (or it must be automatically started when the request is received).

  • The client must know on which host the RPC server is located.

  • The client and the server must agree to communicate on a particular TCP or UDP port.

The simplest way to satisfy this list of conditions is for the Unix computer to start the server when the computer boots, for the server to run on a well-known port, and for the port numbers to be predefined. This is the approach that Unix takes with standard Internet services such as Telnet and SMTP.

The approach that Sun took for RPC was different. Instead of having servers run on well-known ports, Sun developed a program named portmap in SunOS 4.x, and renamed rpcbind in Solaris 2.x. Throughout this book, we will refer to the program as the portmapper.[3]

[3] A rewritten portmapper for SunOS 4.1.x, HP-UX 9.0, AIX 3.x/4.x, and Digital Unix (OSF/1) by Wietse Venema provided superior access control for these older systems. Most modern systems now distribute portmappers that can be configured to restrict access using /etc/hosts.allow and /etc/hosts.deny. However, it is still possible to locate RPC services by scanning for them directly, without asking the portmapper.

When an RPC server starts, it dynamically obtains a free UDP or TCP port, then registers itself with the portmapper. When a client wishes to communicate with a particular server, it contacts the portmapper process, determines the port number used by the server, and then initiates communication.

The portmapper approach has the advantage that you can have many more RPC services (in theory, 232) than there are TCP or UDP port numbers (216).[4] In practice, however, the greater availability of RPC server numbers has not been very important. Indeed, one of the most widely used RPC services, NFS, usually has a fixed port of 2049.

[4] Of course, you can't really have 232 RPC services because there aren't enough programmers to write them, or enough computers and RAM for them to run. The reason for having 232 different RPC service numbers available was that different vendors could pick RPC numbers without the possibility of conflict. A better way to reach this goal would have been to allow RPC services to use names so that companies and organizations could have registered their RPC services using their names as part of the service names.

The portmapper program also complicates building Internet firewalls because you almost never know in advance the particular port that will be used by RPC-based services. (This is mitigated by the realization that you almost always want to deny access to your RPC-based services to anyone outside your firewall.)

13.1.2 RPC Authentication

Client programs contacting an RPC server need a way to authenticate themselves to the server so that the server can determine what information the client should be able to access, and what functions should be allowed. Without authentication, any client on the network that can send packets to the RPC server could access any function. In most environments this is not something you want to allow.

There are several different forms of authentication available for RPC, as described in Table 13-1. Not all authentication systems are available in all versions of RPC.

Table 13-1. RPC authentication options

System

Authentication technique

Comments

AUTH_NONE

None

No authentication. Anonymous access.

AUTH_UNIX[5]

RPC client sends the Unix UID and GIDs for the user

Not secure. Server implicitly trusts that the user is who the user claims to be.

AUTH_DES

Authentication based on public key cryptography and DES

Reasonably secure.

AUTH_KERB

Authentication based on Kerberos

Reasonably secure, but requires that you properly set up a Kerberos server. AUTH_KERB is not universally available.

[5] AUTH_UNIX is called AUTH_SYS in at least one version of Sun Solaris.

13.1.2.1 AUTH_NONE

Live fast, die young. AUTH_NONE is bare-bones RPC with no user authentication. You might use it for services that require and provide no useful information, such as time of day. On the other hand, why do you want other computers on the network to be able to find out the setting of your system's time-of-day clock? (Furthermore, because the system's time of day is used in a variety of cryptographic protocols, even that information might be usable in an attack against your computer.) Besides, NTP is a much better protocol to use for obtaining the time for any legitimate purpose (see the sidebar Telling Time in Chapter 12). Do not use AUTH_NONE.

13.1.2.2 AUTH_UNIX

AUTH_UNIX was the only authentication system provided by Sun through Release 4.0 of the SunOS operating system, and it is the only form of RPC authentication offered by many Unix vendors. It is widely used. Unfortunately, it is fundamentally unsecure.

With AUTH_UNIX, each RPC request is accompanied with a UID and a set of GIDs[6] for authentication. The server implicitly trusts the UID and GIDs presented by the client and uses this information to determine if the action should be allowed. Anyone with access to the network can craft an RPC packet with any arbitrary values for UID and GID. Obviously, AUTH_UNIX is not secure because the client is free to claim any identity, and there is no provision for checking by the server.

[6] Some versions of RPC present 8 additional GIDs, while others present up to 16.

In recent years, Sun has changed the name AUTH_UNIX to AUTH_SYS. Nevertheless, it's still the same system.

13.1.2.3 AUTH_DES

AUTH_DES is the basis of Sun's "Secure RPC" (described in some detail later in this chapter). AUTH_DES uses a combination of secret key and public key cryptography to allow security in a networked environment. It was developed several years after AUTH_UNIX, and for some time was not widely available on Unix platforms other than Sun's SunOS and Solaris 2.x operating systems. AUTH_DES is now available in modern BSD systems and systems that use the GNU C library (such as Linux), as well as HP-UX and AIX, but the availability of applications (such as NFS clients and servers) that can use AUTH_DES on these platforms varies.

13.1.2.4 AUTH_KERB

AUTH_KERB is a modification to Sun's RPC system that allows it to interoperate with MIT's Kerberos system for authentication. Although Kerberos was developed in the mid 1980s, AUTH_KERB authentication for RPC was not incorporated into Sun's RPC until the early 1990s. Solaris 8 and 9 include Kerberos client support, and Solaris 9 includes Kerberos server support as well. We describe Kerberos in Chapter 14.

Carefully review the RPC services that are configured into your system for automatic start when the system boots, or for automatic dispatch from the inetd (see Section 12.1.2). If you don't need a service, disable it. In particular, if your version of the rexd service cannot be forced into accepting only connections authenticated with Kerberos or Secure RPC, then it should be turned off. The rexd daemon (which executes commands issued with the on command) is otherwise easily fooled into executing commands on behalf of any non-root user.



    Part VI: Appendixes