Cover V12, I07

Article
Figure 1

jul2003.tar

Testing an iptables Firewall from within the Host

Edward L. Haletky

Tools such as Nessus and Nmap are essential for searching out the vulnerabilities of iptables-based firewalls. Other articles have discussed these utilities in detail. (See "Proactively Protecting VPN with Nessus", Sys Admin March 2003.) One complication of working with these testing tools is that they are designed to launch their test attacks from across the network. It is difficult to test external firewall rules from within the firewall host. This article describes a technique for configuring an iptables firewall host using User-Mode Linux so the host can test its own external firewall rules.

The Problem

Firewall testing tools such as Nessus are designed to attack the firewall over the network through an external interface. This arrangement has the benefit of being similar to a real attack, in which a remote intruder scans the firewall to seek out a method of entry. However, it is sometimes more convenient to have a means of testing the firewall's external rules through some process running internally on the firewall host. An internal test simplifies the testing process, since it requires interaction with only one computer: the firewall host itself. Internal testing also lets you test your firewall rules without first placing an untested (and possibly insecure) host on the network.

Iptables rules are invoked only when you route through the network device, whether physical or logical, and not if you touch the device. At first glance, you might think it is possible to test a firewall from within the host by installing a logical network device and logging any access to the device. However, in my case, this strategy did not produce any logged output. For example, given the following Ethernet and iptables setup:

ifconfig eth0 192.168.0.154 up
route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.154 dev eth0
iptables -A INPUT -i eth0 -j LOG
iptables -A OUTPUT -o eth0 -j LOG
if you try the following:

ping 192.168.0.154
no iptables log is produced, but if you try the following:

ping 192.168.0.155
then an OUTPUT log is produced.

Unfortunately, to invoke the iptables rules you must route through the physical or logical device to another IP address not existing on the host. Even if you set up an IP-to-IP tunnel from a device to another on the system, the kernel will know you are talking to a local device and bypass your iptables rules. Kernel routing is what makes testing firewalls from the host infernally difficult. Unless you route through the device you cannot access any iptables rules.

A Solution

One common solution to this problem is to set up a virtual test machine within the firewall host using VMWare. Although VMWare does successfully scan the firewall from within the firewall host, it also costs a lot, takes a lot of resources, and only runs in graphical mode, which is not good for scripting purposes. Also, the VMWare solution requires you to migrate your complete firewall rules to a VMWare session to run complete tests.

I devised an alternative solution around the shareware virtual machine tool User-Mode Linux (UML). UML, which can be found at:

http://user-mode-linux.sourceforge.net
uses virtual machine technology and Linux kernel modifications to create an instance of Linux that can run as a User-Mode program. UML's processes are seen by, and can be controlled by, the host. Implementing UML is straightforward and relatively simple. All it requires is disk space, at least initially, and the installation of some new tools. (For more information on User-Mode Linux, see: http://www.samag.com/documents/s=8214/sam0304web/.)

My solution is depicted in Figure 1. I created an Ethertap device on the firewall host (as described later in this article) and mapped the firewall rules to the Ethertap device. I then created a virtual Linux machine on the firewall host using UML and used the UML instance to launch the testing tools that attack the firewall through the Ethertap connection.

Setting Up Ethertap

Ethertap devices will be available to you by default, as they are contained within the default Linux kernel. The TAP device was first created to allow a user to get ahold of the raw Ethernet packet data. Access to this data is incredibly important for the creation of Virtual Private Network (VPN) programs. Most VPNs do not live in kernel space but instead run in user space. The TAP device gives direct access to the datalink layer of the networking stack and therefore a Ethertap device is referred to as a datalink device.

Follow these steps to verify or enable in your kernel:

make menuconfig
Select 'Network device support'
Select 'Universal TUN/TAP device driver support'
Select 'Ethertap network tap (OBSOLETE)'
Exit and save your configuration
Once you boot using the new kernel, the Ethertap device will be available. But "Hey, you used an obsolete device?" That's correct, we must use the devices that are available to UML, such as Ethertap and TUN/TAP. However, I found it much easier to use the Ethertap device rather than the TUN/TAP device. Both are usable, however. There is no need to create or do anything more because the uml_net helper program provided when installing UML will do all that is necessary. If you would rather make the devices yourself, you can do this by using ifconfig directly.

