Linux – netfilter/iptables: why not using the raw table

iptableslinux

Under Linux, we usually use the "filter" table to do common filtering:

iptables --table filter --append INPUT --source 1.2.3.4 --jump DROP
iptables --table filter --append INPUT --in-interface lo --jump ACCEPT

According to the netfilter flow chart below, the packets first travel through the "raw" table:

enter image description here

So we can write:

iptables --table raw --append PREROUTING --source 1.2.3.4 --jump DROP
iptables --table raw --append PREROUTING --in-interface lo --jump ACCEPT
  • the packets are handled sooner, without the need to go though conntrack+mangle+nat+routing. So lightly less CPU/memory used (and in turn lightly compensated by the fact the iptable_raw module has to be loaded)
  • only one rule in case the box is also a router (won't be ok for every rules, obviously) because there is no need to add the same rule for filter/forward

I did only rapid tests, and this works perfectly well.
The documentations I found always describe the raw table to be used in strict cases. But none give even the smallest justification.

Question: is there any reasons not to use the raw table, apart dogmatic ones ?

Best Answer

From man iptables:

raw: This table is used mainly for configuring exemptions from connection
     tracking in combination with the NOTRACK target. It registers at the
     netfilter hooks with higher priority and is thus called before
     ip_conntrack, or any other IP tables.
     It  provides the following built-in chains:

     - PREROUTING (for packets arriving via any network interface)
     - OUTPUT (for packets generated by local processes)

Analysis:

So, the RAW table is before conntrack and it was designed with the objective to be used to set the NOTRACK mark on packets that you do not wish to track in netfilter.

The -j targets are not restricted only to NOTRACK, so yes, you con filter packets in the raw table with the benefits of less CPU/memory consumption.

Most often, servers don't need to keep track of all connections. You only need tracking if you need to filter packets in iptables based on previous established connections. On servers that only serve a simple purpose like with only port 80 (and maybe 21) open, don't require that. In those instances, you can disable connection tracking.

However, if you're trying to run a NAT router, things get slightly complicated. In order to NAT something, you need to keep track of those connections so you can deliver packets from the outside network to the internal network.

If a whole connection is set with NOTRACK, then you will not be able to track related connections either, conntrack and nat helpers will simply not work for untracked connections, nor will related ICMP errors do. You will have to open up for these manually in other words. When it comes to complex protocols such as FTP and SCTP and others, this can be very hard to manage.

Use cases:

One example would be if you have a heavily trafficked router that you want to firewall the incoming and outgoing traffic on, but not the routed traffic. Then, you could set the NOTRACK mark for ignore the forwarded traffic to save processing power.

Another example when NOTRACK can be used is if you have a highly trafficked web-server, you could then set up a rule that turns of tracking for port 80 on all the locally owned IP addresses, or the ones that are actually serving web traffic. You could then enjoy stateful tracking on all other services, except for web traffic which might save some processing power on an already overloaded system.

Example --> running-a-semi-stateless-linux-router-for-private-network

Conclusion: There isn't a strong reason to not to use the raw table, but there is some reasons to take care when using the NOTRACK target in the raw table.

Related Question