Make the Minetest server publicly available
Do you want to play Minetest(or any other game) with your friends on your server but unfortunately your ISP uses CGNAT? In this blog post I will explain how I bypassed this restriction and will show you what I did.
Author:
I am Soupborsh, I am not a GNU/Linux professional and can make mistakes, consequently, I am not responsible for any possible damage.
This will require:
- Remote server(VPS with public ipv4 or ipv6) (I will refer to it as VPS)
- Home server with internet connection (I will refer to it as homeserver)
*This should work with anything using UDP, even with TCP if you can configure iptables for it
My situation:
My ISP uses CGNAT for IPv4 and blocks connections from Internet for IPv6.
VPS OS: Ubuntu 22.04 LTS
How does this work?
To make sure that people all over the internet will be able to connect to your home server which is behind CGNAT(Carrier Grade NAT) I decided to use WireGuard. This is working like this:
Minetest server <– homeserver <– WireGuard tunnel <– VPS <– Internet <– Client(Player)
We need to connect to the VPS using Wireguard. It creates virtual network devices on homeserver and VPS. These have private IPs of other peer, for example, these are outputs of
ip a
on homeserver and VPS after configuring everything.
homeserver:
14: srv: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.66.66.2/32 scope global srv
valid_lft forever preferred_lft forever
inet6 fd42:42:42::2/128 scope global
valid_lft forever preferred_lft forever
VPS:
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8920 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.66.66.1/24 scope global wg0
valid_lft forever preferred_lft forever
inet6 fd42:42:42::1/64 scope global
valid_lft forever preferred_lft forever
10.66.66.2
and fd42:42:42::2
are private vpn ips of homeserver. On a VPS we will redirect all incoming traffic going to VPS’s public ip on port 3000 on udp to 10.66.66.2
and fd42:42:42::2
aka homeserver.
Step by step guide
VPS:
1. Creating WireGuard config
I decided to configure WireGuard using this wireguard-install script:
curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
chmod +x wireguard-install.sh
./wireguard-install.sh
It should promt you something like this:
Welcome to the WireGuard installer!
The git repository is available at: https://github.com/angristan/wireguard-install
I need to ask you a few questions before starting the setup.
You can keep the default options and just press enter if you are ok with them.
IPv4 or IPv6 public address: public_vps_address
Public interface: enp37s0
WireGuard interface name: wg0
Server WireGuard IPv4: 10.66.66.1
Server WireGuard IPv6: fd42:42:42::1
Server WireGuard port [1-65535]: 58838
First DNS resolver to use for the clients: 1.1.1.1
Second DNS resolver to use for the clients (optional): 1.0.0.1
...
Client configuration
The client name must consist of alphanumeric character(s). It may also include underscores or dashes and can't exceed 15 chars.
Client name: soupborsh
Client WireGuard IPv4: 10.66.66.2
Client WireGuard IPv6: fd42:42:42::2
...
Here is your client config file as a QR Code:
...
Your client config file is in /home/soupborsh/wg0-client-soupborsh.conf
If you want to add more clients, you simply need to run this script another time!
It automatically tries to detect your public ip and randomy generates everything else
Change something if it is wrong or you do not like this value. I changed only public_vps_address
to my real public ip address(I have used IPv6 but you can use IPv4 too).
Remember the WireGuard port as well as Server(VPS) and Client(homeserver) IPs, as we will need them later.
2. Configuring iptables
The simplest way I found to redirect traffic from VPS to homeserver is using iptables. Run these commands replacing homeserver_private_vpn_ipv4
homeserver_private_vpn_ipv6
with your actual private WireGuard ipv4 and ipv6 of homeserver(in my case it is 10.66.66.2 and fd42:42:42::2).
sudo iptables -t nat -A PREROUTING -p udp --dport 30000 -j DNAT --to-destination homeserver_private_vpn_ipv4:30000
sudo ip6tables -t nat -A PREROUTING -p udp --dport 30000 -j DNAT --to-destination [homeserver_private_vpn_ipv6]:30000
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo ip6tables -t nat -A POSTROUTING -j MASQUERADE
Make these rules persistent:
sudo apt install iptables-persistent
sudo sh -c "iptables-save > /etc/iptables/rules.v4"
sudo sh -c "ip6tables-save > /etc/iptables/rules.v6"
3. Opening ports
We need to open WireGuard port and port for Minetest(default is 30000) on VPS to be able to connect to it from homeserver. I use ufw as my firewall. Change wireguard_port
to the port of WireGuard we have set up earlier.
sudo ufw allow wireguard_port/udp
sudo ufw allow 30000/udp
sudo ufw reload
You can see which ports are open:
sudo ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
30000 ALLOW Anywhere
58838/udp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
30000 (v6) ALLOW Anywhere (v6)
58838/udp (v6) ALLOW Anywhere (v6)
If it says that status is not active, enable ufw, but be sure that your ssh connection is allowed in it, due to that you can lose your ssh connection to your VPS like that you will have to have to login into your server localy as to regular PC without internet connection.
sudo ufw enable
Homeserver:
1. We need to copy WireGuard .conf files. It can be done with scp
:
sudo scp user@vps_public_ip:/path/to/conf/interface.conf /etc/wireguard/srv.conf
Or like this if you use keys and a custom ssh port:
sudo scp -i /path/to/private/key -P ssh_port user@vps_public_ip:/path/to/conf/interface.conf /etc/wireguard/srv.conf
Change /path/to/private/key
, ssh_port
, user
, vps_public_ip
and /path/to/conf/interface.conf
to yours. Additionally, I set a name for the downloaded config to srv.conf
instead of wg0-client-soupborsh.conf
, due to that wg0-client-soupborsh.conf
gave me issues. Rename it to your liking but I think you can use only lowercase English letters without hyphens and other symbols.
2. Connect to WireGuard VPN.
sudo wg-quick up srv
Change srv
to the name of your config file in /etc/wireguard/
without “.conf” at the end.
3. Minetest server!
If you want IPv6 support add this to the end of your minetest.conf
:
ipv6_server = true
Start or restart(firstly turn off using ctrl + c) your server:
minetestserver
Or by any other method you use to start and stop your Minetest server.