Protecting Against Intrusion Attacks

Protecting Against Intrusion Attacks

Crackers have a wide variety of tools and techniques to assist them in breaking into your computer. Intrusion attacks focus on exploiting weaknesses in your security, so the crackers can take more control of your system (and potentially do more damage) than they could from the outside.

Fortunately, there are many tools and techniques for combating intrusion attacks. This section discusses the most common break-in methods and the tools available to protect your system. Though the examples shown are specific to Red Hat Linux systems, the tools and techniques are generally applicable to any other Linux or UNIX-like operating system.

Cross-Reference?

The tripwire package, which was recently dropped from the Red Hat Linux distribution, was a good tool for detecting whether intrusion attacks have taken place. We removed the description of tripwire from this edition. However, if you are interested in installing the package on your own, you can find the description of tripwire at the Wiley Web site: www.wiley.com/legacy/compbooks/negus)

Evaluating access to network services

Red Hat Linux and its UNIX kin provide many network services, and with them many avenues for cracker attacks. You should know these services and how to limit access to them.

So what do I mean by a network service? Basically, I am referring to any task that the computer performs that requires it to send and receive information over the network using some predefined set of rules. Routing e-mail is a network service. So is serving Web pages. Your Linux box has the potential to provide thousands of services. Many of them are listed in the /etc/services file. Look at a snippet of that file:

# /etc/services:
# service-name  port/protocol  [aliases ...]   [# comment]
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source
ftp-data        20/tcp
ftp-data        20/udp
# 21 is registered to ftp, but also used by fsp
ftp             21/tcp
ftp             21/udp          fsp fspd
ssh             22/tcp                    # SSH Remote Login Protocol
ssh             22/udp                    # SSH Remote Login Protocol
telnet          23/tcp
telnet          23/udp
# 24 - private mail system
smtp            25/tcp          mail

After comment lines, you will notice three columns of information. The left column contains the name of each service. The middle column defines the port number and protocol type used for that service. The rightmost field contains an optional alias or list of aliases for the service.

As an example, let us examine the last entry in the above file snippet. It describes the SMTP (Simple Mail Transfer Protocol) service, which is the service used for delivering e-mail over the Internet. The middle column contains the text 25/tcp, which tells us that the SMTP protocol uses port 25 and uses the Transmission Control Protocol (TCP) as its protocol type.

So, what exactly is a port number? It is a unique number that has been set aside for a particular network service. It allows network connections to be properly routed to the software that handles that service. For example, when an e-mail message is delivered from some other computer to your Linux box, the remote system must first establish a network connection with your system. Your computer receives the connection request, examines it, sees it labeled for port 25, and thus knows that the connection should be handed to the program that handles e-mail (which happens to be sendmail).

Note?

A program that stays quietly in the background handling service requests (such as sendmail) is called a daemon. Usually, daemons are started automatically when your system boots up, and they keep running until your system is shut down. Daemons may also be started on an as-needed basis by xinetd, a special daemon that listens on a large number of port numbers, then launches the requested process.

I mentioned that SMTP uses the TCP protocol. Some services use UDP, the User Datagram Protocol. All you really need to know about TCP and UDP (for the purpose of this security discussion) is that they provide different ways of packaging the information sent over a network connection. A TCP connection provides error detection and retransmission of lost data. UDP doesn't check to ensure that the data arrived complete and intact; it is meant as a fast way to send non-critical information.

Disabling network services

Although there are hundreds of services (listed in /etc/services) that potentially could be available and subject to attack on your Red Hat Linux system, in reality only a few dozen services are installed and only a handful of those are on by default. Most network services are started by either the xinetd process or by a start-up script in the /etc/init.d directory.

xinetd is a daemon that listens on a great number of network port numbers. When a connection is made to a particular port number, xinetd automatically starts the appropriate program for that service and hands the connection to it.

The configuration file /etc/xinetd.conf is used to provide default settings for the xinetd server. The directory /etc/xinetd.d contains files telling xinetd what ports to listen on and what programs to start. Each file contains configuration information for a single service, and the file is usually named after the service it configures. For example, to enable the Post Office Protocol (POP) service, edit the ipop3 file and look for a section similar to the following:

service pop3
{
    socket_type           = stream
    wait                  = no
    user                  = root
    server                = /usr/sbin/ipop3d
    log_on_success       += HOST DURATION
    log_on_failure       += HOST
    disable               = yes
}

Note that the first line of this example identifies the service as pop3. This exactly matches the service name listed in the /etc/services file. You can see that the service is off by default (disable = yes). To enable POP services, change the line to read disable = no instead. Thus, the preceding example with POP services enabled would look like this:

service pop3
{
    socket_type           = stream
    wait                  = no
    user                  = root
    server                = /usr/sbin/ipop3d
    log_on_success        += HOST DURATION
    log_on_failure        += HOST
    disable               = no
}

Because most services are disabled by default, your computer is only as insecure as you make it. You can double-check that insecure services, such as rlogin and rsh, are also disabled by making sure that disabled = yes is set in the /etc/xinetd.d/rlogin and rsh files.

Tip?

You can make the remote login service active but disable the use of the /etc/host.equiv and .rhosts files, requiring rlogin to always prompt for a password. Rather than disabling the service, locate the server line in the rsh file (server = /usr/sbin/in.rshd) and add a space followed by -L at the end.

You now need to send a signal to the xinetd process to tell it to reload its configuration file. The quickest way to do that is to restart the xinetd service. As the root user, type the following from a shell:

