Host Game Servers Using Rathole!
The purpose of this blog post is to show how you can expose a local game server to the internet for very cheap. In this blog post I specifically showcase how you can host a FiveM server on your own machine.
My specific problem was that I was unable to host a fivem server and allow people to access it through my vps.
Options I had attempted was to host it through ngrok, reverse ssh tunnel and wireguard vpn all which had problems and were not ideal solutions.
To host the FiveM server, I had a few requirements:
- Don’t expose my public IP
- Don’t pay a fortune for hosting
- FiveM Server provider was charging £6.56 per month for 8GB RAM & 2 CPU cores
Until I had thought of using a mini-pc I use for hosting virtual machines locally:
tew@lab
-------
OS: Debian GNU/Linux 12 (bookworm) x86_64
Host: HP Pro Mini 400 G9 Desktop PC SBKPF
Kernel: 6.1.0-28-amd64
CPU: 13th Gen Intel i5-13500T (20) @ 1.600GHz
GPU: Intel AlderLake-S GT1
Memory: 2791MiB / 63909MiB
This method of game hosting should work as long as you’re able to host the game server locally initally.
The unqiue issue with hosting a fivem server was the requirment for both UDP+TCP on port 30120 which both ngrok and ssh only support TCP.
Wireguard VPN required me to setup a config for everyone who wanted to play and its a pain in the ass since occasionally the server would decide not to route the packets among the clients.
The Solution
Rathole a program that allows for reverse proxy NAT traversal. For a proper configuration and setup of rathole check out the following blog post by Lukasz Expose a game server securely over proxy.
Using rathole tool I was able to host the server and below is how the setup looked:
localhost:30120"] RC["Rathole Client"] end subgraph VPS["VPS Server
Port 2333"] RS["Rathole Server"] PF["Public Port
0.0.0.0:30120
UDP/TCP"] end subgraph Players["Remote Players"] P1["Player 1"] P2["Player 2"] end GS --> |"Local Port
Forwarding"| RC RC --> |"Encrypted Tunnel
Auth Token"| RS RS --> |"Port Forward"| PF P1 --> |"Connect"| PF P2 --> |"Connect"| PF style GS fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff style RC fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff style RS fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff style PF fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff style P1 fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff style P2 fill:#1a1a1a,stroke:#ff6b1a,color:#ffffff linkStyle default stroke:#ff6b1a,color:#ffffff
For rathole I had used the following server.toml
on my VPS:
[server]
bind_addr = "0.0.0.0:2333"
[server.services.fivem_udp]
token = "<REDACTED>"
bind_addr = "0.0.0.0:30120"
type = "udp"
[server.services.fivem_tcp]
token = "<REDACTED>"
bind_addr = "0.0.0.0:30120"
type = "tcp"
This is the client.toml
for my mini-PC:
[client]
remote_addr = "wire.cat:2333"
[client.services.fivem_udp]
token = "<REDACTED>"
local_addr = "127.0.0.1:30120"
type = "udp"
[client.services.fivem_tcp]
token = "<REDACTED>"
local_addr = "0.0.0.0:30120"
type = "tcp"
It’s that simple, you run those configs using
./rathole {server,client}.toml
and it should work. You might need to do some firewall configuration on the VPS both iptables and any hosting provider policies.