The network in quesiton looks basically like this:
/----Inet1
/
H1---[111.0/24]---GW1---[99.0/24]
\----GW2-----Inet2
Device explaination
- H1: Host with IP 192.168.111.47
- GW1: Linux box with IPs 192.168.111.1 and 192.168.99.2, as well as its own route to the internet.
- GW2: Generic wireless router with IP 192.168.99.1 and its own route to the internet.
- Inet1 & Inet2: Two possible routes to the internet
In short: H has more than one possible route to the internet.
H is supposed to only access the internet via GW2 when that link is up, so GW1 has some policy based routing special just for H1:
ip rule add from 192.168.111.47 table 991
ip route add default via 192.168.99.1 table 991
While this works as long as GW2 has a direct link to the internet, the problem occurs when that link is down. What then happens is that GW2 forwards the packet back to GW1, which again forwards back to GW2, creating an endless loop of TCP-pingpong. The preferred result would be that the packet was just dropped.
Is there something that can be done with iptables on GW1 to prevent this? Basically, an iptables-friendly version of "If packet comes from GW2, but originated from H1, drop it"
- Note1: It is preferable not to change anything on GW2.
- Note2: H1 needs to be able to talk to both GW1 and GW2, and vice versa, but only GW2 should lead to the internet
TLDR; H1 should only be allowed internet access via GW2, but still needs to be able to talk to both GW1 and GW2.
EDIT: The interfaces for GW1 are br0.105 for the '99' network, and br0.111 for the '111' network. The sollution may or may not be obnoxiously simple, but i have not been able to produce the proper iptables syntax myself, so help would be most appreciated.
PS: This is a follow-up question from this question
You really should be fixing your routing on
GW2
instead, if by any means possible. If it is not, you can set up a workaround.Let:
Then adding the rule
would result in an ICMP destination unreachable message sent to
<ip-h1>
in the case the packet from<ip-h1>
is ever returned fromGW2
toGW1
. The idea here is to filter by the MAC address since you seem to have several routes to different routers through this interface and you need to differentiate between the originating routers.You can get the MAC address of
GW2
by either looking at its interface configuration, or, if you don't have access to it, by looking at the ARP cache table ofGW1
- just runarp -n
to see current entries in the cache.Note that if
GW1
is doing NAT for traffic leaving through<int2>
then<ip-h1>
would need to be the IP address of<int2>
, not the one ofH1
.As you asked for a way to wildcard the MAC address - there is none, the iptables mac module requires an exact match. But you obviously could script that (quick & dirty, add checks meeting your level of paranoia before putting in production):
Since G1 is a linux box, why not just test G2's external interface with a ping test and change the default route when it isn't responding? And heck, if you do it right you could auto-unfail back up when the pings start working again.