TCP wrappers [Mou01] are programs that act as intermediaries between the requests of the users of a service and the daemons of the servers that provide the service. Most distributions already come with the wrappers activated and we configure the levels of access. The wrappers tend to be used in combination with inetd or xinetd, so as to protect the services that they offer.
The wrapper basically replaces the service's daemon for another that acts as an intermediary (called tcpd, normally in /usr/sbin/tcpd). When this receives a request, it verifies the user and the origin of the request, in order to determine whether the configuration of the service's wrapper allows it to be used or not. Also, it includes the ability to generate logs, or to inform via email possible attempts at access and then runs the appropriate daemon assigned to the service.
For example, let's assume the following entry in inetd:
finger stream tcp nowait nobody /usr/etc/in.fingerd in.fingerd
We change it for:
finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd
so that when a request arrives, it is handled by the tcpd daemon which will be responsible for verifying the access (for more detailed information, see the tcpd man pages).
There is also an alternative method of TCP wrapper that consists of compiling the original application with the wrappers library. This way the application does not have to be in inetd and we can control it like in the first case with the configuration that we will discuss next.
Example 9-18. Note
Wrappers allow us to control security through access lists to levels of services.
The wrappers system is controlled from the /etc/hosts.deny file, where we specify which services we deny to whom, using options, like a small shell to save the information on the attempt, and the /etc/hosts.allow file, where we place the service we intend to use, followed by the list of who is allowed to use the service (later, in the workshop, we will look at a small example). We also have the tcpdchk commands, which test the configuration of the hosts files (see man hosts_access and hosts_options) to check that they are correct, in other words, it tests the configuration. The other useful command is tcpdmatch, to which we give the name of a service and a potential client (user, and/or host), and it tells us what the system will do in this situation.
A firewall is a system or group of systems that reinforces policies of access control between networks. The firewall can be implemented in software as a specialised application running on an individual computer or could be a special device designed to protect one or more computers.
In general, we will have either a firewall application to protect a specific machine directly connected to Internet (directly or through a provider), or we can place one or several machines designed for this function on our network in order to protect our internal network.
Technically, the best solution is to have one computer with two or more network cards that isolate the different connected networks (or network segments), in such a way that the firewall software on the machine (or if it is a special hardware) is responsible for connecting network packages and determining which can pass or not and to which network.
This type of firewall is normally combined with a router to link the packages of the different networks. Another typical configuration is the firewall towards the Internet, for example with two network cards: on one we obtain/provide traffic to the Internet and on the other we send or provide traffic to our internal network, thus eliminating traffic that is not addressed to us and also controlling traffic moving out towards the Internet, in case we do not wish to allow access to certain protocols or if we suspect that there are potential information leaks due to some attack. A third possibility is the individual machine connected with a single card towards the Internet, either directly or through a provider. In this case, we just want to protect our machine from intruders, unwanted traffic or traffic that is susceptible to data robbery.
In other words, in all these cases we can see that a firewall can have different configurations and uses depending on whether it is software or not, on whether the machine has one or several network cards or on whether it protects an individual machine or a network.
In general, the firewall allows the user to define a series of access policies (which machines can be connected to do or which machines can receive information and what type of information) by means of controlling the allowed incoming or outgoing TCP/UDP ports. Some firewalls come with preconfigured policies; in some cases they just ask whether we want a high, medium or low level of security; others allow all options to be tailored (machines, protocols, ports etc.).
Example 9-19. Note
Firewalls make it possible to establish security at the level of packages and communication connections.
Another related technique is network address translation (NAT). This technique provides a route for hiding IP addresses used on the private network and hides them from the Internet, but maintains the access from the machines. One of the typical methods is the one known as masquerading. Using NAT masquerading, one or several network devices can appear as a single IP address seen from the outside. This allows several computers to be connected to a single external connection device; for example, the case of an ADSL router at home that allows several machines to be connected without the need for the provider to give us various IP addresses. ADSL routers often offer some form of NAT masquerading, and also firewall possibilities. It is fairly common to use a combination of both techniques. In this case, as well as the configuration of the firewall machine (in the cases we have seen above), the configuration of the internal private network that we want to protect also comes into play.
The Linux kernel (as of versions 2.4.x) offers a filtering subsystem called Netfilter [Net], which offers package filtering features as well as NAT. This system allows different filter interfaces to be used, the most commonly used one is called IPtables. The main control command is iptables. Previously [Hata], it provided another filter called ipchains in kernels 2.2 [Gre], the system had a different (although similar) syntax. The 2.0 kernels used a different system called ipfwadm. Here (and in later examples) we will only deal with Netfilter/IPTables (in other words with the kernel versions 2.4/2.6).
Example 9-20. Web site
Netfilter, ver: http://www.netfilter.org
Ipchains, see: http://www.netfilter.org/ipchains/
The interface of the IPtables command allows the different tasks to be perfomed for configuring the rules that affect the filter system: whether the generation of logs, pre and post package routing actions, NAT, and port forwarding.
Example 9-21. Note
IPTables provides different elements such as the tables, chains and the rules themselves.
Service start up with: /etc/init.d/iptables start, if not already configured in the runlevel.
The iptables -L command lists the active rules at that time in each of the chains. If not previously configured, by default they tend to accept all the packages of the chains of input output and forward.
The IPTables system has the tables as a superior level. Each one contains different chains, which in turn contain different rules. The three tables that we have are: Filter, NAT and Mangled. The first is for the filtering norms themselves, the second is to translate addresses within a system that uses NAT and the third, less frequently used, serves to specify some package control options and how to manage them. Specifically, if we have a system directly connected to the Internet, we will generally only use the Filter table. If the system is on a private network that has to pass through a router, gateway or proxy (or a combination of them), we will almost certainly have a NAT or IP masquerading system; if we are configuring the machine to allow external access, we will have to edit the NAT table and the Filter table. If the machine is on a private network system, but is one of the internal machines, it will be enough to edit the Filter table, unless it is a server that translates network addresses to another network segment.
If a package reaches the system, the firewall will first look at whether there are rules in the NAT table, in case addresses towards the internal network need to be translated (addresses are not normally visible outwards); then it will look at the rules in the Filter table in order to decide whether the packages will be allowed to pass or whether they are not for us and we have forward rules to know where to redirect them. On the contrary, when our processes generate packages, the output rules of the Filter table will control whether we allow them out or not, and if there is a NAT system the rules will translate the addresses in order to masquerade them. In the NAT table there are usually two chains: prerouting and postrouting. In the first, the rules have to decide if the package has to be routed and, if so, what the destination address will be. In the second, it is finally decided whether the package is allowed inside or not (to the private network, for example). And there is also an output chain for locally generated outgoing traffic to the private network, since prerouting does not control this (for more details, see iptables man page).
Next we will comment on some aspects and examples of configuring the Filter table (for the other tables, we can consult the associated bibliography).
The Filter table is typically configured as a series of rules that specify what is done inside a particular chain, like the three preceding ones (input, output and forward). Normally, we will specify:
iptables -A chain -j target
where chain is the input, output or forward and target is the destination that will be assigned to the packet which corresponds to the rule. Option -A adds the rule to the existing ones. We have to be careful here, because the order does matter. We have to put the least restrictive rules at the beginning, given that, if we put a rule that eliminates the packets at the beginning, even if there is another rule, this will not be taken into account. Option -j can be used to decide what we will do with the packets, typically accept, reject or drop. It is important to note the difference between reject and drop. With the first, we reject the packet and we will normally inform the sender that we have rejected the connection attempt (normally for an ICMP-type packet). With the second, drop, we simply "lose" the package as though it had never existed and we will not send any form of response. Another target that is used is log, to send the packet to the log system. Normally, in this case, there are two rules, one with the log and another identical one with accept, drop and reject, so that the information on the accepted, rejected or dropped packets can be sent to the log.
When entering the rule, we can also use the option -I (insert) to indicate a position, for example:
iptables -I INPUT 3 -s 10.0.0.0/8 -j ACCEPT
which tells us that the rule should be put in the third position in the input chain; and that packets (-j) that come from (with source, -s) from the subnet 10.0.0.0 with netmask 255.0.0.0 will be accepted. With -D, similarly, we can delete either a rule number or the exact rule, as specified below, deleting the first rule of the chain or the rule that we mention:
iptables -D INPUT 1 iptables -D INPUT -s 10.0.0.0/8 -j ACCEPT
There are also rules that can be used to define a default "policy" for the packets (option -P); the same thing will be done with all the packets. For example, we would usually decide to drop all the packets by default and then enable the ones that we require; likewise, we would often avoid forwarding packets if it is not necessary (if we do not act from the router), this could be declared as follows:
iptables -P INPUT DENY iptables -P OUTPUT REJECT iptables -P FORWARD REJECT
This establishes default policies that consist of rejecting any incoming packets and not permitting the sending or resending of packets. Now we will be able to add rules that affect the packets that we wish to use, stating which protocols, ports and origins or destinations we wish to permit or avoid. This can be difficult as we have to know all the ports and protocols that our software or services use. Another strategy would be to only leave active the services that are essential and to enable access to the services for the desired machine through the firewall.
Some examples of these rules on the Filter table could be:
1)iptables -A INPUT -s 10.0.0.0/8 -d 192.168.1.2 -j DROP 2)iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset 3)iptables -I INPUT -p tcp --dport 113 -s 10.0.0.0/8 -j ACCEPT
1) We drop the packets that come from 10.x.x.x sent to 192.168.1.2.
2) We reject the tcp packets sent to port 113, issuing a tcp-reset type response.
3) The same packets as in 2) but that come from 10.x.x.x will be accepted.
With regard to the names of the protocols and ports, the iptables system uses the information provided by the files /etc/services and /etc/protocols, and we can specify the information (port or protocol) either with numbers or with the names (we must make sure, in this case, that the information on the files is correct and that it has not been modified, for example, by an attacker).
The configuration of the iptables is usually established through consecutive calls to the iptables command with the rules. This creates a state of active rules that can be consulted with iptables -L; if we wish to save them so that they are permanent, we can do this in Fedora with:
And they are saved in:
In Debian, we can execute:
/etc/init.d/iptables save name-rules
We have to be careful and ensure that the directory /var/log/iptables already exists, as this is where the files will be saved; name-rules will be a file in the directory.
With (/etc/init.d/iptables load) we can load the rules (in Debian, we have to provide the name of the rules file), although Debian supports some default file names, which are active for the normal rules (the ones that will be used when the service starts) and inactive for the ones that will remain when the service is deactivated (or stopped). Another similar method that is commonly used is that of putting the rules in a script file with the iptables calls that are necessary and calling them, for example, by putting them in the necessary runlevel, or with a link to the script in /etc/init.d.
With regard to the configuration tools that are more or less automatic in the firewall, there are various possibilities, but we should remember that they do not usually offer the same features as the manual configuration of iptables (which in most cases, is the recommended process). Some tools are:
lokkit: in Fedora/Red Hat, on a very basic level, the user can only choose the desired security level (high, medium or low). Afterwards, the services that would be affected are shown and we can leave it, or not, so that we pass on to the service changing the default configuration. The mechanism used beneath is the iptables. The final configuration of the rules that is made can be seen at /etc/sysconfig/iptables which, in turn, is read by the iptables service, which is loaded on boot up or when stopping or booting using /etc/init.d/iptables with the start or stop options. It is also possible to install it in Debian, but the rules configuration should be left in /etc/defaults/lokkit-l and a script in /etc/init.d/lokkit-l. There is also a graphic version called gnome-lokkit.
Bastille [Proa]: this is a fairly complete and educational security program that explains different recommended security settings and how we can apply them step by step; it also explains the configuration of the firewall (the program is interactive). It works in various distributions, including in both Fedora and Debian.
fwbuilder: a tool that can be used to build the rules of the firewall using a graphical interface. It can be used in various operating systems (GNU/Linux, both Fedora and Debian, OpenBSD, MacOS), with different types of firewalls (including iptables).
firestarter: a graphical tool (Gnome) for creating a firewall. It is very complete, practically managing all the possibilities of the iptables, but, likewise, it has assistants that make it easy to set up a firewall intuitively. Likewise, there is a real-time monitor for detecting any intrusions.
Normally, each of these packets uses a rules system that is saved in its own configuration file and that usually starts up as a service or as a script execution in the default runlevel.
Even if we have well-configured firewalls, we have to remember that they are not an absolute security protection, as there are complex attacks that can pass over the firewalls or falsify the data to create confusion. In addition, modern connectivity sometimes needs to force us to create software that will bypass the firewalls:
Example 9-23. Note
We should never rely on one single mechanism or security system. The security of the system must be established at all the different levels.
Technologies, such as IPP, the printing protocol used by CUPS, or WebDAV, the authoring and versioning protocol for websites, make it possible to bypass (or make it necessary to bypass) the configurations of the firewalls.
A technique called tunnelling is often used (for example, with the abovementioned protocols and others). This technique basically encapsulates the non-permitted protocols, on the basis of others that are permitted; for example, if a firewall only permits HTTP traffic to pass (port 80 by default), it is possible to write a client and server (each one on one side of the firewall) that can speak in any protocol known to both, but in which the network is transformed into a standard HTTP, which means that the traffic can bypass the firewall.
Therefore, although firewalls are a very good solution for most security-related aspects, they can always have vulnerabilities and let traffic that is considered valid through, which then includes other possible sources of attack or vulnerabilities. With regard to security, we should never consider (and rely on) only one single solution and expect it to protect us from everything; it is necessary to examine the various problems, to propose solutions that will detect any problems on time and to establish prevention policies that will protect the system before any harm is done.