14.1 TCP Wrappers

TCP Wrappers is a program and pair of configuration files that allow a SysAdmin to wrap a security layer between the raw TCP and UDP socket layer administered by /etc/inetd and the application (server) which implements each service. This TCP Wrappers layer can control which remote systems and users may access each service, preventing, for example, an unknown system from using the FTP service. TCP Wrappers also turns off any possible source routing for TCP sockets (but not UDP sockets) to eliminate most TCP protocol-level spoofing. This anti-spoofing claim assumes that you are using at least version 2.0.30 of the Linux kernel, as discussed in "Defeating TCP Sequence Spoofing" on page 246. (This source routing exploit also can be blocked in the kernel, as discussed in "Blocking IP Source Routing" on page 133.)

Note that although only services that get started by xinetd can be protected by tcpd directly, now there is a "TCP Wrappers library" (libwrap) for daemons that are not invoked by xinetd. These daemons implement TCP Wrappers by linking in the TCP Wrappers library routines which parse and honor the hosts.allow and hosts.deny configuration files. The hosts.allow and hosts.deny files should be owned by root and mode 600. This will prevent a cracker from seeing what systems you trust, that might enable him first to break into one of these and use your trust of it to break into yours.

The use of IP Chains, too, is encouraged. The IP Chains facility is discussed in "Firewalls with IP Chains and DMZ" on page 514.


Among the daemons whose recent versions support TCP Wrappers are lpd, SOCKS servers (to support other systems on your LAN using Netscape or other services), SSH, and portmap. As of this writing, the enhanced versions of lpd and SOCKS do not seem to be in popular distributions, so you might need to search the Web for them and compile and install them yourself.

Note that attacks via lpd, SOCKS, and portmap are all too common and successful so this is a valuable security option that should be exercised. Without the libwrap enhancement, both lpd and sockd rely on their own configuration files, /etc/hosts.lpd and /etc/sockd.conf, respectively, to restrict access. However, buffer overflow vulnerabilities have been found in lpd. TCP Wrappers come standard with almost all distributions now. Still, you can download the source from its author's site at


If you choose to download it yourself, you need to be careful as there were copies floating around the Web with a Trojan horse in it that took cracker orders from TCP port 421. If you have any doubt at all, use the ports program to verify that you are not running this Trojan version.

TCP Wrappers is very easy to set up and use and works well. Because each connection requires forking tcpd and reading the configuration files, it has substantially more overhead than IP Chains. Additionally, it only works for services started from xinetd and for those few services that support libwrap. Thus, it is not as complete a solution as IP Chains nor is it suitable for high-volume sites. It is a good solution for low-volume usage such as home systems and smaller companies and for individual workstations within companies. Adaptive Firewalls and Cracker Trap are built around it; they are discussed in "Adaptive Firewalls: Raising the Drawbridge with the Cracker Trap" on page 559.

14.1.1 TCP Wrappers Usage

In the /etc/inetd.conf file, the sixth field on a line is the program to invoke to supply the requested service. Many of these program names begin with in; some common ones are imapd, ipop3d, and in.telnetd. Following this field are any arguments that are to be passed to the program. TCP Wrappers works by replacing this program with the name of the TCP Wrappers daemon, typically /usr/sbin/tcpd. The intended service program becomes tcpd's first argument and any arguments to the original program become subsequent arguments to tcpd. xinetd works the same way.

The tcpd program determines the numeric IP address and host name of the client requesting service and the user name offered by the client system's ident service, if any. The tcpd program then consults its two configuration files, /etc/hosts.allow and /etc/hosts.deny, and decides whether to allow the service. If the service is to be allowed, the program specified is executed. If it is denied, the client is told to go away, the connection closed, and the matter logged. Each of these configuration files contains one entry per line and each of these entries contains fields separated with colons (:). For maximum security, the /etc/hosts.allow and /etc/hosts.deny files should be readable only by root.

The first field is a space-separated list of services that apply to this line's entry. The service name is the name of the program invoked. If the program name has slashes (/) in it, this is the name starting after the last slash. It is not the name of the service specified in /etc/services. The wildcard name ALL matches all services.

The second field is a space-separated list of hosts. A host may be named via /etc/hosts or DNS. Named domains may be specified. For example,



will match cory.berkeley.edu. Numeric networks may be specified by using dotted quads but with the host portion left off. For example, the 192.168.*.* class-B network may be matched with



An address/mask format is accepted. The previous network also could be specified via


The ALL wildcard matches all hosts; the LOCAL wildcard matches all hosts whose names do not contain a dot.

The KNOWN and UNKNOWN wildcards match, respectively, hosts whose names are known and those that fail DNS lookup. The failure may be because of a cracker with a spoofed IP address or it can be a temporary DNS problem or timeout. The EXCEPT operator means except for whatever is on the right. They may be nested to enable or disable parts of some networks, for example.

In the absence of special actions, the first line in /etc/hosts.allow that matches grants the service. If there is no match, the lines in /etc/hosts.deny, if any, are tested. If any match, the service is denied. If none of these match either, the service is allowed. Thus, for mostly closed systems, which is recommended, there should be the line in /etc/hosts.deny like



If the service is denied, a syslogd entry is made listing the program name associated with the denied service, the PID, and the client system that was refused. For example, if cracker.com tried to use in.telnetd, the log entry might look like

Sep 7 06:14 pentacorp.com in.telnetd[5196]: refused connect from cracker.com


The man pages for hosts_access in section 5 and for tcpd in section 8 are quite good.

14.1.2 TCP Wrappers Advanced Usage

There may be additional fields after the second field already described. These may be zero or more fields of shell commands and the fields allow or deny. The allow field will cause the service to be allowed, assuming that the service and host match. Similarly, the deny field will cause the service to be denied. These enable the lines of /etc/hosts.allow and /etc/hosts.deny to be combined into a single file if desired.

The shell commands may be used in any way desired, such as logging or generating alarms. A clever use of this is to booby-trap denied services. This means to alert you if someone attempts to get a service and is denied. This is likely a cracker trying to break in. The TCP Wrappers suite includes the safe_finger program that may be used to "finger" the offending system to get additional information about the would-be cracker. I have used this to catch some people red-handed with enough information to convince their ISPs to terminate their accounts.

Typical usage would be to add the following to the /etc/hosts.deny file. Note that the alert is mailed to the SysAdmin's work and home e-mail accounts. Thus, if an attempt on the work system is made over the weekend, the problem will be detected before Monday morning. Note that e-mail also could be sent to the address of your pager. The Adaptive TCP Wrappers configuration discusses all of this in detail.

ALL: ALL: spawn=(/usr/sbin/safe_finger -l @%h | \
  /bin/mailx -s DENIEDdefault_%h/%d/%a/U=%u \
  you@homesys.com you@pentacorp.com \
  ) &:deny


A "%" character introduces an expansion sequence. They may be used as much as desired. The following are recognized:





The clients numeric address.




The servers numeric address (useful when there are multiple servers).




The user@client_sys.




The daemon program name.




The client host name.




The server host name.




The servers PID.




The daemon@server_sys.




The client users name, if supplied by ident.




The "%" character.



The tcpd program even is smart enough to replace any characters in the "%" expansion that might be special to the shell with underscores. Note that unlike the regular finger program, safe_finger will resist attacks from the cracker system, such as buffer overflow attacks and non-ASCII characters.