Port forwarding behind NAT (Using WireGuard and Nginx Reverse Proxy) - Restored Version

things from boards above, but in an international language
Post Reply
User avatar
samo Offline
Posts: 6
Joined: Sun Jul 21, 2024 10:15 pm
Description: ja som samo (pochopitelne).
Contact:

Port forwarding behind NAT (Using WireGuard and Nginx Reverse Proxy) - Restored Version

Post by samo »

This is recovered from old files, pictures will be added later.

Today going to show you how can you port forward if you are behind NAT (or CG-NAT). In some cases, when you want to host some game server or website, you might need to open ports. That might be a problem if you are using mobile network (4G LTE, 5G,…). Typically, the ISP doesn’t allow port forwarding (you might try to ask them if they have public IPv4 or IPv6, but that is outside the scope of this post), so you are going to need other means of port forwarding. In this case, we are going with a private VPN route.
I am taking inspiration from this video and from the people of 370.network :krava:

You will need:

- VPS with public IPv4 address (you can get one for free from Oracle Free Tier) running Linux
- Bit of Linux know how
- Lot of patience
WireGuard and Nginx

In this chapter we will install and configure WireGuard and Nginx reverse proxy.

Update packages on the VPS:

Code: Select all

root@server:~# apt update && apt upgrade -y
Install WireGuard and Nginx:

Code: Select all

root@server:~# apt install wireguard nginx -y
Then do:

Code: Select all

root@server:~# (umask 077 && printf "[Interface]\nPrivateKey= " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
The command is used to create and write to the WireGuard configuration file (/etc/wireguard/wg0.conf) with correct permissions.
  • umask 077: Sets the file creation mask to 077, which means new files will have permissions 700 (read, write, and execute for the owner only, no permissions for group and others).
  • printf "[Interface]\nPrivateKey= ": Prints the initial contents of the configuration file, which includes the [Interface] section and a placeholder for the private key.
  • | sudo tee /etc/wireguard/wg0.conf > /dev/null: Uses sudo to write the printed content to the configuration file as a superuser. The tee command writes to both standard output and the specified file, but > /dev/null discards the standard output, so the content only goes into the file.
Next run this command. It will generate a key that you need to write down somewhere:

Code: Select all

root@server:~# wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
Then we are going to edit WireGuard’s config file:

Code: Select all

root@server:~# nano /etc/wireguard/wg0.conf
Append after “PrivateKey” this:

Code: Select all

ListenPort = 55100
Address = 192.168.33.1
Now install WireGuard on your local machine (Windows or Linux). I will show you both. We will set port forwarding later.
Windows
  • Click on “Windows Installer”
  • Run the setup and install WireGuard

Open WireGuard and click the little triangle besides “Add Tunnel” and click “Add empty tunnel”

Now there are few things we need to do:

Note down the “Public Key” of the tunnel (same as we did earlier in the VPS)

Now name the tunnel (name doesn’t matter). Copy and edit the following config:

Code: Select all

