During the covid-19 pandemic, most people work from home and VPN is a common approach to access insecure private network servers like an HTTP server without access authentication. Most modem servers have security control and can be moved to the internet for direct access by assigning a public IP address and a domain name, such as JIRA and Confluence servers. So there should be a very limited number of legacy servers that are kept in the private network and are protected by VPN, i.e. only accessible from the private network. In this post, I will explain how you can access private servers directly in a secure way using double SSH tunnels (Local + Remote) as an alternative to VPN.
Imagine you have a corporate private network in 10.0.0.x, and you have a PC in the office (10.0.0.11) or any device that can run as an SSH client. You can use the office PC to create an SSH tunnel to a public Linux server (accessible on the internet) as a bridge to access other servers or devices in the office private network, such as an HTTP server (10.0.0.12).
The first step is to create a remote tunnel from the office PC 10.0.0.11 to the public server, e.g. yourserver.com. Assume you access the public server with an SSH key (sshkey.pem).
Run this command on your office PC if it is a Linux:
ssh -R 9000:10.0.0.12:80 -i sshkey.pem -f -N <username>@yourserver.com
-R 9000:10.0.0.12:80This creates a remote tunnel and the public server is listening on port 9000. When you access the port 9000 on the public server, it is redirected to the private server 10.0.0.12 on port 80 (HTTP) via office PC 10.0.0.11. Note that for security reasons the port 9000 is listening only on localhost 127.0.0.1, not all IP addresses 0.0.0.0 on the server. Run
netstat -anp|grep 9000on the public server and you will see that as follows.
-f -NThis is optional. “The
-foption tells the
sshcommand to run in the background and
-Nnot to execute a remote command.”
Now if you SSH into your public server, you can access the private HTTP server
10.0.0.12:80 with local port 9000. Test with
curl 127.0.0.1:9000 or
wget 127.0.0.1:9000and you should get the home page of
If your private office PC is a Windows, install putty and open an ssh session to your public server with the below tunnel settings.
The second step is to create a local tunnel from your home PC 192.168.0.11 to the public server (yourserver.com) so that you can access the private HTTP server
10.0.0.12:80 directly from your home PC, using the public server as a bridge.
Run this command on your home PC if it is a Linux:
ssh -L 9000:127.0.0.1:9000 -i sshkey.pem -f -N email@example.com
-L 9000:127.0.0.1:9000This creates a local tunnel and your home PC is listening on port 9000. When you access the port 9000 on your home PC, it is redirected to the public server local port
127.0.0.1:9000, then to the the private server
10.0.0.12:80via the remote tunnel created above. That’s the magic 😉
netstat -an|grep 9000on your home PC and you will see it listens on port 9000 as follows.
Now open a web browser from your home PC and enter http://127.0.0.1:9000, and you will see the magic that it shows the home page of the private HTTP server (http://10.0.0.12) directly.
Note that the same approach works with a private FTP server, ssh server, etc., just change the destination port in the remote tunnel.
If your home PC is a Windows, install putty and open an ssh session to your public server with the below tunnel settings.
If it feels too technical for you to set up or you simply don’t have any Linux public server, I would recommend using Google Remote Desktop https://remotedesktop.google.com to access your office PC without VPN. Just visit that URL in the Chrome browser in both your office PC and home PC to set it up. And it will start the service on system bootup, so no worries about system auto reboot.