0

I'm forwarding a port from my HOST (192.168.1.4@MY_LAN) to my virtual machine (10.0.10.5@HOST) with the following iptables rule:

HOST:~$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 10.0.10.5:80

If I make a request to 192.168.1.4:80 inside MY_LAN, I get the correct response.

However, port 80 isn't being listened on the HOST:

HOST:~$ netstat -anp | grep 80 | grep -w LISTEN
# nothing shown here 

...so I can not connect to HOST:80 within my VPN_SERVER when I connect my HOST to VPN:

VPN_SERVER:~$ curl http://192.168.30.11:80
curl: (7) Failed to connect to 192.168.30.11 port 80: Connection refused

If I forward the connection with socat, everything works correctly (based on this post):

HOST:~$ sudo socat TCP-LISTEN:80,su=nobody,fork,reuseaddr TCP-CONNECT:10.0.10.5:80
VPN_SERVER:~$ curl http://192.168.30.11:80
<html>
<head><title>Hello world!</title></head>
<body>
</body>
</html>

Question

How can I get rid of this socat workaround and make this type of connection possible by using only iptables?

ceremcem
  • 208
  • 1
  • 10

2 Answers2

1

There are two things:

  1. Port forwarding works without listen sockets, it just rewrites destination address and/or port. So empty listen sockets list for your forwarded port number is a normal situation.
  2. Local originated packets (from HOST itself) don't pass the POSTROUTING chain. You should add another one DNAT rule under the nat/OUTPUT chain:
iptables -t nat -A OUTPUT \
         -d 192.168.30.11 \
         -p tcp --dport 80 \
    -j DNAT --to 10.0.10.5:80
Anton Danilov
  • 4,874
  • 2
  • 11
  • 20
  • We also need [`sysctl -w net.ipv4.conf.all.route_localnet=1`](https://serverfault.com/a/856121/261445) for `localhost:PORT` syntax to work. – ceremcem Dec 27 '19 at 21:55
0

I thing it is a routing problem

Try add masquerade rule. Somtething like this:

iptables -t nat -A POSTROUTING -p tcp --dport 80 -d 10.10.10.5 -j MASQUERADE