[Interface]
PrivateKey = <private key of your tunnel (auto-generated don't touch this!)>
Address = 192.168.33.2/32

[Peer]
PublicKey = <Public key from VPS>
AllowedIPs = 192.168.33.1/32
Endpoint = <IP Address of the VPS>:55100
PersistentKeepalive = 25
Now we are going to add our tunnel to our WireGuard config on our VPS:

Code: Select all

root@server:~# nano /etc/wireguard/wg0.conf
Now on a new line copy following

Code: Select all

[Peer]
PublicKey = <Public key from Windows PC>
AllowedIPs = 192.168.33.2/32
We can now start the WireGuard server:

Code: Select all

root@server:~# systemctl enable --now wg-quick@wg0 
Now check if the server is running:

Code: Select all

root@server:~# ip a
Find “wg0” and check if it looks like this

Code: Select all

X: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8920 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 192.168.33.1/32 scope global wg0
       valid_lft forever preferred_lft forever
Now we need to allow traffic via “iptables”. Because this is test / debug system or private system we can allow everything trough firewall. I DO NOT recommend doing this on production systems. If you want to enhance security port forward only required ports. This is for demonstration only, and I hold no liability for any compromised systems.

Code: Select all

iptables -P OUTPUT ACCEPT
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
  • iptables -P OUTPUT ACCEPT: This sets the default policy for the OUTPUT chain to ACCEPT. This means that any outgoing network packets are allowed by default.
  • iptables -P INPUT ACCEPT: This sets the default policy for the INPUT chain to ACCEPT. This means that any incoming network packets are allowed by default.
  • iptables -P FORWARD ACCEPT: This sets the default policy for the FORWARD chain to ACCEPT. This means that any packets being routed through the system (i.e., not destined for the system itself but passing through it) are allowed by default.
  • iptables -F: This flushes all the rules in all chains. Essentially, it removes any custom rules that have been added, resetting the chains to their default policies.
Then we can turn ON the tunnel on our Windows PC.

Linux

This is basically the same process. We will repeat the installation and config steps from the beginning (except we are not going to install Nginx on our client machine):

Code: Select all

root@client-server:~# apt update && apt upgrade -y

Code: Select all

root@client-server:~# apt install wireguard -y

Code: Select all

root@client-server:~# (umask 077 && printf "[Interface]\nPrivateKey= " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
Next run this command. It will generate a key that you need to write down somewhere:

Code: Select all

root@server:~# wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
Then we are going to edit WireGuard’s config file:

Code: Select all

root@server:~# nano /etc/wireguard/wg0.conf
Now name the tunnel (name doesn’t matter). Copy and edit the following config:

Code: Select all

[Interface]
PrivateKey = <private key of your tunnel (auto-generated don't touch this!)>
Address = 192.168.33.3/32

[Peer]
PublicKey = <Public key from VPS>
AllowedIPs = 192.168.33.1/32
Endpoint = <IP Address of the VPS>:55100
PersistentKeepalive = 25
Now do the same treatment for the firewall as before.

Now you can repeat these steps as many times as you like, just increment the IP address of the clients and keep track of them (i.e.: 192.168.33.1 = Windows PC; 192.168.33.2 = Linux Server; 192.168.33.XXX = <whatever service>).

"Port forwarding"

Now we are going to port forward using the Nginx reverse proxy.

On VPS open Nginx config:

Code: Select all

root@server:~# nano /etc/nginx/nginx.conf
Go to the bottom of the file.

For example, we want to forward some server
— Port: 9998
— Windows PC: 192.168.33.2
— Needs both TCP and UDP forwarded
You can do this:

Code: Select all

stream {
    server {
         listen 9998;
         proxy_pass 192.168.33.2:9998;
    }
    server {
         listen 9998 udp;
         proxy_pass 192.168.33.2:9998;
    }

Code: Select all

#Example for TCP config:
#
#    server {
#         listen <PORT>;
#         proxy_pass <IP>:<PORT>;
#    }
#Example for UDP config:
#
#    server {
#         listen <PORT> udp;
#         proxy_pass <IP>:<PORT>;
#    }
}

Everything above needs to be in stream{...}

Now we need to restart Nginx and WireGuard:

Code: Select all

root@server:~# systemctl restart nginx.service
root@server:~# systemctl restart wg-quick@wg0.service
Now enable Nginx on startup:

Code: Select all

root@server:~# systemctl enable nginx.service
Done! This is how you port forward with WireGuard and Nginx! If you want to add more servers or ports just repeat the steps above. Hope everything works for you!

Common Problem

If you can’t connect to the server and error message like this is appearing:

Code: Select all

Handshake for peer 1 (<IP>:55100) did not complete after 5 seconds, retrying (try 2)
Handshake for peer 1 (<IP>:55100) did not complete after 5 seconds, retrying (try 3)
...
That means you have blocked port 55100. This usually happens after restarting the VPS. You just need to open that port and the connection will establish.
:trol:
Post Reply