SSH logo
SSH logo

Port forwarding behind NAT or CGNAT

There several ways to port forward to expose your local port to the internet. These instructions are working for normal NAT routers and also for Carrier Grade NAT (CGNAT). CGNAT is often used by LTE/4G internet connections. Described port forward methods are:

  • Via SSH on your own webserver/VPS
  • Via ngrok
  • Via Serveo
  • Via OpenVPN server on your webserver/VPS

In the described examples are we going to forward local port 8080 and expose it on internet with port 18080.

Info:

Port forward via OpenSSH on your VPS

To enable port tunneling via SSH on your webserver/VPS, the option GatewayPorts needs to be set on yes. Check this with the following command:

$ sshd -T|grep -i gatewayports
gatewayports yes

If there is a no, change the /etc/ssh/sshd_config:

GatewayPorts yes

Then restart the SSH service on your VPS:

$ systemctl restart ssh

Now it’s possible to port forward from every Linux machine, with for example this command. Run this on the local machine.

$ ssh -l root -R :18080:localhost:8080 my-vps.com

Serveo

Info: https://serveo.net/

In case you don’t have or don’t want to use your own webserver/VPS, it’s possible to use Serveo. It works a bit like on your own VPS. You don’t have to install or configure anything. You also don’t need any account. Clever!

$ ssh -R 18080:localhost:8080 serveo.net
Hi there
Forwarding TCP connections from serveo.net:18080
Press g to start a GUI session and ctrl-c to quit.
TCP connection from 37.188.243.191 on port 18080
TCP connection from 37.188.243.191 on port 18080

And in this case you can reach your local server on this URL: https: //e9d4ff45.ngrok.io

ngrok

Login on the dashboard and download the binary here: https://dashboard.ngrok.com/get-started

Unzip the zipfile on your local machine:

$ unzip /path/to/ngrok.zip

Authenticate ngrok once, you can get the command here https://dashboard.ngrok.com/auth. This will look like this:

$ ./ngrok authtoken 3e5iY2KftJ2844aWA6jDY_9fJFZAc1Hhq5bJ4eD1myV
Authtoken saved to configuration file: /home/arjan/.ngrok2/ngrok.yml

Now it’s possible to start the port forward:

$ ./ngrok http 8080
ngrok by @inconshreveable                                                                           (Ctrl+C to quit)

Session Status                online
Account                       Arjan Wooning (Plan: Free)
Version                       2.3.25
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://e9d4ff45.ngrok.io -> http://localhost:8080
Forwarding                    https://e9d4ff45.ngrok.io -> http://localhost:8080

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

And in this case you can reach your local server on this URL: https://e9d4ff45.ngrok.io

Port forward via OpenVPN on your webserver/VPS

If you have already an OpenVPN server running on your VPS, it’s also possible to port forward via the OpenVPN connection. I don’t describe how to setup the complete OpenVPN server, only what to change to port forward. The local machine needs to have a VPN connection to the VPS.

Configuratin instructions for the OpenVPN server

Activate packet forwarding

On Linux you need to activate IP forward:

$ echo 1 > /proc/sys/net/ipv4/ip_forward

$ vi /etc/sysctl.conf
net.ipv4.ip_forward=1

Add/replace the following VPN settings in server.conf:

# Allow client to client communication
client-to-client
# Send pings to keep connection alive
keepalive 15 60
ping-timer-rem
# Persistent ip addresses
ifconfig-pool-persist /etc/openvpn/ipp

# Enable ip forward on the running system (temporary)
sysctl -w net.ipv4.ip_forward=1

Restart the OpenVPN server:

$ service openvpn start

Poorten forward on the VPS

In this example the local machine has IP nr: 192.168.1.5

$ vi /etc/rc.local
## Port forward: 18080 <-> 8080
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 18080 -j DNAT --to-destination 192.168.1.5:8080
iptables -t nat -A POSTROUTING -d 192.168.1.5/32 -p tcp -m tcp --dport 8080 -j MASQUERADE