Find out if your firewall really works the way you think it should.
So, you’ve set up a firewall and done a few cursory tests to make sure it’s working, but have you tested the firewall to be sure that it’s blocking everything it’s supposed to? You might not have done this because you think it will take too long or be too difficult. Luckily, there’s FTester
(http://dev.inversepath.com/trac/ftester/
), a free tool for doing extensive firewall tests.
FTester consists of three Perl scripts. The ftest script is used for injecting custom packets as defined in the configuration file ftest.conf. If you are testing how the firewall behaves with ingress traffic, you should run this script on a machine outside of your firewalled network. If you want to test your firewall’s behavior toward egress traffic, you will need to run ftest from a machine within your firewall’s protected network.
One of the other scripts, ftestd, listens for the packets injected with ftest that come through the firewall that you are testing. You should run this script on a machine within your internal network if you are testing the firewall’s ingress behavior. If you are testing egress behavior, you’ll need to run it on a machine external to your network. Both of these scripts keep a log of what they send or receive. After a test run, their respective logs can be compared using the freport script, to quickly see what packets were able to get through the firewall.
Before you can use FTester, you will need the Net::RawIP
, Net::PcapUtils
, and
NetPacket
Perl modules. You will also need the Net::Pcap
module if it is not already installed, since the Net::PcapUtils
module depends on it. If you have the CPAN Perl module available, you can install these modules with the following commands:
#perl -MCPAN -e "install Net::RawIP"
#perl -MCPAN -e "install Net::PcapUtils"
#perl -MCPAN -e "install NetPacket"
Once these modules are available on the systems you will be using to conduct your firewall test, you will need to create a configuration file to tell ftest what packets it should generate.
Here’s the general form for a
TCP or UDP packet in ftest.conf, where source
addr
and source port
are the source IP address and port, and dest addr
and dest port
are the destination IP address and port:
source addr
:source port
:dest addr
:dest port
:flags
:proto
:tos
Address ranges can be specified in the low
-
high
format or by using CIDR notation. You can also specify port ranges using the low
-
high
format. The flags
field is where you specify the TCP flags that you want set for the packet. Valid values for this field are S
for SYN
, A
for ACK
, P
for PSH
, U
for URG
, R
for RST
, and F
for FIN
. The proto
field specifies which protocol to use (either TCP
or UDP
), and tos
contains the number to set for the
Type-of-Service (ToS) field in the IP header. Sometimes, routers use the contents of this field to make decisions about traffic prioritization. You can get more information on the ToS field by reading RFC 791 (http://www.ietf.org/rfc/rfc0791.txt
), which defines the Internet Protocol.
You can define ICMP packets in a similar manner. Here’s the general form for one:
source addr
::dest addr
:::ICMP:type
:code
As you can see, the main difference between the two forms is the omission of port numbers and flags, which ICMP does not use. Instead, it uses types and codes (hence the addition of the type
and code
fields). Currently, there are over 40 ICMP types. The ones used by the ping utility, echo (type 8) and echo reply (type 0), or the type used by the traceroute
command (type 30), might be familiar to you. ICMP codes are like subclassifications of ICMP types. Not all ICMP types have ICMP codes associated with them, although there are roughly the same number of ICMP codes as types. You can find out more about ICMP types and codes by reading the Internet Assigned Numbers Authority’s assignments for them at http://www.iana.org/assignments/icmp-parameters
.
Here’s an ftest.conf that will check all of the privileged TCP ports on a machine with the IP address 10.1.1.1:
192.168.1.10:1025:10.1.1.1:1-1024:S:TCP:0 stop_signal=192.168.1.10:1025:10.1.1.1:22:S:TCP:0
stop_signal
creates a payload for the packet that will tell ftestd that the testing is over. For quick tests, you can use the -c
option and specify a packet to send using the syntax described previously. For instance, the following command sends a packet with the source IP address and port of 192.168.1.10:1025 to port 22 on 10.1.1.1.1:
# ./ftest -c 192.168.1.10:1025:10.1.1.1:22:S:TCP:0
Before starting ftest, you should start ftestd:
# ./ftestd -i eth0
Then, run ftest:
# ./ftest -f ftest.conf
This command creates a log file called ftest.log containing an entry for every packet ftest sent. When ftestd receives the signal to stop, it will exit. You can then find its log of what packets it received in ftestd.log.
Now, you can copy the logs to the same machine and run them through freport. If you used a configuration file like the one shown earlier and were allowing SSH, SMPTP, and HTTP traffic, you might get a report similar to this:
# ./freport ftest.log ftestd.log
Authorized packets:
-------------------
22 - 192.168.1.10:1025 > 10.1.1.1:22 S TCP 0
25 - 192.168.1.10:1025 > 10.1.1.1:25 S TCP 0
80 - 192.168.1.10:1025 > 10.1.1.1:80 S TCP 0
Modified packets (probably NAT):
--------------------------------
Filtered or dropped packets:
----------------------------
1 - 192.168.1.10:1025 > 10.1.1.1:1 S TCP 0
2 - 192.168.1.10:1025 > 10.1.1.1:2 S TCP 0
3 - 192.168.1.10:1025 > 10.1.1.1:3 S TCP 0
If you are using a stateful firewall and want to test this functionality, you can also specify packets that have flags other than SYN
set. For instance, if the previous example had used ACK
or some other flag instead of SYN
, it would have been dropped by the firewall because only packets with the SYN
flag set are used to initiate connections.
It’s a good idea to run ftest each time you make changes to your firewall, or periodically just to make sure that your firewall works as you expect. While complex rulesets on your firewall can sometimes make it difficult to predict exactly how it will behave, ftest will tell you with good authority exactly what kinds of traffic are permitted.