Tcp-wrappers consist of two files:
/etc/hosts.allow /etc/hosts.deny |
These two files control access in a fined-grained manner, and can be configured to handle most access to the system. As the names of the files imply, the hosts.allow file controls access to who IS allowed to connect to services on our system, while the hosts.deny controls who will NOT be allowed to connect to services on the server.
For the purpose of this section, we are going to implement the finger daemon/client software. Consult the man page of the finger daemon and client to understand what it can do. Choose one of your workstations as the server and the other as the client. In addition to installing the finger daemon on the server, you will need to install the finger client software on the client workstation . Using your nmap program, check that the finger daemon is running on your server.
To test whether finger is working, run the command:
finger root@<server-workstation> |
This should give you information about the user "root" on the server similar to that displayed below:
#finger root@<server workstation here> Login: root Name: root Directory: /root Shell: /bin/bash On since Thu Apr 22 08:17 (SAST) on pts/1 from 172.16.1.2 23 minutes idle (messages off) No mail. No Plan. |
The format of the hosts.{allow,deny} files are identical. In essence the following procedure is used:
consult the hosts.allow file - allow if daemon/client pair match
consult the hosts.deny file - deny if daemon/client pair match
allow the hosts access to the service
The first match of a daemon/client pair halts the checking of these files and access is either granted (if the match was found in the hosts.allow file) or denied (if the match was in the hosts.deny file). If no entries match in either the hosts.allow or the hosts.deny files, access is automatically granted.
The files have the format:
daemon list: client list |
These lists and match-pairs can get quite complex, and the hosts.allow can over-ride entries in the hosts.deny files.
The first (simplest) method now is to deny access from everyone from the client workstation with an entry in the hosts.deny. The daemon list is the name of the daemon without the path. Thus, the finger daemon is in.fingerd, and the resulting entry in the hosts.deny file is:
in.fingerd: 172.16.1.2 |
This will deny access to anyone trying to finger the server from the host 172.16.1.2. Once changes are made in the hosts.allow and hosts.deny files, they become effective immediately. Save your hosts.deny file and try to "refinger" the root user on the server:
finger root@<server workstation here> |
No reply. Good.
The format of the clients in the hosts.{allow,deny} represent some of the functionality mentioned. For example, in the hosts.deny, we might have an entry such as:
in.fingerd: ALL |
denying everyone from using the finger daemon.
In the hosts.allow file however, we may wish to allow every hosts on the 172.16.1.0 network. Such might be the entry in the hosts.allow file:
in.fingerd: 172.16.1. |
Other forms of this are:
in.fingerd: 172.16.1.0/255.255.255.0 |
which would match all hosts (172.16.1.0 to 172.16.1.255) on the network 172.16.1.
Special reserved words can be used too. The words ALL (as indicated above), EXCEPT and LOCAL can also be used as follows:
in.fingerd: 172.16.1. EXCEPT 172.16.1.2 |
In this pattern, users on the network who try to finger a user from hosts in the 172.16.1 network will be allowed access (if this entry appears in the hosts.allow file), however, fingers from 172.16.1.2 will be explicitly denied. Daemon lists can be included as follows:
in.fingerd, sshd: LOCAL |
The LOCAL keyword indicates that hosts on the LOCAL network may use this service. Hosts considered to be on the LOCAL network will not contain a "." in the hostname. So, connecting from defender.QEDux.co.za will not be allowed access since this hostname contains ".". If the host was on the local network, it would be allowed.
Combining these files can produce some interesting results. Suppose we have hosts.{allow,deny} files as follows:
hosts.allow:
in.fingerd: LOCAL |
hosts.deny:
in.fingerd: ALL |
This would allow all hosts that are local to finger users on the server, but deny everyone else. There are many additional things one can do with tcp-wrappers. For example, suppose you wish to keep track of those users using secure shell to your host, you can include a spawn action that will allow you to log information to the syslog (or messages) directory.
in.fingerd : LOCAL : spawn (/usr/sbin/safe_finger -l @%h | \ /usr/bin/logger -t \ -- MY FINGER WATCHER \ -- -p local0.info "%d-%a-%h" ) & sshd: LOCAL : spawn (/usr/bin/logger -t -- MY SSH WATCHER \ -- -p local1.info "%d-%a-%h" ) & |
This is an extended form of previous hosts.allow we have seen earlier. When a user tries to ssh to the server, the logger application will log an entry to the syslog (or messages) file indicating that a user from the IP address <%a> and the hostname <%h> has tried to access the daemon <%d>. In this case, the entry in the syslog file will be:
Apr 22 11:56:33 mtnkiosk -- MY SSH WATCHER \ --: sshd-172.16.1.2-defender |