Iptables rules with ! character

The problem is that you can't refer multiple IP ranges in a single iptables rule, but using multiple rules indirectly leads to a disjunction (logical OR): connections will be logged if they match your first, OR your second rule.

What you want, is a conjunctive behavior (logical AND): new connections coming out of 10.51.0.0/16, AND also out of 192.168.0.0/16need to be logged.

This is why you can't find that simple solution which you want. There isn't.

But you can solve this by only a little bit more complex way. You can create a new chain:

iptables -N logger
iptables -A INPUT -j logger
iptables -A logger -s 192.168.0.0/16 -j RETURN
iptables -A logger -s 10.51.0.0/16 -j RETURN
iptables -A logger -j LOG

What these commands do:

  1. they create a new table, named logger.
  2. We set up iptables for every connection to try his table as well.
  3. this logger table checks if your packets originating from your trusted networks (192.168.0.0/16 and 10.51.0.0/16). If yes, all goes normally (the RETURN target gives back the control to the originating table).
  4. If not, the connection is logged (and, as we are on the end of the table, the control also returns to the origin).

As a side effect, you can later use this new table for other tasks as well - for example, to REJECT packets or any other purpose. On my opinion the best if we see iptables as if it were some like a simple programming language.


Incoming connections are always going to match one of those rules aren't they?

A connection from 10.51.0.1 for example won't get logged by the first rule but will hit the second one.

Don't you need the equivalent of !10.51.0.0/16 && !192.168.0.0/16 (probably not valid syntax but correct logically).