Setting Up User-Mode Linux

See the UML documentation for information on installing UML. I followed these steps:

1. Download user_mode_linux-2.4.18.26um-0.i386.rpm

2. Download root_fs.rh-7.2-full.pristine.20020312.bz2

3. Install using 'rpm -root . --nodeps' the rpm

4. Uncompress the root_fs file using bunzip2

In Step 3, I installed the tools into a non-system directory so that I did not overwrite the existing UML tools. Once these steps have been completed, you can execute UML using:

./usr/bin/linux -ubd0 root_fs.rh-7.2-full.pristine.20020312 -umid \
  rh72 -eth0 ethertap,tap0,fe:fd:0:0:0:1,192.168.0.254
The preceding command sets the default hard disk file system to "root_fs.rh-7.2-full.pristine.20020312", the UML ID to "rh72" so that it can be controlled externally, and the Ethernet device to "tap0". For UML to connect to the host, the Ethernet must be set up properly. When UML is first run, it will create a host-side address and create the appropriate route using a setuid helper program. You can, alternatively, create your own. The proper route is required on the UML side to route through the Ethertap to the LAN.

When specifying the Ethertap device on the command line, we give the arguments to the TAP device (tap0) in use. We also need to specify a dummy Ethernet MAC address. The MAC address specified is defined by the UML documentation. Be careful to pick a proper address, since the wrong setting can specify the wrong type of device. All of this is defined in the UML documentation, and I urge anyone using UML to peruse all the documentation before implementation. Lastly, specify the IP address to use for the host side of the device. The default is in use until you can log in and make modifications.

You can halt UML using:

./usr/bin/uml_mconsole rh72
(rh72) halt
If you need to use a different set of IP addresses, you must start UML and change its settings before changing the host side. The default routes for UML are not always correct, but that depends on the root file system you are using, as there are many to choose. The root file system I chose does not have any routing issues; however, some of the others (root_fs_toms1.7.205) may have routing problems that will need to be fixed before beginning.

