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
    • VPN Method 1: Proxy on Apache 2 webserver
    • VPN Method 2: Port forward on the VPS

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


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:

$ vi /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



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
Hi there
Forwarding TCP connections from
Press g to start a GUI session and ctrl-c to quit.
TCP connection from on port 18080
TCP connection from on port 18080


Login on the dashboard and download the binary here:

Unzip the zipfile on your local machine:

$ unzip /path/to/

Authenticate ngrok once, you can get the command here 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       
Forwarding           -> http://localhost:8080
Forwarding           -> 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: //

Configuration 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

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

# Allow client to client communication
# Send pings to keep connection alive
keepalive 15 60
# 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

VPN Method 1: Proxy on Apache 2 webserver

Advantage of this method is that you can use the Let’s Encrypt certificate of you webserver. On your lokal network you don’t need to have encryption, http is in most cases secure enough. When the Let’s Encrypt certificates are updated on your webserver, they also are updated for this proxy.

$ vi /etc/apache2/sites-available/application_example.conf
<IfModule mod_ssl.c>
        Listen 18080
        <VirtualHost *:18080>
                ProxyPreserveHost On
                ProxyRequests Off
                SSLProxyEngine On

                ProxyPass "/" ""
                ProxyPassReverse "/" ""
                RewriteEngine on
                RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
                RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
                RewriteRule .* ws://{REQUEST_URI} [P]
                SSLEngine on

                SSLCertificateFile /etc/letsencrypt/live/
                SSLCertificateKeyFile /etc/letsencrypt/live/
                SSLCertificateChainFile /etc/letsencrypt/live/

                ErrorLog ${APACHE_LOG_DIR}/error_home_assistant.log
                CustomLog ${APACHE_LOG_DIR}/access_home_assistant.log combined

And activate the configuration:

$ cd /etc/apache2/sites-enabled/
$ ln -s ../sites-available/application_example.conf
$ systemctl restart apache2.service

VPN Method 2: Port forward on the VPS

In this example the local machine has IP nr:

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