I'm working on a firewall for a virtual dedicated server and one of the things I'm looking into is port scanners. TCP flags are used for protection. I have 2 questions.
The rule:

-p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j DROP

First argument says check packets with flag SYN Second argument says make sure the flags ACK,FIN,RST SYN are set
And when that's the case (there's a match), drop the tcp packet

First question:
I understand the meaning of RST and RST/ACK but in the second argument RST SYN is being used.
What's the difference between RST SYN and RST and SYN RST ?
Is there a "SYN RST" flag in a 3 way handshake ?

Second question is about the difference between

-p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j DROP    


-p tcp --tcp-flags ALL SYN,ACK,FIN,RST SYN -j DROP    

When should ALL be used ?
When I use ALL, does that mean if the tcp packet with the syn flag doesn't have the ACK "and" the FIN "and" the RST SYN flags set, there will be no match ?

2 Answers 2



-p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j DROP

means "look at the flags syn, ack, fin and rst and match the packets that have the flag SYN set, and all the other unset"

The first argument of tcp-flags is the flags your are considering, the second argument is the mask you want to match. if you were using

--tcp-flags SYN,ACK SYN

then it would match packets that have [SYN=1 ACK=0], but it would not match packets that have [SYN=1,ACK=1] or [SYN=0,ACK=1] or [SYN=0,ACK=0]

In your rule above, you are matching SYN packets only.


I think you have this switch confused.

The --tcp-flags switch takes two arguments only. The first argument is which flags to check. The second argument is the flags from the first argument that should be set for a match. Thus your line:

-p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j DROP

Is saying: "Match if only the SYN flag is set from these four. (The space separates the first and second arguments.)

-p tcp --tcp-flags ALL SYN -j DROP

means check ALL flags and match those packets with nothing but SYN set. The third of your examples is bad syntax, since it gives three arguments. Your first rule would drop all new TCP connections coming in, which probably isn't what you want.

The switch is mostly used to drop packets with meaningless TCP flags set. You wouldn't, for instance, get legitimate packets with both SYN and RST set, for instance or SYN and FIN. Take this snippet from one of my* firewall scripts:

${IPTABLES} -t filter -A INETIN -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
${IPTABLES} -t filter -A INETIN -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
${IPTABLES} -t filter -A INETIN -p tcp --tcp-flags SYN,URG SYN,URG -j DROP

These check for specific combinations of TCP flags that should never occur naturally and drop the packets.

More reading at the man page.

*(Tweaked version of monmotha-2.3.8)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .