I don't know if it is a bug or an intentional fallback behavior, but from I what can see here, it has neither anything to do with the wlan0
local route you mentioned, or all the default gateway blah blah (no offense but it almost makes no sense to me) stated in the other/"correct" answer.
Normally how MASQUERADE
works is, it picks the address that is configured on the outbound interface (which is determined by routing, hence POSTROUTING
) for the source NAT that it performs. (If multiple addresses are assigned on the interface, it will probably pick the first one or the one that is set as the preferred source address in the corresponding route; I'm not that familiar with it and that is out-of-scope here anyway). It has nothing to do with the nexthop / gateway address of the default route. (That's not how source NAT works anyway.)
However, when it comes to the interface lo
, things seems to become a bit tricky. More precisely, it does not seem to have something to do with the interface itself (apart from the fact that it will be the outbound interface because the destination is a local address), but rather the fact that, addresses in the 127.0.0.0/8
block is not of scope global
. While I have no idea what is happening behind the scene, it seems that the traffic cannot "show up" if the host has no scope global
IP address configured but attempt to MASQUERADE
.
What I can see here is, even if you just configure an address that is valid for scope global
(e.g. 192.168.0.10/32
) on any interface (including lo
), you'll see it works again. (The local route you mentioned will be added automatically. But I'm not seeing that adding only the route works here.)
For what it's worth, addresses and interfaces are not heavily bound together in Linux (not in a straight-forward way like, it will reply to traffics only if their destination address matches with the configured address on the inbound interface, even when IP forwarding is not of concern). So it might has something to do with that: in case MASQUERADE
cannot pick a scope global
address from what are configured on the outbound interface, it just pick one from any (I doubt that the precedence has something to do with default route though), if still no, it just refuse to work in some way.
In case you really need a rule that enables MASQUERADE
on all interfaces but lo
, you can have:
iptables -t nat -A POSTROUTING ! -o lo -j MASQUERADE