As delivered by most vendors, Unix is a friendly and trusting operating system. By default, network services are offered to every other computer on the network. Unfortunately, this practice is not an advisable policy in today’s networked world. While you may want to configure your network server to offer a wide variety of network services to computers on your organization’s internal network, you probably want to restrict the services that your computer offers to the outside world.
A few Unix servers have built-in facilities for limiting access based on the IP address or hostname of the computer making the service request.[137] For example, NFS allows you to specify which hosts can mount a particular filesystem, and nntp allows you to specify which hosts can read Netnews. Unfortunately, these services are in the minority: most Unix servers have no facility for controlling access on a host-by-host or network-by-network basis.
There are several techniques that you can use to control access to servers that do not provide their own systems for access control. These include:
You can use the TCP Wrapperss program (developed by Wietse Venema) to control access to specific services according to rules located in the /etc/hosts.allow and /etc/hosts.deny files.[138] The TCP Wrappers program can log incoming connections via syslog—whether or not the actual Internet daemon provides logging. TCP Wrappers also allows different server executables to be invoked for a given service depending on the source IP address of the incoming connection.
While TCP Wrappers can be run as a standalone program, today it is most commonly used as a library (libwrap) that is linked into the inetd program. By using a modern inetd program, your system will automatically honor the /etc/hosts.allow and /etc/hosts.deny files, which are described later.
You can use a host-based firewall program, such as ipfw, to block access to specific servers from specific networks. Rules for host-based firewalls are typically loaded into the Unix kernel when the system boots, although the rules can be fine-tuned and otherwise changed while the system operates.
You can place a standalone firewall appliance between your server and the outside network. A firewall can protect an entire network, whereas TCP Wrappers and ipfw can protect only services on a specific machine. Firewalls are an added expense and, in many cases, can be more difficult to configure than TCP Wrappers or ipfw.
We see TCP Wrappers, ipfw, and standalone firewalls as complementary technologies, rather than competing ones. For example, you can run TCP Wrappers on each of your computers to protect specific services, implement general-purpose rules with ipfw, and then protect your entire network with a firewall. This combination is an example of defense in depth , the philosophy of not depending on one particular technology for all of your protection.
In the following sections, we will continue the discussion of using TCP Wrappers and ipfw.
The TCP Wrappers system is built into modern versions of the inetd program, the SSH server, and many other programs. It is included as a standalone program called tcpd on many Unix systems, including Linux, Solaris 9, BSD derivatives, and Mac OS X. If you do not have the TCP Wrappers system on your computer, fear not: you can download it from the Internet and easily install it on your computer, even if you do not have source code to your network utilities. This is one of the advantages of being a wrapper.
The TCP Wrappers system gives the system administrator a high degree of control over incoming TCP connections. The system is invoked after a remote host connects to your computer. It is invoked either through a subroutine library that is linked into the Internet server or through a standalone program started up through inetd. Once running, the TCP Wrappers system performs the following steps:
It opens the /etc/hosts.allow file. This file contains access control rules and actions for each protocol.
It scans through the file, line by line, until it finds a rule that matches the particular protocol and source host that has connected to the server.
It executes the action(s) specified in the rule. If appropriate, control is then turned over to the network server.
If no matching action is found, the file /etc/hosts.deny is opened and sequentially read line by line. If a matching line is found, access is denied and the corresponding action performed.
If no match is found in either the /etc/hosts.allow or the /etc/hosts.deny file, then the connection is allowed by default.
If this seems overly complicated to you, you are right—it is. The reason for having two files, /etc/hosts.allow and /etc/hosts.deny, is to allow for backward compatibility with previous versions of TCP Wrapperss that did not provide for different kinds of actions on each line of the file. These earlier versions simply had a list of allowed hosts for each protocol in the file /etc/hosts.allow and a list of hosts to deny for each protocol in the file /etc/hosts.deny. These days, TCP Wrapperss is compiled with the -DPROCESS_OPTIONS option, which causes the advanced rules to be properly interpreted. Unfortunately, as is often the case, the complexity of having two incompatible modes of operation remains to allow for backward compatibility.
If you’re using a version of TCP Wrapperss that was compiled with -DPROCESS_OPTIONS (as nearly all versions distributed with modern Unix systems are), you should put all your rules into /etc/hosts.allow. Your /etc/hosts.deny should contain only a single rule “ALL:ALL” to deny all access by default. Keeping all the rules in a single file simplifies maintenance. Using /etc/hosts.allow, which has priority over /etc/hosts.deny, ensures that if someone else accidentally modifies the wrong file, it won’t override your rules.
The actions implemented by TCP Wrappers are quite sophisticated. Specifically, options can:
Compare the incoming hostname and requested service with an access control list to see if this host or this combination of host and service has been explicitly denied. If either is denied, TCP Wrappers drops the connection.
Log the results with syslog. (For further information, see Chapter 21.)
Use the ident protocol (RFC 1413)[139] to determine the username associated with the incoming connection. (For further information, see Chapter 11.)
Optionally send a “banner” to the connecting client. Banners are useful for displaying legal messages or advisories.
Optionally run an auxiliary command. (For example, you can have TCP Wrappers run finger to get a list of users on a computer that is trying to contact yours.)
Perform a double reverse lookup of the IP address, making sure that the DNS entries for the IP address and hostname match. If they do not, this fact is logged. (By default, TCP Wrappers is compiled with the -DPARANOID option, so the program will automatically drop the incoming connection if the two do not match under the assumption that something somewhere is being hacked.)
Transfer control to a “jail” or “faux” environment where you study the user’s actions.[140]
Pass control of the connection to the “real” network daemon, or pass control to some other program that can take further action.
The TCP Wrappers system allows you to make up for many deficiencies in other network daemons. You can add logging to services that are not otherwise logged, add sophisticated and easily changeable access control lists, and even substitute different versions of a service daemon depending on the calling host. These are some of the reasons that the TCP Wrappers system has become standard on both free and commercial Unix offerings in recent years.
The TCP Wrappers system has a simple but powerful language and a pair of configuration files that allow you to specify whether incoming connections should be accepted.
If TCP Wrappers is compiled with the -DPROCESS_OPTIONS flag, then each line of the /etc/hosts.allow and /etc/hosts.deny files have the following format:
daemon_list:client_host_list:option[ :option...]
Alternatively, if TCP Wrappers is compiled without the -DPROCESS_OPTIONS flag, then each line in the /etc/hosts.allow and /etc/hosts.deny files has the following format:[141]
daemon_list : client_host_list [: shell_command]in which:
daemon_list
Specifies the command name (argv[0]) of a list of TCP daemons (e.g., telnetd). More than one daemon can be specified by separating them with blanks or commas. The reserved keyword “ALL” matches all daemons; “ALL EXCEPT” matches all daemons except for the specific one mentioned (e.g., “ALL EXCEPT in.ftpd“).
client_host_list
Specifies the hostname or IP address of the incoming connection. More than one host can be specified by separating them with blanks or commas. Incomplete hostnames and IP addresses can be used for wildcarding (see Table 12-1 for information). You can also use the format username@hostname to specify a particular user on a remote computer, although the remote computer must correctly implement the ident protocol.[142] The keyword ALL matches all clients; for a full list of keywords, see the table.
option [ : option ...]
Specifies one or more options that are executed for the particular service. For a full list of options, see Table 12-2.
shell_command
Specifies a command that should be executed if the
daemon_list and
client_host_list are matched. A
shell_command can be specified directly in
the /etc/hosts.allow or
/etc/hosts.deny file if TCP Wrappers is compiled
without the -DPROCESS_OPTIONS flag. If TCP Wrappers is compiled with
the -DPROCESS_OPTIONS flag, shell commands must be specified with the
spawn option. A limited amount of token
expansion is available within the shell command; see Table 12-3 for a list of the tokens that are available.
Table 12-1. Syntax for the “hosts” field in the tcpwrappers /etc/hosts.allow and /etc/hosts.deny files
|
Hostname as it appears in the /etc/hosts.allow or /etc/hosts.deny file |
Has the following effect |
|---|---|
|
ALL |
Matches all hosts. |
|
KNOWN |
Matches any IP address that has a corresponding hostname; also matches usernames when the ident service is available. |
|
LOCAL |
Matches any host that does not have a period (.) in its name. |
|
PARANOID |
Matches any host for which double reverse-hostname/IP address translation does not match. |
|
UNKNOWN |
Matches any IP address that does not have a corresponding hostname; also matches usernames when the ident service is not available. |
|
host.domainhost.subdomain.domainhost.sub1.sub2.domain |
Matches the specific hostname. |
|
.subdomain.domain |
If the hostname begins with a period (.), the hostname will match any host whose hostname ends with the hostname (in this case, ".subdomain.domain“). |
|
iii.jjj.kkk.lll |
Matches the specific IP address iii.jjj.kkk.lll (e.g., 192.168.1.13). |
|
iiiiii.jjjiii.jjj.kkkiii.jjj.kkk.lll |
If the hostname ends with a period (.), the hostname is interpreted as the beginning of an IP address. The string “18.” will match any host with an IP address of 18.0.0.1 through 18.255.255.254. The string “192.168.1.” will match any host with an IP address of 192.168.1.0 through 192.168.1.255. |
|
a pattern EXCEPT another pattern |
Matches any host that is matched by a pattern except those that also match another pattern.[a] |
[a] The EXCEPT operator may also be used for specifying an Internet service. | |
Table 12-2. Options available for TCP Wrapperss when compiled with -DPROCESS_OPTIONS
|
Option |
Effect |
|---|---|
|
|
Allows the connection. |
|
|
Denies the connection. |
|
Options for dealing with sub-shells | |
|
|
Changes the priority of the process to
|
|
|
Sets the environment variable
|
|
|
Runs the |
|
|
Runs the |
|
|
Specifies the |
|
|
Assumes the privileges of
|
|
|
Assumes the privileges of |
|
Options for dealing with the network connection | |
|
|
Specifies a directory that contains banner files. If a filename is found in the banner directory that has the same name as the network server (such as telnetd), the contents of the banner file are sent to the client before the TCP connection is turned over to the server. This process allows you to send clients messages—for example, informing them that unauthorized use of your computer is prohibited. |
|
|
Causes the Unix kernel to periodically send a message to a client process; if the message cannot be sent, the connection is automatically broken. |
|
|
Specifies how long the Unix kernel should spend trying to send a message to the remote client after the server closes the connection. |
|
|
Specifies that the ident protocol should be used
to attempt to determine the username of the person running the client
program on the remote computer. The
|
Table 12-3. Token expansion available for the TCP Wrappers shell command
|
Token |
Mnemonic |
Expands to |
|---|---|---|
|
|
Address |
The IP address of the client |
|
|
Address |
The IP address of the server (useful if the server system has more than one network interface) |
|
|
Client info |
username@hostname (if username is available); otherwise, only hostname or IP address |
|
|
Daemon name |
The name of the daemon (argv[0]) |
|
|
Hostname |
The hostname of the client (IP address if hostname is unavailable) |
|
|
Hostname |
The hostname of the server (IP address if hostname is unavailable) |
|
|
Process |
The process ID of the daemon process |
|
|
Server info |
daemon@host |
|
|
User |
The client username (or unknown) |
|
|
Percent |
Expands to the "%" character |
The TCP Wrappers system is vulnerable to IP spoofing because it uses IP addresses for authentication. In practice, this is not a significant concern, because most TCP protocols require bidirectional communications to do anything useful. Furthermore, most TCP/IP implementations now use unpredictable sequence numbers, significantly reducing the chances of a successful spoofing attack.
TCP Wrappers also provides only limited support for UDP servers, because once the server is launched, it will continue to accept packets over the network, even if those packets come from “blocked” hosts, unless the UDP server is linked with the TCP Wrappers library and has been specially written to consult the TCP Wrappers access control lists after each new request is received.
For examples of using TCP Wrappers, see Section 12.5 at the end of this chapter.
The configuration files we have shown so far are simple; unfortunately, sometimes things get more complicated. The TCP Wrappers system comes with a utility called tcpdchk that can scan through your configuration file and report on a wide variety of potential configuration errors. This is important because the TCP Wrappers system relies on many configuration files (/etc/services, /etc/inetd.conf, /etc/hosts.allow, and /etc/hosts.deny) and requires that the information between these files be consistent.
Here is an example of using the tcpdchk program; each line in this example represents a potential security problem:
% tcpdchk
warning: /etc/hosts.allow, line 24: ipop3d: no such process name in /etc/inetd.conf
warning: /etc/hosts.allow, line 39: sshd: no such process name in /etc/inetd.confWe’ll explore these “warnings” one at a time.
The first line of output refers us to line 24 of the file /etc/hosts.allow, which is shown here:
ipop3d : ALL : ALLOW
To understand the error no such process name in /etc/inetd.conf, we need to now refer to the file
/etc/inetd.conf. This file has a line for the
ipop3d daemon, but as the warning from
tcpdchk implies, the process is not named
ipop3d—it is named
popper:
# example entry for the optional pop3 server # ------------------------------ pop3 stream tcp nowait root /usr/local/libexec/ipop3d popper
We must either change line 24 to refer to the process name popper, or change the entry in /etc/inetd.conf to use the name ipop3d. We’ll change the file /etc/hosts.allow and rerun the tcpdchk program. Here is the new line 24:
popper : ALL : ALLOW
Now let’s rerun the tcpdchk program:
r2# tcpdchk
warning: /etc/hosts.allow, line 24: popper: service possibly not wrapped
warning: /etc/hosts.allow, line 39: sshd: no such process name in /etc/inetd.conf
r2#We are now told that the service is “possibly not wrapped.” This is because tcpdchk is reading through the /etc/inetd.conf file and looking for “tcpd,” the name of the TCP Wrappers executable. Because support for TCP Wrappers is compiled into the version of inetd that this computer is using, tcpd is not used, so tcpdchk reports a warning (which we ignore).
The second warning is that there is a rule in the /etc/hosts.allow file for the sshd service, but there is no matching daemon listed in the /etc/inetd.conf file. This is actually not an error: the sshd service is started up directly at boot time, not by inetd. Nevertheless, the program is linked with the TCP Wrappers library and honors the commands in the /etc/hosts.allow file.
The TCP Wrappers system comes with another utility program called tcpdmatch, which allows you to simulate an incoming connection and determine if the connection would be permitted or blocked with your current configuration files. In the following example, we will see if the user simsong@k1.vineyard.net is allowed to ssh into our machine:
r2# tcpdmatch
usage: tcpdmatch [-d] [-i inet_conf] daemon[@host] [user@]host
-d: use allow/deny files in current directory
-i: location of inetd.conf file
r2# tcpdmatch sshd simsong@k1.vineyard.net
warning: sshd: no such process name in /etc/inetd.conf
client: hostname K1.VINEYARD.NET
client: address 204.17.195.90
client: username simsong
server: process sshd
matched: /etc/hosts.allow line 39
option: allow
access: granted
r2#Ignoring the warning in the first line, we can see that permission would be granted by line 39 of the /etc/hosts.allow file. This line reads:
sshd : ALL : allow
Programs such as tcpdchk and tcpdmatch are excellent complements to the security program TCP Wrappers because they help you head off security problems before they happen. Wietse Venema should be complimented for writing and including them in his TCP Wrappers release; other programmers should follow his example.
Many Unix-based systems contain a built-in packet firewall. The firewall is controlled with rules that are loaded into the kernel at runtime. Rules can block or allow packets to flow based on packet type, host, protocol, and even packet-level flags. Using these rules, you can implement a broad variety of policies for traffic, such as:
Disallow all incoming traffic by default, but permit a few exceptions, such as allowing anyone to make an HTTP connection to port 80, and a list of predefined hosts to make an SSH connection to port 22. This “deny everything that isn’t permitted” approach is a recommended security practice.
Allow all incoming traffic, except from those hosts specifically excluded. (This “allow everything that isn’t prohibited” strategy is not a good security practice, but is surprisingly common.)
Allow outgoing HTTP connections to anywhere on the Internet, but allow incoming connections only from a few select hosts.
Log firewall violations for later analysis.
Traditionally, Linux systems based on the 2.2 kernel have used the ipchains IP firewall, Linux systems based on the 2.4 kernel have used the netfilter IP firewall (also called iptables), and BSD-based systems (including Mac OS X) have used the ipfirewall (also called ipfw, ipf, and pf). Although these systems were developed for Linux and BSD computers serving as routers and firewalls, they can be used with great success on systems that have a single Ethernet interface. Solaris systems have used the public domain ipfilter, which must be added to the Solaris kernel by the end user, Solaris now ships with a firewall product called SunScreen.
The rules that you add to the kernel with a packet-level firewall are in addition to any access control rules that you might implement with the TCP Wrappers system (or another system). They are also in addition to any external firewall that may be protecting the network that the host is on. The kernel-level firewall can give you an additional layer of protection and is an important part of a defense-in-depth strategy.
The primary disadvantage of packet-level firewalls is that they consume some CPU power; this can be a special concern on systems that are heavily loaded and in cases where the rule sets are very long—the added CPU requirements may be more than your system can handle! For most situations, however, packet-level firewalls do not place an excessive burden on the system, as they tend to be quite efficient; if your system has some CPU power to spare, you will not notice their overhead. Indeed, many people dramatically overestimate the amount of CPU power necessary for a Unix-based computer to act as a firewall. For example, FreeBSD running on an Intel-based 486 at 33 MHz can easily handle the traffic of a fully loaded T1 or DSL line.
A second disadvantage of packet-level firewalls is that they can be too good: you might implement a firewall at one point, and then many months later spend hours (or days) trying to get a network service to work—a service that is specifically disallowed by the firewall. In one case, it took one of the authors of this book six months to realize that the Amanda tape backup system wouldn’t work on his home computer was because the Amanda control packets were being specifically disallowed by his host-based firewall.
This section describes the ipfw host-based firewall that is part of BSD-based systems such as FreeBSD and Mac OS X. Although the commands discussed are specific to ipfw, the concepts are applicable to any host-based packet firewall system.
The firewall consists of code that is linked into the BSD kernel and a series of rules that are loaded into the kernel’s memory space at runtime. Each rule consists of a rule number, a filter specification, and an action. Rules are applied to all packets, whether the packets are passed from one interface to another (in the case of a Unix system that is acting as a router or gateway) or are passed from an interface to an application program (in the case of a Unix system that is acting as a network client or server).
The two most widely used Linux firewall systems each behave differently in the way that rules are specified. ipchains applies rules in the INPUT chain to all packets arriving at the firewall, applies the FORWARD chain to packets passing through the firewall between two other hosts, and applies the OUTPUT chain to packets leaving the firewall. A packet passing though the firewall between two other hosts traverses all the chains.
Under iptables, on the other hand, the INPUT chain is applied only to packets destined for the firewall host itself, the FORWARD chain to packets between two other hosts passing through the firewall, and the OUTPUT chain to packets originating from the firewall itself and destined elsewhere. Packets typically traverse only one of these chains.
Rules are evaluated in order until a matching rule is found, at which time the rule’s action is executed. Some actions terminate the rule search for a particular packet, while other actions cause the system to look for the next matching rule.
Rules are controlled using the ipfw command. Typical commands are:
number
rule
Adds a rule to the kernel’s tables. The
number is used to order rules (lower
numbered rules execute first) and to delete individual rules.
number
Deletes a numbered rule from the kernel’s tables.
Lists all of the current rules.
Removes all rules.
There are many more commands beyond these. What’s more, the syntax and subcommands of the ipfw command vary slightly from system to system. For this reason, it is vital that you consult the ipfw (or iptables or ipchains) manpage for your operating system for a complete list. Furthermore, you should always have physical access to a computer on which you are running the ipfw command and be in a position where you can reboot the computer without any hesitation. By typing the wrong command, it is very easy to leave the computer in a state such that it is unable to send or receive packets on the network.
Filters for the ipfw command can be constructed using any or all of the following criteria:
Transmit and receive interface
Direction
Protocol
Source and destination IP address
IP fragment flag
IP options
ICMP types
Source and destination TCP or UDP port
TCP flags (e.g., SYN, ACK, etc.)
User and group of the socket associated with the packet.
Some typical actions are shown in Table 12-4.
Table 12-4. Some rule actions implemented by ipfw
|
Action |
Meaning |
|---|---|
|
|
Allow packets that match the rule to be passed to their destination. |
|
|
Discard packets that match the rule. |
|
|
Discards packets that match the rule and sends an ICMP host unreachable packet to the packet’s source address. |
|
|
Discards packets that match the rule and sends an ICMP unreachable
notice with code |
|
|
Discards packets and sends a TCP reset to the sender. |
|
|
Counts the number of packets that match the rule. This rule does not terminate the rule-matching logic. |
|
|
Allows packets that match the rule to be passed to their destination,
but sends a copy of the packet to the port
|
|
|
Accepts the packet, but instead of sending it to the correct
destination, sends it to |
|
|
Logs the packet through syslog. |
Rules can also be assigned a probability so that they will be invoked only a certain percentage of the time. Although this is not tremendously useful for security applications, it can be useful in simulating conditions of heavy network congestion.[143]
Example 12-3 shows a typical script that starts up a simple ipfwl script that is used on a computer that has two Ethernet interfaces—one on the organization’s internal network, one on the external Internet. (Despite the fact that the computer has two Ethernet interfaces, it is not configured to forward packets from one interface to another.) In this example, the internal network is the subnet 192.168.1.0/24. Note that all actual Internet addresses have been replaced with Net 10. addresses to protect the privacy of the guilty.
The 300-series rules open the firewall so that any packet to or from the organization’s internal network is allowed to pass freely.
The 400-series rules are filters that have been added to block Internet traffic from hosts that, in the opinion of the site’s operator, have shown a history of bad actions. In one case, one of the blocked sites was responsible for large amounts of unwanted email. In another case, computers at the IP address launched a series of attacks against one of the organization’s nameservers in an attempt to appropriate a valuable domain name. Rather than continually reading about these attacks in the system logs, it was easier to block their packets.
The 500-series rules allow a select number of protocols from anywhere else on the Internet. Note that the packets from the hosts mentioned in the 400-series rules will not be accepted because the 400-series rules execute before the 500-series rules.
The remaining rules specify a variety of policies for the site in question. Of particular interest are rules 1001 and 1002, which allow remote database connections from a particular subnet but nowhere else on the Internet, and rule 2001, which blocks all incoming TCP connections that are not specifically allowed by the other rules in the firewall ruleset. The net effect of rule 2001 is that any attacker who sets up a rogue TCP/IP server will find that his service is blocked by the system’s kernel. (Of course, a knowledgeable attacker who achieves superuser status can use the ipfw command to remove rule 2001; if you have a knowledgeable attacker who has achieved superuser status, you have bigger problems to worry about.)
Example 12-3. A typical ipfw initialization script
case $1 in
start)
#
# Allow anything from internal network.
ipfw add 301 allow ip from 192.168.1.0/24 to any
#
# General stuff to block specific attackers out there
ipfw add 460 deny ip from 10.101.236.0/24 to any
ipfw add 461 deny ip from 10.192.228.15 to any
ipfw add 462 deny ip from 10.211.39.250 to any
ipfw add 463 deny ip from 10.20.20.1 to any
ipfw add 464 deny ip from 10.60.89.18 to any
# Allow SSH, SMTP, HTTP, HTTPS, and POP in from anywhere else.
ipfw add 500 allow tcp from any to any 22,25,80,443,110
# Allow DNS from anywhere else.
ipfw add 510 allow tcp from any to any 53
ipfw add 510 allow udp from any to any 53
# Deny syslog.
ipfw add 600 deny udp from any to any 514
# Allow only X to our friends.
ipfw add 700 allow tcp from 10.7.15.234/28 to any 6000-6063
ipfw add 701 allow tcp from 10.175.193.176/28 to any 6000-6063
ipfw add 702 deny tcp from any to any 6000-6063
# MySQL clients from a particular site on the network
ipfw add 1001 allow tcp from 199.175.193.176/28 to any 3306
ipfw add 1002 deny tcp from any to any 3306
# LPD defenses
ipfw add 1010 deny tcp from any to any 515
# SunRPC defenses
ipfw add 1020 deny tcp from any to any 111
# imap only from internal network
ipfw add 1030 deny tcp from any to any 143
# imaps, pops, and smtps from any network
ipfw add 1100 allow tcp from any to any 465,993,995
# rtsp from any network
ipfw add 1101 allow tcp from any to any 554
ipfw add 1101 allow udp from any to any 554
# Allow any outgoing packet from this host.
ipfw add 2000 allow tcp from any to any out
# Deny all other incoming TCP setup packets.
ipfw add 2001 deny tcp from any to any setup
;;
stop)
;;
esac[137] Restricting a service by IP address or hostname is a fundamentally unsecure way to control access to a server. Unfortunately, because more sophisticated authentication services such as Kerberos and DCE are not in widespread use, address-based authentication is the only choice available at most sites. It is certainly better than no such restriction!
[138] These are the default locations. You can change these locations when compiling the program.
[139] RFC 1413 superseded RFC 931, but the define in the code has not changed.
[140] We won’t describe this approach further. It requires some significant technical sophistication to get right, is of limited value in most environments, and may pose some potentially significant legal problems. For further information on hacker jails, see Firewalls and Internet Security by Bill Cheswick and Steve Bellovin (Addison-Wesley), or the Honeynet Project at http://www.honeynet.org.
[141] As we indicated, these days most systems are compiled with the -DPROCESS_OPTIONS flag. However, there are still a few systems out there that are compiled without this flag, so it is important that you be familiar with both formats.
[142] And as we noted in the discussion of ident, the identification returned is not something that can always be believed.
[143] Some firewalls can further limit the rate at which a rule is triggered (e.g., no more than three times per second), which can be very useful in preventing denial of service attacks in rules that log packets.