Between our gateway and our LAN, we have a bridging firewall running iptables. I want to add an additional NIC into the firewall and set up a private subnet on it. Traffic from this subnet which is destined for external addresses will be NAT-ed so that it originates from the IP address configured on the bridge.

I want the firewall to route packets between our LAN and the private subnet without NATing. How can I tell iptables that if a packet from the LAN passes through the bridge and is destined for a private IP that it should send this packet out of the additional non-bridged interface?

  • really bridging? Or rather a proxy-ARP setup? – the-wabbit Jan 13 '12 at 22:20
  • Yep, really bridging. – Gaspode Jan 16 '12 at 9:24

We do something quite similar here. 3 subnets behind a CentOS5 "router". Basically we just have iptables set to the follow 'nat' table rule:

iptables -t nat -A POSTROUTING -o <external NIC device> -j SNAT --to-source <external interface IP>

In our case, device is eth1 and the IP is to differentiate from the Class C IP4 subnets we're still using here.

The real work is done by the routing table. If your NICs are configured properly, the routing table entries should already exist.

For instance, we have these two subnets in the routing table:   U     0      0        0 eth0   U     0      0        0 eth2

But the external traffic is handled by the default gateway line:         UG    0      0        0 eth1

And traffic coming back in through the NAT is tracked by the netfilter module in the kernel and sent to its originating IP by the 'State RELATED,ESTABLISHED' line in the regular chain FORWARD in iptables:

 158M  168G ACCEPT     all  --  eth1   eth0             state RELATED,ESTABLISHED 
  8M   11G ACCEPT     all  --  eth1   eth0             state RELATED,ESTABLISHED 

(Note: Any neckbeard want to correct errors in this, please pop in a comment. I'd love to hear a critique.)

  • Stupid markdown parsing stripped out some of the answer. Please take a look – Magellan Jan 13 '12 at 22:14
  • Unsure if that would work here - eth0 and eth1 don't have IP addresses. The bridge between them has an IP. Our gateway is on (for example) and the firewall's in front of the gateway. 123.1.1.x LAN traffic passes through the bridge to get to the gateway. Traffic from 10.x.x.x addresses on eth2 can be NATed out of the bridge interface but I can't think of any way that traffic from 123.1.1.x to 10.x.x.x can be routed out via eth2 as it's not going 'via' the firewall, just through its bridge.. It may not be possible but am trying to avoid changing the current setup too much.. – Gaspode Jan 16 '12 at 9:29

I don't think you will be using iptables for the routing, since that's not what takes care of the routing. Iptables is for anything to do with checking or changing IP packets; the routing tables are somewhat "blind" in that respect, they just send stuff where their entries tell them.

What I would try do do here is add routing entries on the firewall that tell it to use the additional NIC if the new subnet behind the new NIC is addressed; that should take care of sending stuff to and from there. Then you might want to add some entries in iptables to make sure only packets originating from your LAN are passed into your LAN or whatever policies you want to enforce.

Regarding not having your firewall NATing traffic that's just passing from one part of the LAN to the other, you can just use the NATing rule that @AdrianK gave and which you probably are already using:

iptables -t nat -A POSTROUTING -o < external NIC device > -j SNAT --to-source < external interface IP >

If you're not using a static IP address for the "external" interface of the firewall, you can change "SNAT" to "MASQUERADE" (but you're probably aware of that, just for completeness' sake).


I doubt anyone else will have the same problem as I did but here's the best solution I found (obviously, removing the bridge would be best but wasn't possible)

I installed ebtables and used this command:

ebtables -t broute -A BROUTING -p IPv4 --in-if eth1 --ip-dst -j redirect --redirect-target ACCEPT

..this stops the matching packets from being bridged and means they're routed instead.

Inspiration found here:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.