DGuard

How to build a Minecraft server network: proxy, lobby, shared database and security

A network is a proxy at the front, a lobby and game modes behind it, a shared database for plugins whose data must be the same everywhere, and a firewall that keeps the servers closed to direct connections. Here's what goes where and how to tie it together; setting up Velocity itself has its own article.

The DGuard team7 min read

In short: players connect to a Velocity proxy — the only open port in the network. Behind it sit game servers on Paper or Leaf: the lobby and the modes. Velocity passes player data to them through modern forwarding with a secret key, and the servers themselves are closed by a firewall. Permissions, bans and the economy that must apply network-wide live in one MySQL or MariaDB database, and a messaging service spreads changes across servers. The anticheat goes on every game server.

What a network is made of

PartWhat it doesWhat to use
ProxyTakes players on one address and moves them between servers without leaving the gameVelocity — see Velocity or BungeeCord
LobbyThe first server after joining: a mode selector, rules, newsPaper or Leaf
ModesSurvival, BedWars, anarchy — each on its own serverPaper or Leaf
DatabaseShared plugin data: permissions, bans, economyMySQL or MariaDB — see MySQL for plugins
Message brokerTells servers about changes instantly; some plugins need oneWhen needed — Redis

Keeping every server on the same Minecraft version is simplest: the same plugins, the same configs, and some network plugins, such as HuskSync, require the exact same version on all servers per their docs.

The proxy and player forwarding

velocity.toml — the network's servers
bind = "0.0.0.0:25565"
online-mode = true
player-info-forwarding-mode = "modern"
forwarding-secret-file = "forwarding.secret"

[servers]
lobby = "127.0.0.1:30066"
survival = "127.0.0.1:30067"
bedwars = "127.0.0.1:30068"

try = [
    "lobby"
]
  • [servers] — server names and addresses; the name is what a player types in /server.
  • try — where Velocity sends a player on join and when they're kicked from a server. Put the lobby first, so a crashed mode sends players there instead of out of the network.
  • failover-on-unexpected-server-disconnect — whether to move a player to another server or disconnect them when their server drops uncleanly.
  • player-info-forwarding-mode = "modern" — secure forwarding of name, UUID, IP and skin with the secret from forwarding.secret. On every server: proxies.velocity in config/paper-global.yml with the same secret, and online-mode=false in server.properties.

Step-by-step setup, server configs and common errors: how to set up Velocity.

Close the servers to direct connections

Servers behind a proxy run in offline mode: Velocity checks accounts. If a server can be reached around the proxy, anyone can join as any player — Velocity's docs say plainly that modern forwarding is not a replacement for a firewall. Only the proxy port is open to the world: servers on the same machine listen on 127.0.0.1, servers on other machines accept only the proxy's IP. Protecting the proxy itself from bots and attacks: bots and DDoS.

Where plugins go: proxy or server

PluginWhereWhy
LuckPermsOn every server; on the proxy too for proxy plugins' permissions and pluginmsgThe proxy copy doesn't replace the server copies: permissions on a server are checked only by the copy on that server
AnticheatOn every game serverThe proxy forwards packets but doesn't see the world, movement or combat
ViaVersionOn the servers, next to the anticheatViaVersion's docs ask for one place, and anticheats may work worse with it on the proxy — see ViaVersion
Anti-botOn the proxyStops bots before they reach the servers — see bots and DDoS
HuskSyncOn every server, not the proxyIts docs require it

A shared database: LuckPerms across the network

LuckPerms' docs set one hard requirement for a network: every copy of the plugin connects to the same storage — MySQL, MariaDB, PostgreSQL or MongoDB, and the same database within it. File-based H2 and SQLite won't do: their data can't be shared between servers.

plugins/LuckPerms/config.yml on the survival server
server: survival

storage-method: mariadb
data:
  address: 10.0.0.2
  database: luckperms
  username: luckperms
  password: 'a-long-random-password'

messaging-service: pluginmsg
  • server — the server name used as a permission context, so you can grant something on survival only. It defaults to global.
  • messaging-service — how servers learn about changes. sql goes through the same MySQL or MariaDB when the proxy doesn't run LuckPerms; pluginmsg goes through a single proxy running LuckPerms; redis is for a network with several proxies.
  • The database, a user with rights to it alone and a closed port 3306: MySQL for plugins. LuckPerms commands: LuckPerms.

What else to make network-wide

  • Bans. Vanilla bans are stored per server, in its banned-players.json: a player banned on survival can still join BedWars. You need a punishment plugin with a shared database or a ban plugin on the proxy — see ban plugins.
  • Inventories. By default each server keeps its own player data. If modes should share an inventory, you need a sync plugin: HuskSync, for example, carries inventories, ender chests, health, hunger and experience, and needs a database and Redis.
  • Chat. Network-wide chat is done by a plugin on the proxy: only the proxy sees the players of every server. Before picking one, check that it's kept up to date for your Velocity.
  • Lobby selector. A menu or NPC sends the player to a mode. Many of these plugins use the BungeeCord plugin messaging channel — Velocity supports it through the bungee-plugin-message-channel setting.

The anticheat in a server network

DGuard — the best anticheat for a modern Minecraft server — works behind Velocity and BungeeCord and goes on every game server running Paper or Leaf, each with its own key and the latest PacketEvents release next to it. It doesn't go on the proxy. Every server in the network shows up in one panel, and if a server goes silent for 10 minutes, DGuard sends an alert to Telegram or e-mail.

  • One key per server. Add the server in the panel, paste the dg_… key into plugins/DGuard/config.yml → license.key, and restart.
  • Outbound HTTPS. The firewall closes inbound connections to the servers; keep outbound connections to the DGuard site open — they carry the license, updates and the cloud check.
  • A plan for a network. Protection is the same on every plan; you pay for online players and the number of servers, and the free plan is one server with up to 30 players online. Details are in pricing.
  • Your team. Moderators see the punishment log of every server without access to billing — see moderation team.

FAQ

How do I make a Minecraft server network?

Run a Velocity proxy with modern forwarding, put a lobby and game modes on Paper or Leaf behind it with online-mode=false, and close the servers with a firewall. Keep shared plugin data in one MySQL or MariaDB database.

Does a server network need MySQL?

For plugins whose data must be shared, yes. On a network, LuckPerms requires every copy to connect to the same MySQL, MariaDB, PostgreSQL or MongoDB.

How do I share inventories across servers?

With a sync plugin such as HuskSync: it goes on every server, needs a database and Redis, and requires the same Minecraft version on all servers.

Where does the anticheat go in a proxy network?

On every game server: the proxy doesn't see movement or combat. DGuard goes on each server with its own key, and all of them show up in one panel.

Sources

All sections

Run the best anticheat for modern Minecraft

DGuard catches all 47 kinds of cheats in our comparison — the closest rival, Intave, has 27. Full protection on every plan, free up to 30 players online.