5G is Fast but There’s No Public IP

I’m super happy that I can finally have a broadband that does have a broad bandwidth. However like all other cellular services the 5G gateway has a private IP as its external IP, ie. everything I got is behind huge NAT servers of Optus and they will not open any port just for me.

The NBN wasn’t as fast but there was a public IP assigned to the router… Should I go back to use NBN because of this reason? I’ve done countless internet/cloud solutions, can I do one for myself? I remember when I worked on a private network behind NAT gateways I could do SSH tunneling and expose a port in the private network to outside for 3rd party partners. All I need is a virtual machine in the cloud that has a public IP. It will look like this:

        [CloudFlare] 
             |
            HTTP
             |
     [VM:35.197.x.x:80]
             |
       [SSH Tunnel]
             |
[local server:192.168.1.x:80]

I need to create a SSH tunneling service between my home server and the cloud instance, then point CloudFlare DNS to the public IP of the cloud instance, that’s it! But hang on, I can’t bind to port 80 using a non-privileged user. So there’s a local port forwarding in the cloud instance to handle this:

        [CloudFlare] 
             |
            HTTP
             |
     [VM:35.197.x.x:80]
             |
         [VM:nginx]
             |
    [VM:127.0.0.1:8080]
             |
        [SSH Tunnel]
             |
[local server:192.168.1.x:80]

Ok let’s do it. First I created a cloud instance in Google Cloud, because it gave me $400 free credit last year and I haven’t used much yet. I opened port 80 for the instance, added my SSH public key and installed an nginx server forwarding traffic from port 80 to local port 8080. Here’s the simple nginx configuration:

# This file can be saved as /etc/nginx/site-enabled/proxy
# in the cloud instance
server{
        listen 80;
        server_name raynix.info;
	client_max_body_size 100M;

        location / {
		proxy_pass http://localhost:8080;
		proxy_set_header Host              $host;
		proxy_set_header X-Real-IP         $remote_addr;
		proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto https;
		proxy_set_header X-Forwarded-Host  $host;
		proxy_set_header X-Forwarded-Port  $server_port;
        }
}

Don’t forget to reload nginx. Done! The next step is to create an SSH tunneling service in my home server. My home server is running Ubuntu so the service is defined with systemd syntax:

# The file can be saved as /etc/systemd/system/mytunnel.service
# in my home server
# replace the id_rsa with yours of course
[Unit]
Description=Setup a secure tunnel to kite server
After=network.target

[Service]
ExecStart=/usr/bin/ssh -NT -i /home/ray/.ssh/id_rsa -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R 8080:localhost:80 [email protected]

# Restart every >2 seconds to avoid StartLimitInterval failure
RestartSec=5
Restart=always

[Install]
WantedBy=multi-user.target

Then use the following commands to start and check the service:

$ systemctl daemon-reload
$ systemctl start mytunnel
$ systemctl status -l mytunnel

The status of the tunnel can also be verified in the cloud instance by:

$ sudo netstat -tlnp
...
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      1460/sshd: ray      

By now all the dots have been connected. I can test the round trip on my laptop with:

$ curl http://35.197.x.x -H 'Host: raynix.info'
# this should print out the HTML of my blog's homepage.

The last step is to update CloudFlare DNS to send traffic to the new cloud instance. Did it work? You’re looking at the result right now 🙂

2 Replies to “5G is Fast but There’s No Public IP”

Leave a Reply

Your email address will not be published. Required fields are marked *