Geeks Lunch - Intensive Version -HowTo's




Checking IPTABLES rules with HPING2


How do you know that the IPTABLES rule you just wrote is working?

The way you know your firewall rules are working is to test them.  One of the easiest ways to test them is by constructing specific packet using HPING2.
So lets try some examples.

Entering an IPTABLES rule.
Suppose you want to check for someone trying to open a connection to port 137 (netbios) on your Linux computer and log the attempts in syslog.  Edit the Iptables rules with something like:
vi /etc/sysconfig/iptables
and add a line like:
-A RH-Firewall-1-INPUT -p tcp --dport 137 --tcp-flags SYN SYN -j LOG
(assuming you have a default Fedora Core 3 install)

restart Iptables to pickup the config change with
 /etc/rc.d/init.d/iptables restart
(for the exceptionally paranoid disconnect the Ethernet interface before restarting Iptables to make sure no nasty packets get through during the restart)

Now test the rule.
An easy way to test this rule is using telnet.  Assuming the host with the Iptables rules is 10.10.10.2; telnet to it to port 137 from another host:
telnet 10.10.10.2 137

Check the logs to see if the rule worked.
tail /var/log/messages

You should see something like:
Mar 15 08:21:10 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=39192 DF PROTO=TCP SPT=32806 DPT=137 WINDOW=5840 RES=0x00 SYN URGP=0

Some rules cannot be tested with telnet; they'll need a tool that will let us "craft packets"; create packets with specific parameters.  To start with lets test the same rule with HPING2 instead of telnet.  From another host enter:
hping2 -c 1 -S 10.10.10.2 -p 137

That says send 1 packet (-c 1)  with the SYN flag set (-S) to IP address 10.10.10.2 and port (-p) 137.

If you check the logs on 10.10.10.2 you should see something like:
Mar 15 08:28:52 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=369 PROTO=TCP SPT=2913 DPT=137 WINDOW=512 RES=0x00 SYN URGP=0

Great.  Your rule (and HPING2) is working.


Getting a little more complicated.

Now assume you want to write a rule that will log all packets to port with the SYN and/or ACK flags set.  So you open up /etc/sysconfig/iptables and change the rule to read:
-A RH-Firewall-1-INPUT -p tcp --dport 137 --tcp-flags SYN ACK  -j LOG

now lets test it
hping2 -c 1 -S -A 10.10.10.2 -p 137

but syslog shows nothing.  We've found a problem with our new rule.  The reason is a "brain fart" in the iptables rule  "SYN ACK" means mask on SYN and check for ACK.  Thats not going to work-- ever.   Lets revise the rule and change it to:
-A RH-Firewall-1-INPUT -p tcp --dport 137 --tcp-flags SYN,ACK SYN,ACK  -j LOG

Now lets test it with a packet that has the SYN and ACK bits set
hping2 -c 1 -S -A 10.10.10.2 -p 137

"-S" says set the SYN flag and "-A" says set the ACK flag.  Checking /var/log/messages shows:
Mar 15 08:57:21 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=788 PROTO=TCP SPT=2562 DPT=137 WINDOW=512 RES=0x00 ACK SYN URGP=0

So for so good.  Now lets check for "SYN" and "ACK" separately.
hping2 -c 1 -S 10.10.10.2 -p 137
hping2 -c 1  -A 10.10.10.2 -p 137

Checking /var/log/messages on 10.10.10.2 show that neither packet was logged!  We found another mistake  "SYN,ACK SYN,ACK" says mask on SYN and ACK and check for both SYN and ACK, not each independently.

Final Change.

So lets try another approach and change the iptables line to:
-A RH-Firewall-1-INPUT -p tcp --dport 137 --tcp-flags ! RST RST  -j LOG

This rule says log any packets to port 137 that don't have the RST flag set (which should catch all combinations of SYN and ACK (and a few other things)).

Now lets test the permutations.  First "SYN"
hping2 -c 1 -S  10.10.10.2 -p 137

And check the logs:
Mar 15 09:04:17 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=2107 PROTO=TCP SPT=2731 DPT=137 WINDOW=512 RES=0x00 SYN URGP=0

Great, we caught it.  Now test "ACK"
hping2 -c 1 -A  10.10.10.2 -p 137

Mar 15 09:04:46 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=12256 PROTO=TCP SPT=2385 DPT=137 WINDOW=512 RES=0x00 ACK URGP=0

It shows up too.

and finally "SYN" and "ACK" together.

 hping2 -c 1 -S -A  10.10.10.2 -p 137

and syslog shows:
Mar 15 09:05:20 ClubGeek kernel: IN=eth1 OUT= MAC=00:0e:0c:01:dc:b2:00:08:02:d4:a2:8a:08:00 SRC=10.10.10.7 DST=10.10.10.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=31764 PROTO=TCP SPT=1970 DPT=137 WINDOW=512 RES=0x00 ACK SYN URGP=0
 
Now we've changed Iptables (even though there are other ways of writing the rules) and checked that it catches what we want.




The most recent copy of this document is here.

http://www.geekslunch.com/glivh/Iptables_and_HPING2.html
written by: Monta Elkins

Back to GLIVH's [Geeks Lunch Intensive HowTo's]

email Monta.gl @ [this domain]
Please send you comments/feedback/suggestions