When filtering on a bridge i think you need to use a different match for the interface in/out,
in your case, in i understand your setup correctly, something like
iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080
iptables -a FORWARD -m physdev --physdev-in eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -m physdev --physdev-out eth0 -j MASQUERADE
I don't think you need to enable ip_forward ... this is a bridge afterall
last but not least
echo 1 > net.bridge.bridge-nf-call-iptables
make sure this is enabled , but it should by default.
Reasons for observed behviour
The reason that iptables doesn't get the physical bridge information when the packet arrives from a non-bridged interface is that the packet has never been near the bridging mechanism, even though at this point we know we are sending it out on the bridge.
In the case where the packet did arrive over a bridge port, but it is an N>2 bridge, the problem is that the iptables PHYSDEV extention only provides for their being one value for "out", so it just doesn't bother telling us if there are two.
Solution
Use ebtables instead of iptables. The ebtables OUTPUT
chain will know which physical bridged interface it is sending packets out on.
In the scenario above, where you want to filter packets that are leaving via a specific bridged interface (eth0
), regardless of how it arrived into the system, add an ebtables rule along the following lines:
-A OUTPUT -o eth0 -j <target>
In a more complex scenario, where you want to filter packets arriving from a specific interface, and leaving via a bridged interface, it gets harder. Say we want to drop all traffic from eth2
(non-bridged) going to eth0
(bridged as part of br0
) we need to add this rule to iptables:
-A FORWARD -i eth2 -o br0 -j MARK --set-mark 1234
This will mark any packet that comes from eth2
and is bound for the bridge. Then we add this rule to ebtables:
-A OUTPUT -physdev-out eth0 --m mark --mark 1234 -j DROP
Which will DROP
any packet marked by iptables (as being from eth2
) that is egressing via the specific bridge port eth0
.
Acknowledgements
Thanks goes out to Pascal Hambourg over at the netfilter iptables mailing list for his help in coming up with this solution.
Best Answer
Unfortunately
nftables
have no implemented syntax for source and destination ipv4 address in arp tables right now.Empirically I found out that the next expressions can be used instead:
plen 4 @nh,64,32
(source ip)plen 4 @nh,96,32
(destination ip)IPv4 address in value should be specified in decimal
integer
type.You can use some online converter for get your IP-address to numeric format.
In your example
192.168.178.237
will be3232281325
So final rule will looks like:
PS: You can use
xtables-nft-multi
from the last iptables package which providesnf_tables
compat backend for import your old commands and check the new syntax.