In order to test the iptables string matching feature, we construct a simple iptables rule that uses the string match extension to verify that it functions as advertised. The following rule uses the iptables LOG target to generate a syslog message when the string "tester" is sent to a Netcat server that is listening on TCP port 5001. (We need the ACCEPT rule so that the default iptables policy from Chapter 1 will allow the establishment of the TCP connection from an external source.)
[iptablesfw]# iptables -I INPUT 1 -p tcp --dport 5001 -m string --string "tester" ©--algo bm -m state --state ©ESTABLISHED -j LOG --log-prefix "tester" [iptablesfw]# iptables -I INPUT 2 -p tcp --dport 5001 -j ACCEPT
Notice at © above the --algo bm command-line argument to iptables. The string match extension is built on top of a text-searching infrastructure in the Linux kernel (located within the linux/lib directory in the kernel sources). It supports several different algorithms, including the Boyer-Moore string search algorithm (the bm above), and the Knuth-Morris-Pratt string-searching algorithm (kmp).1
The -m state --state ESTABLISHED command-line arguments at © restrict the string match operation to packets that are part of established TCP connections, and this means that someone cannot cause the iptables rule to match on a spoofed packet from an arbitrary source address—a bidirectional connection must be established.
We'll use Netcat to spawn a TCP server that listens locally on TCP port 5001, and then we'll use it again from the ext_scanner system as a client to send the string "tester" to the server:
[ext_scanner]$ echo "tester" | nc 71.157.X.X 5001
Now we'll examine the system logfile for evidence that the string match rule generated the appropriate syslog message:
[iptablesfw]# tail /var/log/messages | grep tester Jul 11 04:19:14 iptablesfw kernel: tester IN=eth0 OUT=
MAC=00:13:d3:38:b6:e4:00:30:48:80:4e:37:08:00 SRC=144.202.X.X DST=71.157.X.X LEN=59 TOS=0x00 PREC=0x00 TTL=64 ID=41843 DF PROTO=TCP SPT=55363 DPT=5001 WINDOW=92 RES=0x00 ACK PSH URGP=0
Notice the log prefix tester in bold above. By examining the remaining portion of the log message, we can confirm that the associated packet was sent from the ext_scanner system to our Netcat server listening on TCP port 5001.
NOTE We could have achieved the same result as above by using telnet (running in line mode) as our client instead of Netcat, so that the entire string "tester" is contained within a single packet. This works well enough, but telnet has some serious limitations: It is unable to interact with UDP servers, and it is also difficult to use telnet to generate arbitrary non-printable characters.
Was this article helpful?