Contents:
Understanding UNIX Internet Servers
Controlling Access to Servers
Primary UNIX Network Services
Security Implications of Network Services
Monitoring Your Network with netstat
Network Scanning
Summary
Connecting a UNIX computer to the Internet is not an action that should be taken lightly. Although the TCP/IP protocol suite and the UNIX operating system themselves have few inherent security problems, many of the problems that do exist have a strange way of showing themselves when computers running the UNIX operating system are put on the global network.
The reason for caution has a lot to do with the flexibility of both UNIX and the Internet. A network connection gives users on the network dozens of different ways to form connections with your computer: they can send it mail, they can access a WWW server, and they can look up the names and addresses of your users. Unfortunately, each of these services can contain potential security holes, both as the result of bugs, and because of fundamental shortcomings in the services themselves.
Over the years many security problems have been discovered in network services, and workable solutions have been found. Unfortunately, some UNIX vendors have been slow to incorporate these security-related fixes into their standard offerings. If you are the system manager of any UNIX computer that is connected to a network, you must therefore be aware of the security failings of your own computer, and take appropriate measures to counteract them. To do so, you first need to understand how the UNIX operating system works with the Internet.
This chapter is not a definitive description of the TCP/IP services offered by UNIX. Instead, it presents a brief introduction to the various services, and describes security-related concerns of each. For a more definitive discussion, we recommend the following books:
Building Internet Firewalls, by D. Brent Chapman and Elizabeth D. Zwicky (O'Reilly & Associates, 1995).
Managing Internet Information Services,by Cricket Liu, Jerry Peek, Russ Jones, Bryan Buus, and Adrian Nye (O'Reilly & Associates, 1994).
DNS and BIND, by Paul Albitz and Cricket Liu (O'Reilly & Associates, 1992).
sendmail, by Bryan Costales, with Eric Allman and Neil Rickert (O'Reilly & Associates, 1993).
UNIX Network Programming, by W. Richard Stevens (Prentice Hall, 1990).
Most UNIX network services are provided by individual programs called servers. For a server to operate, it must be assigned a protocol (TCP or UDP), be assigned a port number, and be started when the system boots or as needed, as we'll describe in "Starting the Servers" below.
The /etc/services file is a relational database file. Each line of the /etc/services file consists of a service name, a network port number, a protocol name, and a list of aliases. A rather extensive list of Internet services, including their uses on UNIX systems, their security implications, and our recommendations as to whether or not you should run them, appears in Appendix G, Table of IP Services.
The /etc/services file is referenced by both Internet client programs and servers. The information in the /etc/services file comes from Internet RFCs[1] and other sources. Some of the services listed in the /etc/services file are no longer in widespread use; nevertheless, their names still appear in the file to prevent the accidental reassignment of their ports in the event that the services are still used somewhere on the global network.
[1] RFC stands for Request For Comment. The RFCs describe many of the actual standards, proposed standards, and operational characteristics of the Internet. There are many online sources for obtaining the RFCs.
The following is an excerpt from the /etc/services file that specifies the Telnet, SMTP, and Network Time Protocol (NTP) services:
# /etc/services # telnet 23 /tcp smtp 25 /tcp mail time 37 /udp timeserver ...
UNIX servers should determine their port numbers by looking up each port in the /etc/services file using the UNIX system call getservicebyname(). The /etc/services file can be supplemented or replaced by distributed database systems such as NIS, NIS+, Netinfo, or DCE Most of these systems patch the system's getservicebyname() system call, so that they are transparent to the application.
Some programmers bypass this system call and simply hard-code the service number into their programs. Thus, if you make a change to a program's port number in the /etc/services file, the server may or may not change the port to which it is listening. This can result in significant problems if a change is necessary, although well-known services seldom change their ports.
There are fundamentally two kinds of UNIX servers:
Servers that are always running. These servers are started automatically from the /etc/rc* files when the operating system starts up.[2] Servers started at boot time are usually the servers that should provide rapid responses to user requests, must handle many network requests from a single server process, or both. Servers in this category include nfsd (Network Filesystem daemon) and sendmail.
[2] On System V-derived operating systems, such as Solaris 2.x, these servers are usually started by an entry in a file located inside the /etc/rc2.d/ directory.
Servers that are run only when needed. These servers are usually started from inetd, the UNIX "Internet" daemon. inetd is a flexible program that can listen to dozens of Internet ports and automatically start the appropriate daemon as needed. Servers started by inetd include popper (Post Office Protocol daemon) and fingerd (the finger daemon).
Servers that are always running are usually started by a command in the /etc/rc* files. For example, the lines in the /etc/rc file that start up the Simple Mail Transfer Protocol (SMTP) server looks like this:
if [ -f /usr/lib/sendmail -a -f /etc/sendmail/sendmail.cf ]; then /usr/lib/sendmail -bd -q1h && (echo -n ' sendmail') > /dev/console fi
This example checks for the existence of /usr/lib/sendmail and the program's control file, /etc/sendmail/sendmail.cf. If the two files exist, /etc/rc runs the sendmail program and prints the word "sendmail" on the system console. After the program is running, sendmail will bind to TCP/IP port number 25 and listen for connections.[3]
[3] The option -bd makes the sendmail program "be a daemon" while the option -q1h causes the program to process the mail queue every hour.
Each time the sendmail program receives a connection, it uses the fork()system call to create a new process to handle that connection. The original sendmail process then continues listening for new connections.
The first version of UNIX to support the Internet, BSD 4.2, set a different server program running for every network service.[4] As the number of services grew in the mid-1980s, UNIX systems started having more and more server programs sleeping in the background, waiting for network connections. Although the servers were sleeping, they nevertheless consumed valuable system resources such as process table entries and swap space. Eventually, a single program called /etc/inetd (the Internet daemon) was developed, which listened on many network ports at a time and ran the appropriate TCP-based or UDP-based server on demand when a connection was received.
[4] BSD 4.1a was an early test release of UNIX with TCP/IP support. BSD 4.2, released in September 1983, was the first non-test release with TCP/IP support.
inetd is run at boot time as part of the start-up procedure. When it starts execution, it examines the contents of the /etc/inetd.conf file to determine which network services it is supposed to manage. inetd uses the bind() call to attach itself to many network ports and then uses the select() call to cause notification when a connection is made on any of the ports.
A sample inetd.conf file might look like this:
# @(#)inetd.conf 1.1 87/08/12 3.2/4.3NFSSRC # # Internet server configuration database # ftp stream tcp nowait root /usr/etc/ftpd ftpd telnet stream tcp nowait root /usr/etc/telnetd telnetd shell stream tcp nowait root /usr/etc/rshd rshd login stream tcp nowait root /usr/etc/rlogind rlogind exec stream tcp nowait root /usr/etc/rexecd rexecd uucp stream tcp nowait uucp /usr/etc/uucpd uucpd finger stream tcp nowait nobody /usr/etc/fingerd fingerd tftp dgram udp wait nobody /usr/etc/tftpd tftpd comsat dgram udp wait root /usr/etc/comsat comsat talk dgram udp wait root /usr/etc/talkd talkd ntalk dgram udp wait root /usr/etc/ntalkd ntalkd echo stream tcp nowait root internal discard stream tcp nowait root internal chargen stream tcp nowait root internal daytime stream tcp nowait root internal time stream tcp nowait root internal echo dgram udp wait root internal discard dgram udp wait root internal chargen dgram udp wait root internal daytime dgram udp wait root internal time dgram udp wait root internal
Each line contains at least six fields, separated by spaces or tabs:
The service name that appears in the /etc/services file. inetd uses this name to determine which port number it should listen to.
Whether the service expects to communicate via a stream or on a datagram basis.
Whether the service expects to use TCP- or UDP-based communications. TCP is used with stream sockets, while UDP is used with dgram, or datagrams.
If the entry is "wait," the server is expected to process all subsequent connections received on the socket. If "nowait" is specified, inetd will fork() and exec()a new server process for each additional datagram or connection request received. Most UDP services are wait, while most TCP services are nowait, although this is not a firm rule. Although some man pages indicate that this field is only used with datagram sockets, the field is actually interpreted for all services.
Specifies the UID that the server process is to be run as. This can be root (UID 0), daemon (UID 1), nobody (often UID -2 or 65534), or an actual user of your system. This field allows server processes to be run with fewer permissions than root, to minimize the damage that could be done if a security hole is discovered in a server program.
The remaining arguments specify the command name to execute and the arguments that the command is passed, starting with argv[0].
Some services, like echo, time, and discard, are listed as "internal." These services are fairly trivial, and they are handled internally by inetd rather than requiring a special program to be run. Although these services are useful for testing, they can also be used for denial of service attacks. You should disable them.
You should routinely check the entries in the /etc/inetd.conf file and verify that you understand why each of the services in the file is being offered to the Internet. Sometimes, when attackers break into systems, they create new services to make future break-ins easier. If you cannot explain why a service is being offered at your site, you may wish to disable it until you know what purpose it serves.