When scaling a Minecraft network across multiple game instances (lobby, survival, minigames), interconnecting standalone servers requires a dedicated proxy layer. The modern industry standard is Velocity by the PaperMC team, superseding legacy BungeeCord. Velocity delivers exceptional connection throughput, resilience against bot floods, and native support for modern protocol packets.
However, novice administrators frequently introduce a critical security vulnerability: they launch Velocity on public port 25565 while leaving backend Paper instances (ports 25566, 25567) exposed to the internet. Threat actors can connect directly to backend ports using modified clients, impersonating administrator nicknames and UUIDs. This guide walks through deploying Velocity securely using Modern HMAC forwarding and isolating backends via UFW firewall rules.
Configuring forwarding.secret in velocity.toml#
Unlike legacy BungeeCord forwarding—where player IP addresses were passed as plaintext handshake headers—Velocity implements Modern forwarding. In this architecture, player metadata (client IP, authentic UUID, skin data) is signed cryptographically using an HMAC shared secret.
Generate a secure secret key:
mkdir -p /opt/velocity /opt/paper-lobby
openssl rand -hex 32 > /opt/velocity/forwarding.secret
Configure /opt/velocity/velocity.toml to bind public port 25565 and activate modern player forwarding:
cat << 'EOF' | sudo tee -a /opt/velocity/velocity.toml
bind = "0.0.0.0:25565"
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"
[servers]
lobby = "127.0.0.1:25566"
survival = "127.0.0.1:25567"
try = [
"lobby"
]
EOF
Configuring Paper backend server nodes#
Backend Paper (or Purpur) instances must now be configured to accept player packets exclusively from your proxy while verifying HMAC signatures.
Copy the generated forwarding.secret to each backend working directory:
cp /opt/velocity/forwarding.secret /opt/paper-lobby/
Update config/paper-global.yml on the backend node to enable Velocity integration:
cat << 'EOF' | sudo tee -a /opt/paper-lobby/config/paper-global.yml
proxies:
velocity:
enabled: true
online-mode: true
secret: "PASTE_CONTENTS_OF_FORWARDING_SECRET_HERE"
EOF
In server.properties, set online-mode=false (as Mojang authentication is handled upstream by Velocity) and bind the service to the local loopback interface:
cat << 'EOF' | sudo tee -a /opt/paper-lobby/server.properties
server-ip=127.0.0.1
server-port=25566
online-mode=false
EOF
Isolating backend ports with UFW firewall rules#
When backend servers reside on separate physical VPS nodes within a private VPC network, binding to 127.0.0.1 alone is insufficient. You must block public ingress on backend ports using firewall rules, granting access exclusively to the Velocity proxy IP.
Configure UFW rules on the backend host:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
# Allow game connections only from the Velocity proxy IP
sudo ufw allow from 10.0.0.5 to any port 25566 proto tcp
# Enable firewall
sudo ufw enable
sudo ufw status verbose
With these rules active, connection attempts targeting port 25566 directly from the internet are silently dropped by the Linux kernel.
Verifying network routing and client IP preservation#
Start both the Velocity proxy and Paper instances, then review startup logs:
sudo journalctl -u velocity -n 50 --no-pager
Connect via your client targeting the public proxy IP on port 25565. Check the backend log:
tail -n 20 /opt/paper-lobby/logs/latest.log | grep -E "(logged in with entity id|UUID)"
Verify that the output reports the client's authentic public IP address and valid Mojang UUID rather than 127.0.0.1. This confirms accurate passthrough for anti-cheat and banning systems.
To administer multi-server Minecraft networks, monitor node health, and orchestrate private cluster firewalls without manual configuration edits, teams use an end-to-end server management platform, where proxy routing and server isolation are automated natively.




