Servers of this kind are started from a Unix system's /etc/rc files, which are shell scripts executed when the machine boots. Examples of servers typically started from /etc/rc files are those that handle NFS, SMTP, and DNS. In BSD-based versions of Unix, there are customarily a few files in /etc with names that start with "rc". (for example /etc/rc.boot). In other versions of Unix, there are customarily directories in /etc instead of files (for instance, /etc/rc0.d); the directories contain the various startup commands, each in its own little file.
In either case, you need to be careful to look at all of the startup scripts and all of the scripts they call, recursively. Usually, more than one script is run in the process of bringing a system all the way up. On modern Unix systems, those scripts often call others, sometimes through multiple levels of indirection. For example, you may find that a startup script calls another script to start up networking, and that one calls yet another script to start up file service. You may also find that startup scripts use mystical options to familiar commands (e.g., they often run ifconfig with little-used options that cause ifconfig to pick up configuration information from obscure places). Be sure that you understand these options and that you replace any that tell the machine to pick up information about itself from the network (or from services it normally provides but that you are going to turn off).
Linux and some versions of Unix have a utility called chkconfig that is used to determine whether or not services are started up. When a service is installed on a system that's using chkconfig, a startup script is also installed and always runs, but the startup script uses the chkconfig command to determine whether or not it should actually start the service. Administrators also use the chkconfig command to change or check the status of services. Different versions of the chkconfig system use different methods of storing the configuration status; some of them create files, while others store the status in the startup scripts themselves.
Some versions of Unix and Linux have a file called /etc/inittab. On these systems, the init process uses information in this file to control how the boot process is performed and to keep a number of system processes running. Normally the processes configured to be run from /etc/inittab allow interactive logins from terminal and workstation console devices. The init process will start and monitor these processes and, if configured to do so, will restart them when they terminate or die. Disabling these processes can usually be performed by commenting out the configuration line or by instructing init not to start them at all. If you change the contents of /etc/inittab, there is usually a special and operating system-dependent way to signal the init process to re-read the file.
In some versions of Unix, one of the servers that is run from the startup files is designed to restart other servers if they fail. If such a program exists on a system, it will try to start the other servers if they are removed from the startup files but not from its configuration file. Either turn off this program or be sure to remove from the program's configuration file any servers removed from the startup files. You'll notice the program when you work through the startup files.
Servers of this kind are usually run from the inetd server. (The inetd server itself, because it runs indefinitely, is started from the /etc/rc files, as described in the previous section.) The inetd server listens for requests for services specified in the /etc/inetd.conf configuration file. When it hears such a request, it starts the right server to process the request.
In a perfect world, you would like to disable everything, and then enable only the services you need. Unfortunately, if you do this, you may find that the machine is no longer able to boot. It is slightly easier to work from the other direction by disabling services you definitely don't need, and then examining the rest of the boot process and adjusting it slowly so that the machine will always boot.
One way to start this process is to take a snapshot of all the services that are running on your machine by using the netstat utility. This utility allows you to list all of the open network connections and, with additional options, the TCP and UDP network ports that have a service configured to listen or accept datagrams. The Linux netstat utility has a very useful feature that allows you to directly list the numeric process identifier and name associated with each network port. Other versions of Unix are supplied with tools, such as fuser, which will map the network ports to the numeric process identifier. You can also use the lsof utility (see Appendix B, "Tools" for information on where to get lsof ). Once the process name is known, it can be used to search through the configuration files to find where it is started.
As mentioned before, some versions of Unix and Linux include the chkconfig program that can administratively enable and disable services. The command can be used to test whether a service is turned on, to list the services that can be controlled, and to enable or disable services. These systems work because the startup file checks to see if the service should be run. Disabling a service can be as simple as using chkconfig to turn the service off. This is a convenient and standard way to disable a service, but it doesn't leave any documentation of why the service is off, and it's very easy to re-enable a service that's been disabled this way.
Although it's more work, it's a good idea to comment out the code that starts the service or to remove the startup file altogether. This will prevent people from simply turning it back on with chkconfig, and will give you a good place to put comments about why you've disabled the service. If you do disable services with chkconfig, you should be sure to keep a list in a standard place that says what services are supposed to be disabled and why. This will help keep people from re-enabling them by mistake, and it will also allow you to easily reconfirm the list if you upgrade, patch, or reinstall software, which may change the chkconfig status of services.
On other versions of Unix, you will have no choice; you will have to comment out or delete the lines that start services you don't need. You will frequently see services that are started after a check for some configuration file. If you don't want the service to run, comment out the entire code block. Don't leave the code active simply because the configuration file doesn't currently exist and the service won't currently be started. Someone or something might create the configuration file some time in the future. Commenting out the entire thing is more secure and less risky.
Commenting out lines is preferable to removing them because it leaves evidence of your intent. When you comment something out, add a comment about why you have commented it out. If you delete something, replace it with a comment about why you have deleted it. Make sure that the next person to look at the files knows that you got rid of things on purpose and doesn't helpfully "fix" it for you. If you comment out a call to another script, add a comment in that script indicating that it's not supposed to be started and why. Renaming it or commenting out its contents are also good ways to help ensure that it won't accidentally reappear.
For every service that you leave enabled, apply the same line-by-line procedure to the service's configuration files. Obviously, you want to pay particular attention to inetd 's configuration file. On most systems, this file is called /etc/inetd.conf. (On other systems, this file might be called /etc/servers or something else; check your manual pages for inetd ). If you have a daemon-watcher and have decided to leave it on, its configuration files are also particularly important.
This process will need to be repeated if you install new software or a patch, because sometimes the startup scripts are modified or replaced. Installation scripts often assume that you will want to run all the software you are installing, and will helpfully turn it on for you, in its default, insecure configuration, even when you are upgrading an old installation on which it was turned off. You will want to have good documentation about your desired configuration to refer to when you install upgrades, patches, or new software. In any case, you should certainly disconnect the system from any hostile networks before performing any software installation or patching.
You should audit the configuration files for the services you leave enabled, to be sure that they are configured appropriately. The manual page for a service is a good place to find out which configuration files are used. In the preceding list, we have already discussed the configuration files for syslogd and inetd. Checking the configuration files for the cron service is frequently overlooked. Vendors typically provide a number of housekeeping functions that are not suitable for a bastion host. In particular, you should check for places where the system log files are rotated. You will typically find that cron will attempt to rotate log files on a weekly basis and may discard information older than two weeks. We suggest that you check these housekeeping rules and bring them into alignment with your policy on how long to keep log files.
NFS services are provided by a whole set of servers; the specific set of servers, and the names of the individual servers, varies slightly from one version of Unix to the next. Look for these names or names like them:
ost of these services are started at boot time from the /etc/rc files, although some are started on demand by inetd. mountd is somewhat peculiar in that it is often started at boot time and is listed in the inetd configuration file, apparently so that it will be restarted if the copy that was started at boot time crashes for some reason.
ypupdated
Also disable these RPC-based services:
bootpd
dhcpd
You probably don't need routed on your bastion host because your bastion host is probably located on the perimeter of your network, where routing should be fairly simple. A more secure approach is to create static routes pointing to your internal networks and a default route pointing to your Internet gateway router. You do this at boot time by adding appropriate "route add" commands to the /etc/rc files.
If you must do dynamic routing on your bastion host, obtain and use a routing daemon that will provide some sort of authentication on the source of routing information. Either it should filter routes based on their source address, or it should support an authenticated routing protocol like RIP v2. If you want to use an authenticated routing protocol, be sure that your routers also support it; if you want to filter on source address, be sure to actually configure the daemon to do so. Traditionally, the most popular routing daemon of this type has been GateD, but others are now available, including Zebra. Appendix B, "Tools", has information on how to get these daemons.
For example, here is the old /etc/inetd.conf line from Great Circle Associate's system:
and here is the new /etc/inetd.conf line:finger stream tcp nowait nobody /usr/libexec/fingerd fingerd
and here are the contents of the /etc/finger_info file:finger stream tcp nowait nobody /bin/cat cat /etc/finger_info
Great Circle Associates Phone: +1 415 555 0841 Email: [email protected] For more information, or to report system problems, please send email or call.
If you're not going to provide anonymous FTP, you can probably disable your FTP server entirely; it's started on demand by inetd.
Even if you've disabled the FTP server on your bastion host, you can still use the FTP client program (typically called simply ftp) on the bastion host to transfer files to and from other systems. You'll just have to do the work from the bastion host, instead of from the other systems.
If necessary, turn off source routing separately.
You will also need to turn off IP forwarding. Turning off routing services merely keeps the machine from advertising itself as a router; it doesn't keep the machine from routing packets. Preventing the machine from routing packets requires modifications to the kernel. Fortunately, these days most Unix vendors provide supported parameters for turning off IP forwarding. Even for vendors that don't, it's about as easy as kernel patches get on most machines: turning off IP forwarding requires a change in the value of only a single kernel variable. You need to consult your vendor to find out how to turn off IP forwarding on your machines.
On some machines, turning off normal IP forwarding will not also turn off source routing; it will still be possible for an attacker to get packets through the machine. (Source routing is discussed further in Chapter 10, "Bastion Hosts".) If you are not screening out all source routed packets before they reach the bastion host, you should consult your vendor to find out how to disable source routing in addition to normal IP forwarding.