This is what happens:
- Your
192.168.33.35
server sees the Syn packet from 192.168.33.Z
(it's unaware of 192.168.31.0/24
network and sees the "WAN" address of the 192.168.31.1
gateway, I don't know what Z
is) and replies to this address.
- Its routing table says this address belongs to local network, so the response is destined to MAC address of
192.168.33.Z
.
- Even if the response physically travels through the
192.168.33.1
machine, the gateway doesn't mangle with it because it is destined to MAC address of another machine.
192.168.33.Z
sees the response from 192.168.33.35
. It expects one from 66.66.66.66
and doesn't know what to do.
Note it doesn't matter 192.168.33.Z
performs NAT (being 192.168.31.1
on its LAN side). The mechanism of failure is very similar to the one where NAT loopback (hairpin NAT) is only partially set up.
You have to make your 192.168.33.35
server send responses to the MAC address of your 192.168.33.1
gateway.
Either set a routing rule for 192.168.33.Z
(remember I don't know Z
, you do; substitute the real number) or even for entire 192.168.33.0/24
network:
# do this on the 192.168.33.35 machine
route add -host 192.168.33.Z gw 192.168.33.1
Note it will affect all communication from 192.168.33.35
to 192.168.33.Z
. In cases when 192.168.33.35
should act as 192.168.33.35
packets will be unnecessarily routed; it shouldn't break things though.
Or let the 192.168.33.1
gateway perform not only DNAT but SNAT as well. This solution is basically the same as the one for NAT loopback in the already linked answer:
# do this on the 192.168.33.1 gateway
# you already have this line
iptables -t nat -I PREROUTING -d 66.66.66.66 -j DNAT --to-destination 192.168.33.35
# this line is new
iptables -t nat -I POSTROUTING -d 192.168.33.35 -j SNAT --to-source 192.168.33.1
This fragment applies to your situation:
Note that the NAT table in iptables
is only used for the first packet of a connection. Later packets related to the connection are processed using the internal mapping tables established when the first packet was translated.
This means the second of your lines (iptables … -j SNAT --to-source 66.66.66.66
) is irrelevant when you initiate a connection from a client. Later packets will be SNAT-ed and DNAT-ed properly because the first packet was.
I think if your first line
iptables -t nat -I PREROUTING -d 66.66.66.66 -j DNAT --to-destination 192.168.33.35
acted on the 192.168.31.1
gateway, it would do what you want for other clients from 192.168.31.0/24
without any additional tricks.
This second line of yours
iptables -t nat -I POSTROUTING -s 192.168.33.35 -j SNAT --to-source 66.66.66.66
will apply if you initiate a connection from 192.168.33.35
. Internet servers rarely do this, so you may not need this rule at all. In case you do need it, remember that:
- the rule will only work if packets are routed through the
192.168.33.1
gateway where this rule acts, so to reach your local computers and to present to them as 66.66.66.66
you need to adjust the routing table on the 192.168.33.35
machine similarly as above;
- you cannot communicate as
66.66.66.66
with external hosts (beyond your network) because even if you managed to reach them acting as 66.66.66.66
, their response would get to the real 66.66.66.66
, not back to you.