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.
|