A common way to restrict access to some TCP services is to use the TCP Wrappers program. TCP Wrappers is a package that monitors and filters requests for TCP (Transmission Control Protocol) services. We don't look at the protocol in any detail here ”that's a book subject in itself. Suffice it to say the protocol has enough control information in it that we can use a package like TCP Wrappers to filter some of that traffic. TCP Wrappers can be used to restrict certain network services to individual computers or networks.
To make use of this program on some flavors of Unix, TCP Wrappers must be installed by the system administrator. This isn't a necessary step in Mac OS X because the TCP Wrappers program comes preinstalled on the system. The /etc/inetd.conf file in Mac OS X already assumes that you use TCP Wrappers, as evidenced by a line such as the following:
#ftp stream tcp nowait root /usr/libexec/tcpd ftpd -l
The /usr/libexec/tcpd portion of the preceding line indicates that TCP Wrappers is used to call ftpd .
TCP Wrappers can block access to a service, but it can't refuse the connection.
When you use TCP Wrappers to protect an inetd service, it lets you prevent a remote machine from connecting to that service, but the connection to inetd still happens. Using tcpd to protect a service in this fashion can prevent the internal resource depletion effects of a DoS attack, but inetd itself still must accept the connection and pass it to tcpd . Through this limitation, a DoS attack against inetd , even on a completely TCP Wrapped machine, can impact performance and resources.
TCP Wrappers therefore should be thought of primarily as a way to limit access to services to hosts that you want accessing them, rather than a way of securing inetd itself.
The particularly difficult part about using TCP Wrappers is configuring it. We will look at two ways you can configure TCP Wrappers in OS X: the traditional method of using two control files and an alternate method that uses only one control file.
Traditionally, TCP Wrappers has two control files, /etc/hosts.allow and /etc/hosts.deny . We will look at the traditional method in greater detail because it is the default setup for a machine when extended processing options are not enabled. An understanding of the traditional method should carry over to the alternate method. Be sure to read the hosts_access and hosts_options man pages for detailed information.
Here is the format of the access control files:
daemon_list : client_list : option : option ...
Through /etc/hosts.allow you can allow specific services for specific hosts.
Through /etc/hosts.deny you can deny services to hosts, and provide global exceptions.
The easiest way to think of and use these configuration files is to think of TCP Wrappers as putting a big fence up around all the services on your machine.
The specifications in /etc/hosts.deny are most typically used to tell the fence what services are on the outside of the fence, and therefore for which access is not denied (that is, the specifications provide exceptions to the deny rule). The fence can appear to be around different sets of services for different clients . For example, an /etc/hosts.deny file might look like
ALL EXCEPT ftpd : 192.168.1. : banners /usr/libexec/banners ALL : 184.108.40.206 220.127.116.11 : banners /usr/libexec/banners ALL EXCEPT ftpd sshd : ALL : banners /usr/libexec/banners
This file says
For the subdomain 192.168.1. , deny all connections except connections to the FTP daemon, ftpd .
For the specific machines 18.104.22.168 and 22.214.171.124 (maybe they're troublemakers) deny absolutely all connections.
For all other IP addresses, deny everything except connections to ftpd and to the secure-shell daemon sshd .
The banners /usr/libexec/banners entry is an option that tells tcpd that if it denies a connection to a service based on this entry, try to find an explanation file in this location. Use this option if you have a need to provide an explanation as to why the service is not available. The banners option can be used when tcpd is compiled with the -DPROCESS_OPTIONS option. A makefile that can build the banners comes with the TCP Wrappers distribution. Make a prototype banner called prototype , run make to create a banner for the service, and place the banner file in the appropriate directory; in this case, /usr/libexec/banners . This option can be used primarily for ftpd , telnetd , and rlogind . For Mac OS X, you would probably have to compile your own tcpd to get this to work.
The specifications in /etc/hosts.allow make little gates through the fences erected by /etc/hosts.deny for specific host and service combinations. For example, an /etc/hosts.allow file might look like the following:
ALL: 126.96.36.199 192.168.2. 192.168.3. popper: 188.8.131.52 184.108.40.206 192.168.1.36
This file says
Allow connections to any TCP service from the host 220.127.116.11 and all hosts in the 192.168.2. and 192.168.3. subdomains. (Perhaps the 192.168.2 . and 192.168.3. subdomains are known highly secure networks because they're subnets within our own corporate LAN, and we really trust 18.104.22.168 because it's so well run.)
Allow connections to the popper (POPMail v3 daemon) service for three specific machines: 22.214.171.124 , 126.96.36.199 , and 192.168.1.36 . If used in combination with the previous /etc/hosts.deny file, these allowances still stand. They override the denials in /etc/hosts.deny , so even though the 192.168.1. subdomain is denied all access except to ftpd by /etc/hosts.deny , the specific machine 192.168.1.36 has its own private gate that allows it access to the popper popd service as well.
Services with a smile or without? There can be a bit of confusion as to the name of the service to put in an /etc/hosts.allow or /etc/hosts.deny file. If it's a service out of inetd.conf , generally the name to use is the service name from the left-most column of the file. If this doesn't work, try adding a d to the end of the service name ( ftp -> ftpd ). If that doesn't work, then try the program name as used in the right-most column of the inetd.conf file or as started by your rc files.
Other services use names that don't seem to be recorded officially anywhere . These sometimes require a bit of experimenting on your part, but the service names inserted into the Services NetInfo map are usually the hint you need.
If all else fails, read the man pages for the service.
Now that you have seen how the traditional method of controlling TCP Wrappers works, let's take a brief look at an alternate method that uses only the /etc/hosts.allow file. This method can be used on systems where extended option processing has been enabled. This is indeed the case with OS X. Nevertheless, either method works in OS X.
In the single file, /etc/hosts.allow , you specify allow and deny rules together. With the /etc/hosts.allow -only method, tcpd reads the file on a first-match-wins basis. Consequently, it is important that your allow rules appear before your deny rules.
For example, to restrict access to ftpd to only to our host, 188.8.131.52 , we would use these rules:
ftpd: 184.108.40.206 127.0.0.1 localhost: ALLOW ftpd: ALL: DENY
In the first line, the host, 220.127.116.11, is allowed access to ftpd using the various addresses that it knows for itself. On the second line, access to all other hosts is denied. If you reversed these lines, even the host that you wanted to allow ftpd access would be denied access.
After you have sufficiently tested that you have properly set up your allow and deny rules, there is nothing else you need to do to keep TCP Wrappers running. As you are testing your rules, check your logs carefully to see where, if at all, the behaviors are logged. You will rarely see entries for tcpd itself in your logs, but you may see additional logging for a wrapped service under that service. The best place to check is /var/log/system.log .