iptables port forwarding A -> B -> A
I have a host machine(A
) with lxc-container(B
).
A
's local ip address is 10.0.3.1 and public ip, let's say 1.2.3.4.
B
's local ip address is 10.0.3.21.
I need 1.2.3.4:7999 to be forwarded to 10.0.3.1:7999 and I created the following rules for that:
iptables -t nat -I PREROUTING -p tcp -d 1.2.3.4 --dport 7999 -j DNAT --to 10.0.3.21:7999
iptables -A FORWARD -p tcp -d 10.0.3.21 --dport 7999 -j ACCEPT
When I connect to the A
(1.2.3.4:7999) from the outside world I am connecting successfully.
But I am falling when I try to connect to B
from A
(connection timed out).
What rules should I create to be able to connect to 1.2.3.4:7999 from 10.0.3.1?
You have a NAT hairpin situation here, which your current iptables rules don't support. When the container sends the request out the packet looks like this:
10.0.3.21:12345 -> 1.2.3.4:7999
The gateway then DNATs the packet to this, and sends it back to the container:
10.0.3.21:12345 -> 10.0.3.21:7999
The container receives the packets and sends a response which looks like this:
10.0.3.21:7999 -> 10.0.3.21:12345
i.e. it's directly addresses to the container itself. But port 12345 doesn't know about a connection with 10.0.3.21:7999, because the connection was with 1.2.3.4:7999, and so the response is ignored.
The solution is to also SNAT the packet on the gateway so that the response goes back to the gateway, which then undoes both NATs. Try adding something like this:
iptables -t NAT -A POSTROUTING -o lxcbr0 -d 10.0.3.21 -s 10.0.3.21 -j SNAT --to 10.0.3.1