Joey's Notes: TCP Wrappers on Red Hat Enterprise Linux
By Joey Prestia
In information technology, security is never a result of "just one thing"; in other words, there is not a panacea for digital security. The best security practices result from multiple applications and practices to protect your system, such as iptables firewalling, Mandatory Access Controls such as SELinux, and Discretionary Access Controls such as permissions and rights. Last, consider coupling TCP Wrappers to complement your firewall rules.
[ As security guru Bruce Schneier often points out, "security is not a product; it's a process". The largest part of security is not even related to the tools you use; it's the awareness of the continual necessity of staying informed, updated, and at the top of the game. The tools are one of the means to that end. -- Ben ]
TCP Wrappers work in the manner of a host-based Access Control List. They are used to filter out network access to Internet Protocol (IP) servers that are running Linux, Unix, or BSD. They will allow host or network addresses to be used as indicators to filter and implement a layer of access control. They additionally extend the capabilities of xinetd-controlled daemons. By using this technique, connection attempts can be logged, restricted, and messages returned. This can add an extra layer of security in your environment. TCP Wrappers also allow run-time reconfiguration without restarting or reloading the services they protect.
Connections that are permitted are simply allowed; those that are denied will fail. Some services will report a particular error message, as do SSH and vsftpd. Here is an example of an exchange using TCP Wrappers to protect services.
An example of SSH being disallowed from the client's perspective:
[root@alien ~] ssh email@example.com ssh_exchange_identification: Connection closed by remote host
An example of FTP being disallowed:
[root@alien ~] ftp 192.168.0.15 Connected to 192.168.0.15. 421 Service not available.
How TCP Wrappers Work
When connections are attempted to a service using TCP wrappers, the following occurs (the following steps are important because order matters, and rules are processed line-by-line):
- The process will check the file /etc/hosts.allow. Access will be granted if a match is found in the /etc/hosts.allow file.
- The process will check the file /etc/hosts.deny. Access will be denied if a match is found in the /etc/hosts.deny file.
- In the event no matching rules apply, access will be granted.
To uncover what processes/daemons use TCP Wrappers, do the following:
strings -f <program_name> | grep hosts_access
An example of output from this command:
[root@alien ~] strings -f /usr/sbin/* | grep hosts_access /usr/sbin/in.tftpd: hosts_access /usr/sbin/sshd: hosts_access /usr/sbin/stunnel: hosts_access /usr/sbin/stunnel: See hosts_access(5) manual for details /usr/sbin/tcpd: hosts_access_verbose /usr/sbin/vsftpd: hosts_access /usr/sbin/xinetd: hosts_access [root@alien ~] strings -f /sbin/* | grep hosts_access /sbin/portmap: hosts_access_verbose
Implementing TCP Wrappers
When using TCP Wrappers, bear certain things in mind. First, order matters. Second, the search will stop with the first match. Any changes to /etc/hosts.allow or /etc/hosts.deny take effect immediately without having to restart any services. As with iptables, order is crucial in these rules. Let's take a look at the commands for setting rules. The basic formats of commands in /etc/hosts.allow and /etc/host.deny are:
daemon_list : client_list : shell_command daemon_list - This is a list of one or more daemon process names or wildcards client_list - This is a list of one or more host names, host addresses, patterns or wildcards that will be matched against the client host name or address.
Examples of /etc/hosts.allow and /etc/hosts.deny rules:
# # hosts.allow This file describes the names of the hosts # allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # My new rule below sshd : 192.168.0.14
# # hosts.deny This file describes the names of the hosts # *not* allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # The portmap line is redundant, but is left to remind you that # the new secure portmap uses hosts.deny and hosts.allow. In particular, # you should know that NFS uses portmap! # # My new rule below ALL : ALL
Observe the results of my new rules:
From station14.example.com (192.168.0.14)
Last login: Tue Apr 7 06:45:09 2009 from station14 [root@station15 ~]#
From alien.example.com (192.168.0.247)
[root@alien ~]# ssh 192.168.0.15 ssh_exchange_identification: Connection closed by remote host [root@alien ~]#
- This wildcard will match all services or hosts.
- This matches any host that does not contain a dot character.
- This matches any unknown user, and matches any host whose name or addresses are unknown. Remember that host names may be unavailable if name server problems are encountered.
- This matches any known user, and matches any host whose name and address are known. Remember that host names may be unavailable if name server problems are encountered.
- This will match any host whose name does not match its address.
- This is intended to be used in the form: list_1 EXCEPT list_2. This operator matches anything that matches list_1 unless it matches list_2. EXCEPT can be used in daemon_lists and in client_lists.
(WARNING: Always leave a blank line containing an 'enter' character in both /etc/hosts.allow and /etc/hosts.deny! Simply go to the end of your last line in insert mode within the vi editor, and hit the carriage return (<enter>) key. Failure to perform this step may cause unwanted consequences with TCP Wrappers.)
Here are some rule examples included below. Which file you put the rule in determines how the rule works, unless you add an 'allow' or a 'deny' at the end of the rule.
sshd : .example.com vsftpd : 192.168. ALL : 192.168.1.0/255.255.255 sshd : station1.example.com : allow sshd : station15.example.com : deny vsftpd : ALL EXCEPT *.hacker.org
The 'twist' directive is used to replace the service with a selected command. It is commonly used to set up honeypots. Another use for it is to send messages to connecting clients. The 'twist' command must be used at the end of a rule line. Here is an example of using 'twist' in /etc/hosts.deny to send a message to a host that has abused FTP services, via the echo command:
Example using twist in /etc/hosts.deny
vsftpd : station6.example.com \ : twist /bin/echo "Service suspended for abuse!"
The 'spawn' directive causes a child process to be launched. This can be very handy when used to generate special access log files. You can also run custom scripts in the background with this directive that will be unseen by the user. In this example, we will create a timestamp in a custom log so we can monitor FTP connections:
Example in /etc/hosts.allow
vsftpd : .example.com \ : spawn /bin/echo $(/bin/date) access granted to %h>>/var/log/ftp_access.log
These are what character expansions you can take advantage of, when used in either /etc/hosts.allow or /etc/hosts.deny.
% EXPANSIONS The following expansions are available within shell commands: %a The client host address %A The server's host address %c Client information: user@host, user@address, a host name, or just an address %d The daemon process name %h The client host name or address, if the host name is unavailable %H The server host name or address, if the host name is unavailable %n The client host name (or "unknown" or "paranoid") %N The server host name (or "unknown" or "paranoid") %p The daemon process id %s Server information: daemon@host, daemon@address, or just a daemon name %u The client user name (or "unknown") %% Expands to a single "%" character. (Characters in % expansions that may confuse the shell are replaced by underscores)
TCP Wrappers make a great complement to your current security measures. Remember: always thoroughly test any security implementation before moving to a production platform!
Joey was born in Phoenix and started programming at the age fourteen on a Timex Sinclair 1000. He was driven by hopes he might be able to do something with this early model computer. He soon became proficient in the BASIC and Assembly programming languages. Joey became a programmer in 1990 and added COBOL, Fortran, and Pascal to his repertoire of programming languages. Since then has become obsessed with just about every aspect of computer science. He became enlightened and discovered RedHat Linux in 2002 when someone gave him RedHat version six. This started off a new passion centered around Linux. Currently Joey is completing his degree in Linux Networking and working on campus for the college's RedHat Academy in Arizona. He is also on the staff of the Linux Gazette as the Mirror Coordinator.