3

I'm using IPtables and I have a doubt for which I can't find an answer. I want to apply a rule in the PREROUTING part of the nat table. The rule is supposed to execute a chain but I want it to be executed for every interface except for two of them. I can't use wildcards because I need all of the other interfaces regardless of their name (say I can't have it).

I have applied this rule:

iptables -t nat -A PREROUTING -j my_chain ! -i eth0

That results into this:

Chain PREROUTING (policy ACCEPT 19 packets, 3008 bytes)
pkts bytes target     prot opt in     out     source       destination
10   1538  my_chain   all  -- !eth0   *       0.0.0.0/0    0.0.0.0/0

But I need something like this:

Chain PREROUTING (policy ACCEPT 19 packets, 3008 bytes)
pkts bytes target     prot opt in               out     source      destination
10   1538  my_chain   all  -- !(eth0 or tun0)   *       0.0.0.0/0   0.0.0.0/0

The thing is it cannot be in two different rules because one of these two interfaces will enter into the other interface's rule. I also tried something like:

iptables -t nat -A PREROUTING -j my_chain ! -i eth0 ! -i tun0

But it returns: multiple -i flags not allowed

Basically, I need a way to implement that or in the interface condition or !eth0 and !tun0 (logical equivalent).

I'm using debian with iptables v1.4.21.

Thanks for your help!

2
  • Have you tried adding them as two separate rules? Iptables is a "first-match" firewall system, so it should work as you are expecting. And I don't scan your reasoning for why that can't work. Commented Nov 10, 2016 at 16:06
  • I thought about that but I think that if I add a rule for every interface except eth0 and after that I add the same rule but without tun0 that time, tun0 will enter the one that doesn't accept eth0. Commented Nov 10, 2016 at 16:14

1 Answer 1

2

To solve your problem, you must remember that iptables rules are applied sequentially (as soon as one is found that applies, the packet is removed from the chain and the following rules in the same chain are just skipped), and that you may invent new chains; so let us define two new chains,

 iptables -N chain1
 iptables -N chain2

and now we send packets on tun0 and eth0 to chain1, and everything else to chain2:

 iptables -t nat -A PREROUTING -i tun0 -j chain1
 iptables -t nat -A PREROUTING -i eth0 -j chain1
 iptables -t nat -A PREROUTING -j chain2 

and now you can assign your rules separately to the two chains: for instance, to delete everything on chain2 but not on chain1,

iptables -A chain1 -j ACCEPT
iptables -A chain2 -j DROP

This trick allows you to build a rule equivalent to a boolean OR: if the packet is coming in thru eth0 OR thru tun0, then do... Since boolean AND is easy to implement (for instance, if something comes in thru eth0 and is destined to 8.8.8.8, then.. is equivalent to

 iptables -t nat -A PREROUTING -i eth0 -d 8.8.8.8 ....

), you have both OR and AND connectives, which will allow you to build any truth table in the Boolean logic.

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.