# iptables: rules order.

## kleenex

Hi. I would like to ask about the best place (INPUT chain) in which to place the rule responsible for related and established connections (typical (...) -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT rule). Let say, that default policy for INPUT and FORWARD chains is set to DROP and for OUTPUT chain is set to ALLOW. This firewall is for typical Desktop without any running services. There is also some additional rules in INPUT chain, such as for block/allow icmp protocol or drop INVALID packets etc. iptables checks rules from the top of chain to the bottom, right? So, where is the best place for rule allowing related and established connections? It is better to place this rule at the very beginning, in the middle or the end of the INPUT chain?

Best regards!Last edited by kleenex on Sun Jan 13, 2013 7:51 pm; edited 1 time in total

----------

## PaulBredbury

At the beginning, or very close to it. Example script snippets:

```
ipt=iptables

loc=127.0.0.1

$ipt -A INPUT -s $loc -i lo -j ACCEPT

# https://wiki.archlinux.org/index.php/Simple_Stateful_Firewall

$ipt -N invalid

$ipt -A INPUT -m conntrack --ctstate INVALID -j invalid

$ipt -A invalid -j LOG --log-level warning --log-prefix "invalid: "

$ipt -A invalid -j DROP

# http://spamcleaner.org/en/misc/w00tw00t.html

for s in "/w00tw00t.at." "/phpMyAdmin" "http://login." "/pma/" "/myadmin/" "http://proxy" ; do

    $ipt -A INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string "GET $s" -j DROP

done

$ipt -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
```

----------

## kleenex

Hi Paul. Could You explain to me why this rule should be placed at the beginning? iptables check rules from the top to bottom, right? So, if I have several rules e.g. for INVALID packets, bad flags etc. it seems to me, that it is better to place this rule at the bottom, because iptables will check all the rules in the INPUT chain and allow only the established/related connections and drop all the rest (of course, if they will match) "bad" rules - which are placed from the beginning to the bottom.

a) If during checking rules, one of them will match to - let say - bad flags (e.g. ALL NONE), iptables will drop this connection (in this case, rule for established/related connections is placed at the end of the INPUT chain). 

b) If rule for established connection will be placed on the beggining of the INPUT chain, iptables will not check rest of rules and will do nothing with the rules regarding to e.g. bad flags mentioned above. Do I understand it?

Doh! I'm sorry for such a stupid question, but it always interested me.

----------

## PaulBredbury

 *kleenex wrote:*   

> iptables check rules from the top to bottom, right?

 

Yes. Any beginner's tutorial should tell you that  :Wink: 

Think about performance, rather than just the elegance of the script as it appears to us humans. Using a simple rule to discard a packet, rather than do more checking on it only to discard it later, is a quick and easy win.

----------

## kleenex

Hi Paul. So, according to Your opinion, it is better to put this rule at the beginning of the INPUT chain or very close to it. But there are no contraindications to place this rule at the end of the INPUT chain, right?

Thank You.

----------

## truc

 *kleenex wrote:*   

> Hi Paul. So, according to Your opinion, it is better to put this rule at the beginning of the INPUT chain or very close to it. But there are no contraindications to place this rule at the end of the INPUT chain, right?
> 
> Thank You.

 

It's not really about his opinion but more  about how it's working, you can put your rules in the order you want: the first rule matching a given 'flow' will be used to make the decision whether or not to accept it.

Now if you think about already established traffic, if you have the rule to accept it at the end of the ruleset that means that every rules before this one will have to be 'tested' before the decision is made (I mean every rules has to be tested for _every_ packet from that established connection).

----------

## kleenex

Hi truc! Thank You very much. You described it that way, what I wanted to ask on my 1. post. Summary if rule for established/related connections is at the end of INPUT chain, that means that every rules before this one will have to be 'tested' before the decision is made. So, iptables will check all the rules from the top to bottom of the INPUT chain and if iptables hits on some unrelated rule to established/related connection, like e.g. INVALID packet, they will be blocked/DROP right?

When placed this rule at the beginning of the INPUT chain, everything described above did not work, right (I mean tested for _every_ packet)? If established/related connection rule is at the beginning of the INPUT chain, iptables will not check of the rest rules (to bottom).

According to my opinion; a better place to put established/related rule is the end of the INPUT chain, because of what truc wrote: "if you think about already established traffic, if you have the rule to accept it at the end of the ruleset that means that every rules before this one will have to be 'tested' before the decision is made (...)"

I hope I understood it.

----------

## PaulBredbury

 *kleenex wrote:*   

> a better place to put established/related rule is the end of the INPUT chain

 

Not without good reason, otherwise you're pointlessly slowing down your firewall. As I said.

If you really want to keep pressing this point, then show an example.

man iptables will help, for starters:

```
TARGETS

       A  firewall  rule specifies criteria for a packet and a target.  If the

       packet does not match, the next rule in the chain is the  examined;  if

       it does match, then the next rule is specified by the value of the tar‐

       get, which can be the name of a user-defined chain or one of  the  spe‐

       cial values ACCEPT, DROP, QUEUE or RETURN.
```

----------

## kleenex

 *Paul wrote:*   

> Not without good reason (...)

  Hi Paul. 

I do not understand - what reason do you mean? If iptables checks all rules from the top to down of the INPUT chain, I think it's good or even better (from security point of view(?)). I do not see any slowdown with this configuration, but still I am searching a good solution.

----------

## PaulBredbury

 *kleenex wrote:*   

> checks all rules

 

I think this is where you are going wrong. See howto:

 *Quote:*   

> -j - Jump to the specified target. By default, iptables allows four targets:
> 
>     ACCEPT - Accept the packet and stop processing rules in this chain.
> 
>     REJECT - Reject the packet and notify the sender that we did so, and stop processing rules in this chain.
> ...

 

----------