# service xinetd restart
Stopping xinetd:         [ OK ]
Starting xinetd:         [ OK ]

That's it — you have enabled the ipop3 service. Provided that you have properly configured your mail server (see Chapter 19), clients should now be able to get their mail from your computer.

Using TCP wrappers

Completely disabling an unused service is fine, but what about the services that you really need? How can you selectively grant and deny access to these services? In previous versions of Red Hat Linux, the TCP wrapper daemon (tcpd) was used to facilitate this sort of selective access. In the current version of Red Hat Linux, TCP wrapper support has been integrated into xinetd. xinetd will look at the files /etc/hosts.allow and /etc/hosts.deny to determine when a particular connection should be granted or refused. It scans through the hosts.allow and hosts.deny files and stops when it finds an entry that matches the IP address of the connecting machine. These checks are made when connection attempts occur:

  • If the address is listed in the hosts.allow file, the connection is allowed and hosts.deny is not checked.

  • Otherwise, if the address is in hosts.deny, the connection is denied.

  • Finally, if the address is in neither file, the connection is allowed.

It is not necessary (or even possible) to list every single address that may connect to your computer. The hosts.allow and hosts.deny files enable you to specify entire subnets and groups of addresses. You can even use the keyword ALL to specify all possible addresses. You can also restrict specific entries in these files so they only apply to specific network services. Let's look at an example of a typical pair of hosts.allow and hosts.deny files.

#
# hosts.allow   This file describes the names of the hosts are
#               allowed to use the local INET services, as decided
#               by the '/usr/sbin/tcpd' server.
#
   
imapd, ipop3d: 199.170.177.
in.telnetd: 199.170.177., .glaci.com
ftpd: ALL
#
# hosts.deny    This file describes the names of the hosts which are
#               *not* allowed to use the local INET services, as
#               decided by the '/usr/sbin/tcpd' server.
#
   
ALL: ALL

The preceding example is a rather restrictive configuration. It allows connections to the imap, ipop3d, and telnet services from certain hosts, but then denies all other connections. Let's examine the files in detail.

As usual, lines beginning with a # character are comments and are ignored by xinetd when it parses the file. Each noncomment line consists of a comma-separated list of daemons followed by a colon (:) character and then a comma-separated list of client addresses to check. In this context, a client is any computer that attempts to access a network service on your system.

A client entry can be a numeric IP address (such as 199.170.177.25) or a host name (such as dexter.glaci.com) but is more often a wildcard variation that specifies an entire range of addresses. A client entry can take four different forms. The online manual page for the hosts.allow file describes them as follows:

  • A string that begins with a dot (.) character. A host name is matched if the last components of its name match the specified pattern. For example, the pattern .tue.nl matches the host name wzv.win.tue.nl.

  • A string that ends with a dot (.) character. A host address is matched if its first numeric fields match the given string. For example, the pattern 131.155. matches the address of (almost) every host on the Eindhoven University network (131.155.x.x).

  • A string that begins with an at (@) sign is treated as an NIS (formerly YP) netgroup name. A host name is matched if it is a host member of the specified netgroup. Netgroup matches are not supported for daemon process names or for client user names.

  • An expression of the form n.n.n.n/m.m.m.m is interpreted as a net/mask pair. A host address is matched if net is equal to the bitwise AND of the address and the mask. For example, the net/mask pattern 131.155.72.0/255.255.254.0 matches every address in the range 131.155.72.0 through 131.155.73.255.

The example host.allow contains the first two types of client specification. The entry 199.170.177. will match any IP address that begins with that string, such as 199.170.177.25. The client entry .glaci.com will match host names such as dexter.glaci.com or scooby.glaci.com.

Let's examine what happens when a host named daffy.glaci.com (with IP address 199.170.179.18) connects to your Red Hat Linux box using the Telnet protocol:

  1. xinetd receives the connection request.

  2. xinetd begins comparing the address and name of daffy.glaci.com to the rules listed in /etc/hosts.allow. It starts at the top of the file and works its way down the file until finding a match. Both the daemon (the program handling the network service on your Red Hat Linux box) and the connecting client's IP address or name must match the information in the hosts.allow file. In this case, the second rule that is encountered matches the request:

    in.telnetd: 199.170.177., .glaci.com
  3. Daffy is not in the 199.170.177 subnet, but it is in the glaci.com domain. xinetd stops searching the file as soon as it finds this match.

How about if Daffy connects to your box using the IMAP protocol? In this case, it matches none of the rules in hosts.allow; the only line that refers to the imapd daemon does not refer to the 199.170.179 subnet or to the glaci.com domain. xinetd continues on to the hosts.deny file. The entry ALL: ALL matches anything, so tcpd denies the connection.

The ALL wildcard was also used in the hosts.allow file. In this case, we are telling xinetd to permit absolutely any host to connect to the FTP service on the Linux box. This is appropriate for running an anonymous FTP server that anyone on the Internet can access. If you are not running an anonymous FTP site, you probably should not use the ALL flag.

A good rule of thumb is to make your hosts.allow and hosts.deny files as restrictive as possible and then explicitly enable only those services that you really need. Also, grant access only to those systems that really need access. Using the ALL flag to grant universal access to a particular service may be easier than typing in a long list of subnets or domains, but better a few minutes spent on proper security measures than many hours recovering from a break-in.

Tip?

You can further restrict access to services using various options within the /etc/xinetd.conf file, even to the point of limiting access to certain services to specific times of the day. Read the manual page for xinetd (by typing man xinetd at a command prompt) to learn more about these options.




Part IV: Red Hat Linux Network and Server Setup