-   Linux - Server (
-   -   String filtering using IPTABLES (

bobbera 06-24-2008 04:26 PM

String filtering using IPTABLES
Hi All .

I have a Tomcat web server behind a firewall ( iptables ) and I need to permit to external clients to post only specific string and get reply from the web server ( "demo" for example ) . Other stuff should be declined by iptables .

First I took care of the port forwarding - all web traffic to my external-interface:8001 is being forwarded to the internal:8001 one .And everything works OK , clients can get web reply from the Tomcat internal server .Then I try to allow only specific string requests adding next command :

iptables -A FORWARD -j DROP -p tcp -s -m string ! --string "demo" --algo bm

It should do a job but it doesn't - external clients still can post any string in url path : etc .

My default FORWARD policy is set to ACCEPT .

Looks like inverse ( ! ) command doesn't effect on the traffic .

Any ideas ?
Thanks .

jomen 06-24-2008 04:40 PM

I consulted the man page for iptables.
It says:

--string pattern
Matches the given pattern...
It does say nothing about the use of "!" to achieve the opposite result.
This inverse "!" match is not available I'd say.

I'd rewrite the rule to match the string to be allowed - and everything else dropped afterwards - if this is what you intended.

bobbera 06-25-2008 02:22 AM

Hi Joman .

I had the same idea more or less . Putting first in a rule string taht allowed and close other stuff . But what would be a ssecond rule . I played with default FORWARD policy but to no success .

When I implement next solution it blocks all the traffik :

iptables -A FORWARD -j ACCEPT -p tcp -m string --string "scp" --algo bm
iptables -A FORWARD -j DROP

About ! . Check next command: iptables -m string --help
UIt says follow among others : --string [!] string Match a string in a packet

Thanks man.

jomen 06-25-2008 03:13 AM

I think you should add
--source-port or --destination-port
-s x.x.x.x/x
As it is now, you are dropping everything on any port with proto tcp not containing the string.

And yes you are right:
--string [!] string should work - it is just not explicitly in the man-page - the help tells different and should be correct.
Your first example should do what you want unless the options need to be in a certain order.

I have always written the rules so that the target (-j) was last in line - I'm not sure if it has to be like that.
I find it easier to read.
In all the examples I ever saw it was done like that.
So maybe this will help though it seems like black magic.

bobbera 06-25-2008 05:37 AM

That is exactly I'd like to have : "As it is now, you are dropping everything on any port with proto tcp not containing the string" If I understand you corretly .

I want to drop all packets not contain "scp" string :

ALLOW my string

1. iptables -A FORWARD -p tcp -m string --string "scp" --algo bm -j ACCEPT

and DROP all other stuff :

2 . either iptables -A FORWARD -p tcp -m string ! --string "scp" --algo bm -j REJECT

or iptables -A FORWARD -j DROP

do not provide a solution .


bobbera 06-25-2008 08:27 AM

Looks like slution is found :

1. iptables exams first all TCP packets and only afterwards looks for match strings .That is why

iptabes -A FORWARD -p tcp --dport 8001 -j DROP blocked all the stuff .

2. string filtering takes into consideration ALL , absolutely ALL traffic . That is why command

iptables -A FORWARD -p tcp -m string ! --string "scp" --algo bm --to 65535 -j DROP

did not worked , since it does not distinguish between data(usl) and tcp service packets .

Here what works :

iptables -A FORWARD -p tcp -m tcp --tcp-flags PSH PSH -m string --string ! "scp" --algo bm --to 65535 -j LOG --log-prefix "NOT SCP:8001--" --log-level 6
iptables -A FORWARD -p tcp -m tcp --tcp-flags PSH PSH -m string --string ! "scp" --algo bm --to 65535 -j DROP

All times are GMT -5. The time now is 08:49 AM.