Skip to content

Setup Server

Harden a fresh Ubuntu VPS for hosting the MIP backend and game servers.

Throughout this guide, replace SERVER_IP with your server's public IP address.


Prerequisites

  • A fresh Ubuntu 22.04+ VPS from any cloud provider
  • Your server's public IP address (referred to as SERVER_IP below)
  • PowerShell or Windows Terminal on your dev machine

1 — First Login (Root)

Use the root password provided by your hosting provider:

ssh root@SERVER_IP

2 — Create the Ubuntu User

Check if the ubuntu user already exists (common on cloud images):

id ubuntu

If the user doesn't exist, create it:

adduser ubuntu
usermod -aG sudo ubuntu

So ubuntu can run sudo without a password prompt:

echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' | tee /etc/sudoers.d/90-ubuntu-nopasswd
chmod 440 /etc/sudoers.d/90-ubuntu-nopasswd

3 — Generate an SSH Key (on Your Dev Machine)

If you don't already have one, generate a key on your Windows machine:

ssh-keygen -t ed25519 -C "your_email@example.com"

Accept the default path (C:\Users\<you>\.ssh\id_ed25519). Your public key is at C:\Users\<you>\.ssh\id_ed25519.pub.


4 — Copy Your Public Key to the Server

On the server (still logged in as root):

mkdir -p /home/ubuntu/.ssh
chmod 700 /home/ubuntu/.ssh
nano /home/ubuntu/.ssh/authorized_keys

Paste the entire contents of your id_ed25519.pub file, save and exit (Ctrl+O, Enter, Ctrl+X).

Set ownership:

chown -R ubuntu:ubuntu /home/ubuntu/.ssh
chmod 600 /home/ubuntu/.ssh/authorized_keys

5 — Test Key-Based Login

Open a new terminal (keep the root session open as fallback) and verify:

ssh ubuntu@SERVER_IP

You should get in without a password. If not, fix permissions before continuing.


6 — Disable Password Authentication

Logged in as ubuntu:

sudo nano /etc/ssh/sshd_config

Set these values (uncomment if they exist with #):

PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no

Check config and restart SSH:

sudo sshd -t && (sudo systemctl restart ssh 2>/dev/null || sudo systemctl restart sshd)

Warning

Keep your existing SSH session open until you've confirmed key login works in a new terminal. If you close it before testing, you could lock yourself out.


7 — Install Tailscale

Tailscale creates a private WireGuard mesh network between your machines. With Tailscale, SSH traffic never goes over the public internet — you can close port 22 entirely and still have secure remote access.

Public SSH (port 22 open) Tailscale SSH
Brute-force exposure Thousands of daily attempts Zero — port 22 is closed
Network encryption SSH only WireGuard + SSH (double layer)
Access management Per-server authorized_keys Centralized Tailscale ACLs
Connecting ssh ubuntu@SERVER_IP ssh ubuntu@my-server (MagicDNS)

Install on your server

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Follow the auth URL to link the server to your Tailscale account.

Install on your dev machine

Download from tailscale.com/download or via Chocolatey:

choco install tailscale -y

Sign in with the same Tailscale account. Both machines are now on the same private network.

Verify

From your dev machine:

ssh ubuntu@<tailscale-hostname>

You can find the hostname in the Tailscale admin console.


8 — Configure UFW Firewall

With Tailscale handling SSH, the firewall only needs to allow game-related traffic on the public interface. Port 22 stays closed — all SSH goes over Tailscale.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow in on tailscale0
sudo ufw allow 7000:8000/udp    comment 'Agones game server ports'
sudo ufw enable
sudo ufw status verbose

Why 7000–8000 and not 7777?

UE dedicated servers listen on 7777/udp inside the container, but Agones uses portPolicy: Dynamic — it maps that container port to a randomly allocated host port from the node port range (Agones default: 7000–8000). Game clients connect to the host port, not 7777 directly. The UFW range must cover the full Agones allocation range.

If you change gameservers.minPort / gameservers.maxPort in the Agones Helm values, update this range to match.


Quick Reference

Step Command
First login ssh root@SERVER_IP
Create ubuntu user adduser ubuntu && usermod -aG sudo ubuntu
Passwordless sudo echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' \| tee /etc/sudoers.d/90-ubuntu-nopasswd
Copy SSH key Paste into /home/ubuntu/.ssh/authorized_keys
Test key login ssh ubuntu@SERVER_IP
Disable password auth Edit /etc/ssh/sshd_config → restart sshd
Install Tailscale curl -fsSL https://tailscale.com/install.sh \| sh && sudo tailscale up
Firewall sudo ufw default deny incoming && sudo ufw allow in on tailscale0 && sudo ufw enable

Troubleshooting

"Permission denied (publickey)" : Key not in /home/ubuntu/.ssh/authorized_keys, or wrong permissions. Needs 700 for .ssh/ and 600 for authorized_keys. Fix via your provider's web console if locked out.

Locked out after disabling password : Use your provider's recovery console (VNC / web shell) to edit /etc/ssh/sshd_config, set PasswordAuthentication yes, restart SSH, then fix keys.

UFW blocks SSH : Ensure ufw allow in on tailscale0 was run before ufw enable. If locked out, use your provider's recovery console: ufw allow in on tailscale0 && ufw reload.