Enhancing a Linux system’s security with TCP wrappers essentially involves editing two files. The first is the hosts.allow file, which allows administrators to specify which hosts or networks can access the system. The other file is hosts.deny, which explicitly states all of the hosts or networks that will be prevented from accessing the system. The files also allow us to specify which services should be accessible or protected.
This is a rudimentary and simplistic approach to securing the system on the network, but it is nonetheless effective at preventing explicit hosts or networks from accessing the system, while allowing those that are whitelisted. For certain scenarios, it can be a quick and easy way to implement basic network security. It also adds a layer of redundancy beyond the system firewall. However, it is also worth considering more advanced and modern techniques, which we will discuss below.
In this tutorial, you will see how to secure a Linux system with TCP wrappers. We will show example configurations that can be implemented in order to allow or deny hosts or entire networks from accessing your system or specific services. In addition, we will go over important considerations for Linux administrators that are interested in using TCP wrappers as part of their system security’s line of defense.
In this tutorial you will learn:
- Limitations and considerations for using TCP wrappers
- How to configure allow and deny rules for TCP wrappers

| Category | Requirements, Conventions or Software Version Used |
|---|---|
| System | Any Linux system |
| Software | N/A |
| Other | Privileged access to your Linux system as root or via the sudo command. |
| Conventions |
# – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux commands to be executed as a regular non-privileged user |
Are TCP Wrappers Still a Relevant Security Measure?
Before configuring TCP wrappers, all users should be aware of its limitations.
Utilizing TCP wrappers for system hardening has been largely phased out by Linux administrators in favor of using the default firewall: iptables / nftables, or one of the popular front ends like ufw or firewalld.
Support on Contemporary Distros
First off, some modern Linux distributions do not even support TCP wrappers anymore. So before diving into using TCP wrappers, you should consider the systems you are working with and check for native support. Consulting the official documentation of your Linux distribution is a good place to start. Otherwise, checking for the existence of the hosts.allow and hosts.deny files on your system will help you confirm whether or not this configuration is supported.
Here is the result on our Arch Linux test system, where using TCP wrappers is no longer supported:
$ ls -l /etc/hosts.allow ls: cannot access '/etc/hosts.allow': No such file or directory
And here is the result on our Ubuntu test system, where using TCP wrappers is still supported:
$ ls -l /etc/hosts.allow -rw-r--r-- 1 root root 411 Feb 22 2023 /etc/hosts.allow
Firewall Alternatives
Implementing TCP wrappers was an ordinary security practice 20 years ago, and even commonplace before that. These days, most Linux administrators will opt to use the built in iptables firewall or one of its simpler front ends mentioned earlier.
Netfilter (the system that iptables and nftables rely on) has been built into the Linux kernel since 2001, and its introduction and widespread adoption have subsequently rendered old network hardening methods like TCP wrappers irrelevant for many users.
Reasons why you might still want to utilize TCP wrappers are:
- A second line of defense that reiterates current firewall rules – if the firewall gets turned off or misconfigured, the idea is that TCP wrappers would still be actively blocking or allowing the connections you need configured
- If you just want to implement simple network rules (for example, on a test system) and do not want to fiddle with the firewall
- If you need to control network access to applications – TCP wrappers can block or allow connections to specific services (think vsftpd or sshd) rather than network protocols
- Firewall rules and the required syntax to program them can prove rather complex, especially compared to TCP wrappers’ straightforwardness and simplicity
Reasons why you should use a firewall in addition to TCP wrappers, or why many system administrators will simply opt for a firewall instead of using TCP wrappers:
- The firewall allows for stateful packet inspection, allowing admins to craft complex and granular rules to control packet flow based on a variety of conditions
- TCP wrappers are not supported on every Linux system
- A firewall supports logging and real time traffic analysis, so you can see what exactly is being denied or allowed through your system
- The system firewall can allow or deny traffic based on protocol (such as FTP or SSH) as opposed to TCP wrappers only being able to allow or deny traffic from hosts, networks, or to specific services
- The firewall supports chains in order to create rules for input (incoming traffic), output (outgoing traffic), and forwarding (incoming traffic that gets rerouted to somewhere else)
There are a plethora of other reasons, too, but these are some of the most compelling. As you can see, the reasons for using a firewall outweigh the reasons for using TCP wrappers.
This is not meant to discourage you from using TCP wrappers. This explanation is only meant to arm you with the necessary insight to understand the implications of using TCP wrappers in place of a more widely accepted and modern solution.
Configuring TCP Wrappers
Now let’s see how we can configure some rules using TCP wrappers. To apply any configuration, you will need to open the /etc/hosts.allow and/or /etc/hosts.deny files, depending on whether you are trying to allow or deny traffic, respectively. This must be done with root permissions, and can be with any text editor (nano, vim, etc.) of your choice.
Deny Rules
First, let’s see some deny rules that we can configure in TCP wrappers:
- A common practice is to configure only one rule inside of the
hosts.denyfile, which is to simply deny incoming traffic from all hosts to all services:ALL: ALL
This rule by itself would not do us much good since it would mean that none of our services are accessible over the network. But, the idea behind this rule is that we can proceed to add all of the hosts we want to grant access to inside of the
hosts.allowfile. Such a setup will only work if we have a known list of hostnames, networks, or IP addresses that we wish to grant access to. If we can’t predict the network addresses of the systems that need access, then this rule will not be feasible. - The following rule would deny ALL traffic to SSH – more specifically
sshd, the SSH server daemon:sshd: ALL
Keep in mind that after configuring this rule, we can still go into the
hosts.allowfile and specify hosts that should be granted access to SSH. - Let’s see how we can deny access to a specific host. In this example, we deny access to host
192.168.1.100:ALL: 192.168.1.100
Or deny to a specific service:
sshd: 192.168.1.100
- Here is how we can deny traffic to an entire network. In this example, we will deny traffic to the
192.168.1.0/24network for the sshd service:sshd: 192.168.1.0/255.255.255.0
- We can also use the
ALL EXCEPTsyntax to deny traffic from all hosts and networks except the ones we specify. Here is an example where we allow two different networks (192.168.1.0/24andlinuxconfig.org) but deny traffic from everywhere else:ALL: 192.168.1.0/255.255.255.0, .linuxconfig.org
Allow Rules
The syntax for allow rules will be the same as the deny rules. Typically, but not always, the deny rules are configured to block most incoming traffic, with the allow rules then being configured as the exceptions.
- Rather than blocking all connections in
hosts.denyand usinghosts.allowto configure the exceptions, we can also employ the opposite configuration by allowing all traffic inhosts.allowand subsequently denying specific hosts inhosts.deny. Here is how to allow all traffic to a certain service such as sshd:sshd: ALL
- We can use the
ALL EXCEPTsyntax to allow everyone except the hosts or networks we explicitly want to deny:
sshd: ALL .linuxconfig.org EXCEPT prod.linuxconfig.org
To get the ideal configuration, you will need to configure both files to construct your allow and deny list. For simple setups, this proves easy to do. Once you need a more advanced configuration, maintaining rules in two separate files is probably more difficult than using the built in system firewall.
Closing Thoughts
In this tutorial, we saw how to secure a Linux system using TCP wrappers. This involved editing the hosts.allow and hosts.deny files in order to have them work in conjunction to allow and deny a list of hosts and networks that we specify. We also covered the limitations and considerations that every Linux administrator should take into account when working with TCP wrappers. When it comes to allowing or denying traffic on the application layer (layer 7 in the OSI mode), TCP wrappers is a quick and simple method, assuming that your Linux distro supports them.