I thought today I would outline a few tips on network security with tcpwrappers or, as you’re probably more familiar, the hosts.allow and hosts.deny files. How you can use them? What applications are compatible? etc. I know network security is a really broad topic, but this will hopefully be enough to get you going and understand some more basics of securing your machine.
tcpwrappers compatibility
The first thing to remember is that not every network-based application on your machine is compatible with tcpwrappers. The restrictions on hosts.allow or hosts.deny are only valid if they refer to the tcpwrappers library. How can you find out if your application is compatible? Use this command:
ldd /path/to/binary | grep libwrap (general example)
ldd /usr/sbin/sshd | grep libwrap (shows that the sshd refers to libwrap)
ldd /usr/sbin/apache2 | grep libwrap (show that apache does not refer to libwrap)
In the basic example above we see that the sshd (ssh server) is referring to the libwrap.so, so we can tell that any restrictions in hosts.allow and hosts.deny are applicable to that service. We also see that apache2 does not refer to libwrap.so, so any restrictions outlined there do not apply to apache2 connections. (ie; you could lock down ssh but apache2 is still wide open)
hosts.allow and hosts.deny
These two files, located in your /etc/ folder, allow you to limit or permit connections from specific hosts or ips. Using these two files you could setup a whitelisting firewall or blacklist. Remember, as mentioned in the compatibility section, this only applies to the services referring to libwrap. If you are running services outside of the scope of libwrap.so this may not be the best solution for you in terms of firewalling.
/etc/hosts.allow
ALL: 127.0. [::1] (the 127.0. range is allowed, as well as the localhost ipv6 address)
sshd : 192.168.0.5 (specific IP) 192.168.0. (specific range) EXCEPT 192.168.0.10 (range exceptions)
/etc/hosts.deny
ALL : ALL (denying all services to all hosts)
This example would allow connections from localhost on ipv4 and ipv6 for all services and also explicitly allow ssh connections from the 192.168.0.5 address, the entire 192.168.0. range, but excluding the 192.168.0.10 host. The hosts.deny then outright denies all services for all hosts. This is a very basic example but hopefully it gets the idea across. You could also reverse the contents of the two files in the example above and do blacklisting. ALL : ALL are allowed with the exceptions of services and ips listed in the hosts.deny.
The syntax of the hosts.allow and hosts.deny files are:
service(s) : ips or hosts
You can comma separate the list of services you want to allow or deny and make a similar list of hosts/ips to allow or deny. Very simple syntax.
conclusion
The hosts.allow and hosts.deny files are very flexible and allow you to lock down your network in very granular ways. The limitation of some applications not honoring hosts.allow and hosts.deny is the biggest thing to remember. Make sure the service you are trying to block refers to libwrap.so before you start writing rules or you may sit and wonder why your rules don’t work, when its really the application itself not being compatible.
Though not as user-friendly, ip tables is a much more efficient solution; it works at a layer lower, and also doesn’t depend on tcp wrappers.
Joe – yes, iptables is a much more powerful solution. Let’s give people something they can walk with before they run with iptables 🙂
Joe – really good security people always believe in security in layers. Having an additional layer of security doesn’t hurt and in many cases can help. Maybe my iptables rules get borked some how. In that case, it’s helpful to have tcp wrappers implemented.
I think it is worth mentioning the strings command as well. Some versions of portmap use tcpwrappers, but, if you run ldd against them, you won’t see that it does. Also nagios is compiled the same way.
i.e.:
strings /path/to/binary | grep hosts
will show that it checks the hosts.allow and hosts.deny files.
You missed the coolest function of tcpwrappers and that is the spawn command. Try something like this:
sshd: ALL: spawn (echo “Attempt from %h %a to %d at `date` by %u” | tee -a /var/log/sshd.log)
I installed two packages Rootkit Hunter and Chkrootkit on ubuntu 8.04 ever since that it keeps updating my /etc/hosts.deny file with a valid ip address so I cannot loggin from my work to my home server. I tried the following below but ubuntu 8.04 does not have a /usr/share/denyhosts/data/* directory
1. Stop DH daemon. /etc/init.d/denyhosts stop
2. Remove usr’s IP from /etc/hosts.deny
3. Grep DH’s data directory for usr’s IP. grep ‘xxx.xxx.xxx.xxx’ /usr/share/denyhosts/data/*
4. Here’s the best part… Remove usr’s IP from all the files that grep showed in step 3.
5. Start DH daemon. /etc/init.d/denyhosts start
6. Ask usr to log in now.
Step 1-5 does not work in ubuntu becuase there is no /usr/share/denyhosts/data/*
Please help
Thanks
gary
The reason you can’t find apache2 in libwrap is because there is no such thing. The executable for Apache 2 is httpd.
I need a script for automatic backup. I want to take a backup different ip address like this is my server ip 192.168.0.2 so i need to put a backup to 192.168.0.71.
@Paul:
No, in Ubuntu (at least in 8.04, anyway) the binary is actually called apache2 as noted in the article:
texaslabrat@ratnest:~$ which httpd
texaslabrat@ratnest:~$ which apache2
/usr/sbin/apache2
texaslabrat@ratnest:~$ ls -asl /usr/sbin/apache2
412 -rwxr-xr-x 1 root root 414016 2009-07-10 13:57 /usr/sbin/apache2
@Gary:
Have you tried putting your work IP address in the hosts.allow file? The allow file is searched first, and tcpwrappers stops at the first match. And I don’t know about your implementation, but my denyhosts database appears to be in /var/lib/denyhosts:
texaslabrat@ratnest:/var/lib/denyhosts$ ls
hosts hosts-root offset users-hosts users-valid
hosts-restricted hosts-valid suspicious-logins users-invalid
texaslabrat@ratnest:/var/lib/denyhosts$ cat hosts-restricted
117.102.90.158:0:Tue Jul 28 21:47:10 2009
149.217.72.19:0:Mon Jul 27 05:32:37 2009
…
I am troubleshooting a networking problem and i wand to find out if the following line in the hosts.allow is correct or not?
ALL:127.0.0.1,3.21.,23.10.:allow
One thing I don’t understand is why is there “:allow” at the end? What if I remove it? It is a typo?
Thanks.
I don’t believe the commas are proper syntax. I generally break my lines up, for readability:
ALL : 127.0.0.1 : allow
ALL : 3.21. : allow
ALL : 23.10 : allow
The allow appended to the end is not required, but technically the hosts.deny file is deprecated so it is “proper” to define :allow or :deny explicitly for each line.