Let’s say that you want to access your home surveillance cameras from anywhere, if you have a public IPv4 address from ISP its as simple as forwarding a port on the router.
However, Carrier Grade NAT makes this complicated. You cannot just forward a port and make web servers accessible from your public IP if you are on a Carrier Grade NAT. ISPs may also charge a ton of money for public IP or straight up refuse to provide one.
In this tutorial I will show you how to very easily relay your web server through a VPS.
Here is a diagram to see the workings:
Hardware you will need:
You can install ZeroTier pretty easy with:
curl -s https://install.zerotier.com | sudo bash
This works on most Linux distros including Debian, Ubuntu, CentOS, RHEL, Fedora etc.
You will need to create the ZeroTier network on my.zerotier.com/network . Register an account if you don’t have one and create a network.
Once you have a network, set it to Public from Private and note down its Network ID.
Next, let’s connect both devices to the network we just created. To do this enter the following command on both the machines:
sudo zerotier-cli join <network_id>
Replace <network_id> with your network ID.
You should see both the devices on: my.zerotier.com/network/<network_id> under Members section. Note down the IP Address of both the devices. For me, local server is on: 10.147.19.37 and VPS is on: 10.147.19.235
Now that both devices are on ZT, you can set Access Control to Private on same page.
You will need to install socat on both the systems. Socat is a simple program for forwarding ports across IPs.
On Ubuntu/Debian this is as simple as:
sudo apt install socat
The commands should be similar for other distros as well as Socat is in the package list of most distros.
Now that socat is installed you need to forward the ports on both your systems
My web server is located on 192.168.5.250 on port 80 inside my LAN. Hence we will run the following command on local machine:
socat TCP-LISTEN:45114,fork TCP:192.168.5.250:80
You can replace the 45114 with any high port that won’t be used.
Now, our web server is accessible on our local server at both 192.168.5.240:45114 (which is our LAN) and 10.147.19.37:45114 (ZeroTier IP of local machine).
Now that we have our web server accessible from ZeroTier network. We can forward the port 45114 of our local machine to the internet. To do this we will run the following command:
sudo socat TCP-LISTEN:80,fork TCP:10.147.19.37:45114
Note that in some distros, listening on low ports (such as 80 or 443) needs sudo privileges. You can change TCP-LISTEN to something high like 42142 to not require sudo.
Here 10.147.19.37 is the ZeroTier IP of your local machine and we are making socat listen on Port 80 which is standard port of http. You don’t have to make it listen on port 80, you can use any port you want if you are running something like NVR for better security.
On running this we should be able to access the web server from public IP of VPS with whatever port we made it in listen earlier.
The problem with running socat like we did earlier is that, we have to keep the SSH/Shell open otherwise socat will stop. In order to prevent this we will setup a service.
We will setup a service on both our systems:
Find the path of your socat binary using:
which socat
In my case it’s /usr/bin/socat
Enter following command:
sudo nano /etc/systemd/system/socat.service
Type in the following into nano:
[Unit]
Description=Socat Proxy
[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:45114,fork TCP:192.168.5.250:80
[Install]
WantedBy=multi-user.target
Change /usr/bin/socat to whatever your socat binary path is in your system
Change 192.168.5.250:80 to address of your web server
Press Ctrl+O and Enter to save the file and Ctrl+X to exit from Nano
Type in sudo systemctl daemon-reload to reload systemd
Type in sudo systemctl start socat to start socat service
Do the same thing to find path of socat binary
Type in:
sudo nano /etc/systemd/system/socat.service
Type in following to nano:
[Unit]
Description=Socat Proxy
[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:42142,fork TCP:10.147.19.37:45114
[Install]
WantedBy=multi-user.target
Change 42142 to whatever port you want your webserver accessible from WAN. Also change 10.147.19.37 to your local machine’s ZeroTier IP
Press Ctrl+O and Enter to save the file and Ctrl+X to exit from Nano
Type in sudo systemctl daemon-reload to reload systemd
Type in sudo systemctl start socat to start socat service
That’s it you should be able to access your webserver/NVR from anywhere on the public IP of VPS with the you set as TCP-LISTEN on the VPS’s service file. In my case its http://25.21.214.2:42142
To make it start on reboot enter:
sudo systemctl daemon-reload
sudo systemctl enable socat
on both the systems
However, Carrier Grade NAT makes this complicated. You cannot just forward a port and make web servers accessible from your public IP if you are on a Carrier Grade NAT. ISPs may also charge a ton of money for public IP or straight up refuse to provide one.
In this tutorial I will show you how to very easily relay your web server through a VPS.
Here is a diagram to see the workings:
Hardware you will need:
- A Linux machine within your LAN: This is what we will be using to connect to ZeroTier network. You can use something simple like a Raspberry Pi. In my case I will be using my home server running Ubuntu 20.04.
- Any Linux VPS with a public IP: You will need a VPS with a public IP running Linux. This is what we will be using to access our local NVR from WAN.
- Socat Proxy: Socat will be used to forward port from LAN to our ZeroTier network. This way we won’t have to bridge the networks.
- ZeroTier: ZeroTier can punch through CGN to make direct connection between our VPS and Home Server. This is what allows us to port forward using Socat.
Step 1: Install ZeroTier on both the systems
You can install ZeroTier pretty easy with:
curl -s https://install.zerotier.com | sudo bash
This works on most Linux distros including Debian, Ubuntu, CentOS, RHEL, Fedora etc.
Step 2: Create a network on my.zerotier.com
You will need to create the ZeroTier network on my.zerotier.com/network . Register an account if you don’t have one and create a network.
Once you have a network, set it to Public from Private and note down its Network ID.
Step 3: Connect both devices to ZeroTier.
Next, let’s connect both devices to the network we just created. To do this enter the following command on both the machines:
sudo zerotier-cli join <network_id>
Replace <network_id> with your network ID.
You should see both the devices on: my.zerotier.com/network/<network_id> under Members section. Note down the IP Address of both the devices. For me, local server is on: 10.147.19.37 and VPS is on: 10.147.19.235
Now that both devices are on ZT, you can set Access Control to Private on same page.
Step 4: Socat
You will need to install socat on both the systems. Socat is a simple program for forwarding ports across IPs.
On Ubuntu/Debian this is as simple as:
sudo apt install socat
The commands should be similar for other distros as well as Socat is in the package list of most distros.
Now that socat is installed you need to forward the ports on both your systems
Step 5: Forwarding ports using Socat
My web server is located on 192.168.5.250 on port 80 inside my LAN. Hence we will run the following command on local machine:
socat TCP-LISTEN:45114,fork TCP:192.168.5.250:80
You can replace the 45114 with any high port that won’t be used.
Now, our web server is accessible on our local server at both 192.168.5.240:45114 (which is our LAN) and 10.147.19.37:45114 (ZeroTier IP of local machine).
Step 5: Forwarding the port to WAN
Now that we have our web server accessible from ZeroTier network. We can forward the port 45114 of our local machine to the internet. To do this we will run the following command:
sudo socat TCP-LISTEN:80,fork TCP:10.147.19.37:45114
Note that in some distros, listening on low ports (such as 80 or 443) needs sudo privileges. You can change TCP-LISTEN to something high like 42142 to not require sudo.
Here 10.147.19.37 is the ZeroTier IP of your local machine and we are making socat listen on Port 80 which is standard port of http. You don’t have to make it listen on port 80, you can use any port you want if you are running something like NVR for better security.
On running this we should be able to access the web server from public IP of VPS with whatever port we made it in listen earlier.
Step 6: socat start on boot
The problem with running socat like we did earlier is that, we have to keep the SSH/Shell open otherwise socat will stop. In order to prevent this we will setup a service.
We will setup a service on both our systems:
On our home server:
Find the path of your socat binary using:
which socat
In my case it’s /usr/bin/socat
Enter following command:
sudo nano /etc/systemd/system/socat.service
Type in the following into nano:
[Unit]
Description=Socat Proxy
[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:45114,fork TCP:192.168.5.250:80
[Install]
WantedBy=multi-user.target
Change /usr/bin/socat to whatever your socat binary path is in your system
Change 192.168.5.250:80 to address of your web server
Press Ctrl+O and Enter to save the file and Ctrl+X to exit from Nano
Type in sudo systemctl daemon-reload to reload systemd
Type in sudo systemctl start socat to start socat service
On the VPS:
Do the same thing to find path of socat binary
Type in:
sudo nano /etc/systemd/system/socat.service
Type in following to nano:
[Unit]
Description=Socat Proxy
[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:42142,fork TCP:10.147.19.37:45114
[Install]
WantedBy=multi-user.target
Change 42142 to whatever port you want your webserver accessible from WAN. Also change 10.147.19.37 to your local machine’s ZeroTier IP
Press Ctrl+O and Enter to save the file and Ctrl+X to exit from Nano
Type in sudo systemctl daemon-reload to reload systemd
Type in sudo systemctl start socat to start socat service
That’s it you should be able to access your webserver/NVR from anywhere on the public IP of VPS with the you set as TCP-LISTEN on the VPS’s service file. In my case its http://25.21.214.2:42142
To make it start on reboot enter:
sudo systemctl daemon-reload
sudo systemctl enable socat
on both the systems