title: iptables/ebtables/bridge-utils: PREROUTING/FORWARD to another server via single NIC
body: <p>We have a number of iptables rules for forwarding connections, which are solid and work well.</p>
  
  <p>For example, port 80 forwards to port 8080 on the same machine (the webserver).  When a given webserver is restarting, we forward requests to another IP on port 8080 which displays a Maintenance Page.  In most cases, this other IP is on a separate server.</p>
  
  <p>This all worked perfectly until we installed bridge-utils and changed to using a bridge br0 instead of eth0 as the interface.</p>
  
  <p>The reason we have converted to using a bridge interface is to gain access to the MAC SNAT/DNAT capabilities of ebtables.  We have no other reason to add a bridge interface on the servers, as they don't actually bridge connections over multiple interfaces.</p>
  
  <p>I know this is a strange reason to add a bridge on the servers, but we are using the MAC SNAT/DNAT capabilities in a new project and ebtables seemed to be the safest, fastest and easiest way to go since we are already so familiar with iptables.</p>
  
  <p>The problem is, since converting to a br0 interface, iptables PREROUTING forwarding to external servers is no longer working.</p>
  
  <p>Internal PREROUTING forwarding works fine (eg: request comes in on port 80, it forwards to port 8080).</p>
  
  <p>The OUTPUT chain also works (eg: we can connect outwards from the box via a local destination IP:8080, and the OUTPUT chain maps it to the Maintenance Server IP on a different server, port 8080, and returns a webpage).</p>
  
  <p>However, any traffic coming into the box seems to die after the PREROUTING rule if the destination IP is external.</p>
  
  <p>Here is an example of our setup:</p>
  
  <p>Old Setup:</p>
  
  <pre>
  iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
  iptables -a FORWARD --in-interface eth0 -j ACCEPT
  iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE
  echo 1 > /proc/sys/net/ipv4/ip_forward
  </pre>
  
  <p>New Setup: (old setup in various formats tried as well..., trying to log eth0 and br0 packets)</p>
  
  <pre>
  iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
  iptables -a FORWARD --in-interface br0 -j ACCEPT
  iptables -t nat -A POSTROUTING --out-interface br0 -j MASQUERADE
  echo 1 > /proc/sys/net/ipv4/ip_forward
  </pre>
  
  <p>Before changing to br0, the client request would  go to server A at port 9080, and then be MASQUERADED off to a different server $MAINTIP.</p>
  
  <p>As explained above, this works fine if $MAINTIP is on the same machine, but if it's on another server, the packet is never sent to $MAINTIP under the new br0 setup.</p>
  
  <p>We want the packets to go out the same interface they came in on, MASQUERADED, as they did before we switched to using a single-NIC bridge (br0/bridge-utils).</p>
  
  <p>I've tried adding logging at all stages in iptables.  For some reason the iptables TRACE target doesn't work on this setup, so I can't get a TRACE log, but the packet shows up in the PREROUTING table, but seem to be silently dropped after that.</p>
  
  <p>I've gone through this excellent document and have a better understanding of the flow between iptables and ebtables:
  <a href="http://ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html" rel="nofollow">http://ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html</a></p>
  
  <p>From my understanding, it seems that the bridge is not forwarding the packets out the same interface they came in, and is dropping them.  If we had a second interface added, I imagine it would be forwarding them out on that interface (the other side of the bridge) - which is the way bridges are meant to work ;-)</p>
  
  <p>Is it possible to make this work the way we want it to, and PREROUTE/FORWARD those packets out over the same interface they came in on like we used to?</p>
  
  <p>I'm hoping there are some ebtables rules which can work in conjunction with the iptables PREROUTING/FORWARD/POSTROUTING rules to make iptables forwarding work the way it usually does, and to send the routed packets out br0 (eth0) instead of dropping them.</p>
  
  <p>Comments, flames, any and all advice welcome!</p>
  
  <p>Best Regards,
  Neale</p>