From a packet filtering point of view, what do the packets associated with particular services look like? As an example, we're going to take a detailed look at Telnet. Telnet allows a user to log in to another system, as if the user had a terminal directly connected to that system. We use Telnet as an example because it is fairly common, fairly simple, and from a packet filtering point of view, representative of several other protocols such as SMTP and NNTP. We show both outbound and inbound Telnet service.
For detailed discussions of the packet filtering characteristics of other protocols, see the chapters in Part III, "Internet Services".
The TCP destination port is 23; that's the well-known port number Telnet servers use.
The TCP source port is 23; that's the port the server uses.
The TCP destination port is the same "Y" we used as the source port for the outgoing packets.
Why is the client port -- the source port for the outgoing packets, and the destination port for the incoming packets -- restricted to being greater than 1023? This is a legacy of the BSD versions of Unix, the basis for almost all Unix networking code. BSD Unix reserved ports from to 1023 for local use only by root. These ports are normally used only by servers, not clients, because servers are run by the operating system as privileged users, while clients are run by users. (The major exceptions are the BSD "r" commands like rcp and rlogin, as we'll discuss in Section 18.1, "Terminal Access (Telnet)".) Because TCP/IP first became popular on Unix, this convention spread to other operating systems, even those that don't have a privileged root user (for instance, Macintosh and MS-DOS systems). No actual standard requires this behavior, but it is still consistent on almost every TCP/IP implementation. When client programs need a port number for their own use, and any old port number will do, the programs are assigned a port above 1023. Different systems use different methods to allocate the numbers, but most of them are either pseudo-random or sequential.
The incoming packets for the inbound Telnet service contain the user's keystrokes and have the following characteristics:
The TCP source port is some random port number greater than 1023 (which we'll call "Z" in this example).
The IP packet type is TCP.
The TCP source port is 23 (these packets are from the Telnet server).
The TCP destination port is the same random port "Z" that was used as the source port for the inbound packets.
Service Direction | Packet Direction | Source Address | Dest. Address | Packet Type | Source Port | Dest.Port | ACKSet |
---|---|---|---|---|---|---|---|
Outbound | Outgoing | Internal | External | TCP | Y | 23 |
[18]
|
Outbound | Incoming | External | Internal | TCP | 23 | Y | Yes |
Inbound | Incoming | External | Internal | TCP | Z | 23 | |
Inbound | Outgoing | Internal | External | TCP | 23 | Z | Yes |
[18]The TCP ACK bit will be set on all but the first of these packets, which establishes the connection.Note that Y and Z are both random (from the packet filtering system's point of view) port numbers above 1023.
If you want to allow outgoing Telnet, but nothing else, you would set up your packet filtering as follows.
Rule | Direction | Source Address | Dest. Address | Protocol | Source Port | Dest. Port | ACK Set | Action |
---|---|---|---|---|---|---|---|---|
A | Out | Internal | Any | TCP | >1023 | 23 | Either | Permit |
B | In | Any | Internal | TCP | 23 | >1023 | Yes | Permit |
C | Either | Any | Any | Any | Any | Any | Either | Deny |
Suppose you mistakenly assume that the source port is associated with a particular service. Someone who is in control of the source machine (e.g., someone with root access on a Unix system, or anyone at all with a networked PC) could run whatever client or server he or she wanted on a "source port" that you're allowing through your carefully configured packet filtering system. Furthermore, as we've discussed previously, you can't necessarily trust the source address to tell you for certain what the source machine is; you can't tell for sure if you're talking to the real machine with that address, or to an attacker who is pretending to be that machine.
What can you do about this situation? You want to restrict the local port numbers as much as possible, regardless of how few remote ports you allow to access them. If you only allow inbound connections to port 23, and if port 23 has a Telnet server on it that is trustworthy (a server that will only do things that a Telnet client should be able to tell it to do), it doesn't actually matter whether or not the program that is talking to it is a genuine Telnet client. Your concern is to limit inbound connections to only ports where you are running trustworthy servers, and to be sure that your servers are genuinely trustworthy. Part III, "Internet Services" discusses how you can achieve these goals for various services.
This problem is particularly bad for servers that use ports above 1023 because you need to allow packets in to those ports in order to let in traffic bound for clients. For instance, in the preceding example, we allow inbound packets for any port over 1023 from source port 23. This would allow an attacker to run anything at all on port 23 (for instance, an X Window System client) and send packets to any server above port 1023 (for instance, an X Window System server). We avoided this problem in our example by using the ACK bit to accept inbound packets but not inbound connections. With UDP, you have no such option, because there is no equivalent to the ACK bit. Fortunately, relatively few important UDP-based protocols are used across the Internet. (The notable exception is DNS, which is discussed further in Section 20.1, "Domain Name System (DNS)".)