There is a VPS somewhere in the cloud with a public IP address. Also, there is a virtual machine somewhere deep in my garage, connected to the Internet behind NAT.

I have established a permanent OpenVPN link between the two machines. They can talk to each other no problem. The VPS's private IP is, the VM's

Now, I want anyone/anything that attempts to connect to the VPS's public IP (on any port) to be actually connecting to the VM. The only exceptions are ports 22 and 1194 — so that I could still connect to the VPS itself, and so that the VPN link stays up.

That said, the VPS's iptables, routes or whatever needs to be configured to forward all incoming connections (except for the 2 specified ports) to

How can that be done?

Use case: expose a WebRTC streaming server running on the VM. There is a shitload of various ports and protocols that need to be exposed, so forwarding them individually is impracticable. It is expected that WebRTC, upon clients connecting to the public IP, will bootstrap/establish direct P2P connections to the VM drilling through the NAT as it is designed to do.

  • link is thhis what you looking for ?
    – Vaibhav.c
    Mar 6, 2022 at 12:50
  • @Vaibhav.c That looks pretty close at first glance, thanks. However, it does not show how to include any exceptions (e.g. ports 22, 1194).
    – Greendrake
    Mar 6, 2022 at 13:28
  • 1
    One workaround you can try is to add two rules with --dport=22 and --dport=1194 which forward to same destination IP and 3rd rule with all the ports to forward to your vm. So when something hits on port 22 or 1194 it will forward to same machine else it will go to 3rd rule and forward it to vm.
    – Vaibhav.c
    Mar 6, 2022 at 13:36
  • There are even ways without NAT to really give the public IP to the VM (eg: superuser.com/questions/1608801/… 's answer, but there's an intermediate system there to help the setup which isn't present here).
    – A.B
    Mar 6, 2022 at 18:18
  • 1
    @A.B Yes I get that. What I'm saying is that I didn't know of such a great alternative to OpenVPN as WireGuard. I'm gonna use it (irrespectively of this question).
    – Greendrake
    Mar 7, 2022 at 14:05

1 Answer 1


To exclude some ports you can have rules matching them but doing "nothing" to stop further processing:

iptables -t nat -A PREROUTING -p TCP --dport 22 -j ACCEPT
iptables -t nat -A PREROUTING -p UDP --dport 1194 -j ACCEPT

And then do the actual forwarding and set the "returnpath":

iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination
iptables -t nat -A POSTROUTING -d -j MASQUERADE
  • The MASQUERADE part is unnecessary if the VM uses redirect-gateway or equivalent.
    – Tom Yan
    Mar 6, 2022 at 20:36
  • And in addition the masquerade part would probably be harmful to any tool like a WebRTC server since all clients would be seen with the same IP address.
    – A.B
    Mar 7, 2022 at 9:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .