Port Fowarding Minecraft with PiVPN & Wireguard

Got a Minecraft server you want to expose to the Internet, but can’t open ports on your home network? Well, this is a solution for you!

Before we start, I will give you a small list of what we will be using:

  • wireguard - A free-and-open source virtual private network tool. It will allow us to forward traffic from our server hosting Minecraft to a relay server and vice versa.
  • iptables - The default firewalling and networking software installed on Linux systems.
  • PiVPN - A script to easily install either OpenVPN or Wireguard. We will be using it to install the latter.

Prerequisites

  • A server running Minecraft (aka the “Client”).
  • A server that can have open ports, e.g. a VPS or that Raspberry Pi 4 in your friend’s house (aka the “Host”).

Step 0: Install Wireguard using PiVPN on the host

Installing wireguard and configuring the network manually is a little daunting, so I decided to instead just have PiVPN handle it for me.

$ curl -L https://install.pivpn.io | bash 

Follow the instructions on screen. If you want to set a static IP for your server, then go ahead. Continue through and make sure you select Wireguard. Leave the port as 51820 unless you know what you’re doing. Select any DNS. If you want to access PiVPN via a domain name, make sure you either set up a Dynamic DNS or have a static public address. Go ahead and reboot once it’s done.

Step 1: Create a user through PiVPN

We need to create a user for our Client server to connect to Wireguard with. Luckily, PiVPN contains a command to do this easily.

$ pivpn -a

Add any name you want. Once done, it will generate a .conf file in the configs directory in your user’s home directory.

If you use this VPN with multiple clients (e.g. letting your friends use your VPN), then make sure you create one user per device.

Step 2: Opening ports on the Host

We still need to open ports to let our Client actually access Wireguard on the Host. We also need to allow our Host to accept Minecraft traffic as well. Thus, we need to open ports 25565/tcp (which is Minecraft) and 51820/udp (for Wireguard). The way to do this varies a bit based on routers or services. Search how to do it for your device.

Step 3: Forwarding traffic from the Host to the Client

On the Host, we first want to enable forwarding traffic. This is done with:

echo "1" > /proc/sys/net/ipv4/ip_forward

NOTE: This requires you to be root. Use sudo -i if you are not already root (which you shouldn’t be for security reasons).

Next, we want to forward traffic to the IP address of the Client’s wireguard tunnel. We can find this out by checking the generated .conf file mentioned earlier.

$ cd ~/configs
$ cat [NAME OF USER].conf

Look at the “Address” field under “[Interface].” Write down or copy either the IPv4 or IPv6. I used IPv4 since it’s easier to read. Don’t copy the subnet mask (e.g. the “/24” at the end).

Then, we need to set up our iptables to send traffic that hits our Host to the Client. Replace “[WIREGUARD CLIENT IP] with the IP address you wrote down.

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 25565 -j DNAT --to-destination [WIREGUARD CLIENT IP]:25565
$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE

Now our traffic will be forwarded to our Client’s Wireguard tunnel.

NOTE: iptables will reset if you restart your Host! Install iptables-persistent with sudo apt install iptables-persistent or an alternative if you want to make sure these rules stay.

Step 4: Install Wireguard on Client

Now, we need to connect to Wireguard on the Client, but we need to get Wireguard installed first. On Debian-based systems (e.g. Ubuntu), we can do this by running the command:

$ sudo apt install wireguard

Step 5: Copy the .conf file from PiVPN to the Client

Now, get the user .conf file from your Host to your Client. If you have SSH access, you can run SCP from the Host. If you don’t, you can copy the file to a USB drive and plug it in. Or scan it into your phone using pivpn -qr. Or just manually type the entire thing out. Whatever works best.

Either way, make sure to move the file to /etc/wireguard.

$ sudo mv [NAME OF USER].conf /etc/wireguard/

Step 6: Launch the tunnel

One command.

$ wg-quick up [NAME OF USER]

The Wireguard tunnel will not persist through restarts. If you want to keep it running after your Client machine restarts, enable it in systemd with

$ sudo systemctl enable wg-quick@[NAME OF USER]

Make sure the tunnel isn’t already up when you run this command (you can take it down with wg-quick down [NAME OF USER]).

Congratulations, you’re done.

Postinstallation

Forwarding additional ports

Maybe you want to forward Simple Voice Chat or Geyser. This can be done fairly easily, just open the required ports on the Host and update iptables.

For example, for Geyser on 19132/udp:

$ sudo iptables -t nat -A PREROUTING -p udp --dport 19132 -j DNAT --to-destination [WIREGUARD CLIENT IP]:19132

Make sure to specify the protocol as UDP or TCP under the -p flag depending on the port you needed open. Geyser and Simple Voice Chat both listen on UDP while Minecraft listens on TCP.