Once the network is working, you can install the firewall testing tools into UML. I use Nessus and Nmap in combination to test my firewalls. Once those tools are configured and tested, you can begin to script your UML session. Unfortunately, the root file system chosen in this example does not contain an RPM database so installation requires the use of the -nodeps option to RPM. You will need to start UML and either set up network services (because there are none in UML) or log in to UML and ftp the files from the host. (The latter method is recommended because it's easier.)

Nessus and Nmap require very little in the way of network services to run besides a simple network connection (i.e., can you ping an address on the host). Nessus is a complete server/client package and also only requires a valid network connection. I generally start up either SSH or FTP in UML to aid in the transfer of needed RPMS to UML, but they are not required. However, you must have a complete network between UML and the host. You should test this by using ping to the UML address from the host, and vice versa from UML.

Anatomy of an Incoming Firewall Test

To test all firewall rules, we must create a test that will check all aspects. This means we might need to tweak our existing rules first. Make sure your non-iptables rules do not allow access from your test network address range. In most cases, you must ensure that your host-based access is strict enough. Once this step is completed, we can continue with the scriptable part. But remember to transfer or set up something like SSH in the UML session to transfer any tools to UML.

Here are the general steps to follow:

1. Write a script that will map your external network iptables device rules to the tap0 device. You can automate this step (my preferred method) or maintain a duplicate firewall setup script. The possibility of not putting a new change into both is high, so I recommend writing a script.

2. Using Expect, write a script that will automatically spawn UML and log in as root to the UML session. UML can either be graphical or textual. The text interface is the console for UML and should be used to log into the UML session or you cannot write a script. Running extraneous servers like XFree86 is a waste of needed cycles.

3. At a UML session prompt, start your first test tool (e.g., Nmap). Be sure to specify the attacked IP address to be the external IP address of the host, to force the packets to be routed through the Ethertap device. You could also use any other device except the loopback device. If you use Nessus, you will need a pre-existing .nessusrc file. You can create this on the host and transfer it to UML. You may also want to grab the latest rules before loading Nessus. If this is a standalone machine, do this upon installation of Nessus. However, if this is just a periodic scan, you may want to grab these rules as part of the scan script.

4. Log the output of Nmap for later analysis. At the next UML session prompt, sync the disks. Be sure you capture only the output of the test tool or else you will collect a log of the possibly long UML boot process. Also, tune the Expect timeout accordingly.

5. At next prompt, spawn a uml_mconsole command on the host and halt the UML session. I found using shutdown-style commands to be troublesome and the uml_mconsole command to be safe and immediate.

6. Perform any automated analysis of the results (e.g., sending email). All vulnerabilities must be documented and understood. I recommend making a known good set of outputs and running some sort of comparison; any differences could point to possible problems.

7. Remove the tap0 rules and devices if necessary. It's best to remove the iptables test rules when finished so that a new test will overwrite them completely. These rules are unnecessary without a tap0 device and can cause iptables invocation to make unnecessary checks and slow down all packet filtering.

By only copying over your external device-specific iptables rules and routing through to the external address, you ensure that all your firewall rules are invoked. Once done, all your incoming rules have been tested.

The presence of tools and scripts such as those described in this article on the firewall host could raise security issues that are worthy of your careful attention. You must determine whether this type of arrangement works for your environment and take the necessary precautions. If you plan to use this tool, please consult with your IT department before implementing to make sure all security policies and procedures are considered.

The Other Half

Occasionally, it is also wise to run the tests from inside to outside to also test the outgoing rules. To run these tests, you must specify the target address. Using the UML session as the target has the distinct advantage that you can control the response to this type of scan and you do not need permission from a third party or even another machine. Testing your outgoing filters is perhaps easier than testing the incoming filters.

Outgoing Test Steps

1. Map the external device-specific iptables rules to tap0. By doing this, your device-specific outgoing rules will be duplicated and applied to the foreign destination represented by tap0 and UML.

2. Start the UML session using Expect, invoking your tests when the UML session login prompt occurs. Thus, you are assured of a good UML startup.

3. Run your security tests against the UML session address, logging all the results. If you are using Nessus as one of your tests, be sure to start up the Nessus server before running the scan and disabling it afterwards.

4. Perform some automated analysis of the log file and store the other for future hand analysis. A good automated analysis will produce a baseline and then a difference between each of the runs with the baseline. If there are any differences, these should be addressed. The advantages of using a UML session are greater than any other type of system. The UML session is completely under your control, so you can control the responses to the security tests as well.

5. Be sure to use uml_mconsole to disable the UML session when completed.

But That's Not All

Besides doing the outgoing and incoming tests described here, you may also want to run a scan against your external IP address just to see what services are running on the box. A test of this nature, where you are not routing through an interface will bypass all your iptables rules and produce a list of services running on your machine. This informational scan will let you know if there is an unknown server on your host and is really not useful for any other purpose. If, for instance, you had these tools stored on a device like a floppy with a hardware read-only setting, you can ensure these tools are never corrupted. Now your outgoing firewall rules have been tested without leaving your own host.

Conclusion

As I have shown, you can easily script the testing of all firewall rules from within the firewall host. You don't need to place a machine upon a network in order to test the firewall, and you can run your tests before you ever connect. The benefits are enormous. This method provides a completely Linux-based test tool that is inexpensive and easy to implement. I envision that users could customize their UML file systems to further speed up testing. The time required to run the tests will also be increased, as there is no longer a complex network to wend through in order to scan a host. In most cases, a Nessus scan might take 2 hours with a lot of hops, however, on a LAN, it might take 20 to 30 minutes. Local access is sped up even more.

For virtual office workers and for IT departments that need to control access to many machines, the tool can be used to warn administrators of problems, without their intervention, or even a live network connection. Administrators are no longer dependent upon having the network up to run any security scan. This implies that such tests can be run on boot and as part of nightly, weekly, or monthly tests. The machines themselves can let us know the results.

Once you have the results, they must be interpreted and failures must be investigated as usual, but the method described drastically changes the current method of data collection and the amount of work required. Using UML as a part of a security toolbox provides many useful features not otherwise available.

Edward L. Haletky graduated from Purdue University in 1988 with a degree in Aeronautical and Astronautical Engineering. Since then, he has worked programming graphics and other lower-level libraries on various UNIX platforms. He currently works for Hewlett-Packard in the High Performance Technical Computing team and as a security consultant for the virtual office community.