Running a server
Network
On this page
The network link joins several rustmc servers into one network, with no proxy in front of them. Once servers are linked, their plugins can send each other messages, see who is online on every server, and send a player from one server to another. The link carries nothing by itself: what a network does (cross-server chat, a server selector, staff alerts) is up to the plugins you run.
Every server connects to every other server it names, and accepts a connection from each of them. So every server on the network lists every other one.
Turning it on
The network is off by default. Give each server a name, a listen address, the shared secret and
its peers in rustmc.yml:
# rustmc.yml on the server named "survival"
network:
enabled: true
name: survival
listen: 127.0.0.1:25700
secret: "a long random string, the same on every server"
peers:
rusty:
address: 127.0.0.1:25701
join: rusty.example.net:25567
# rustmc.yml on the server named "rusty"
network:
enabled: true
name: rusty
listen: 127.0.0.1:25701
secret: "a long random string, the same on every server"
peers:
survival:
address: 127.0.0.1:25700
join: survival.example.net
The names under peers must be the other servers' own network.name, spelt the same way, and
each server must list the others. A server only accepts a connection from a name it lists as a
peer, and when it connects out it checks that the server answering has the name it expected.
For a player to be sent to a server, that server needs accepts-transfers=true in its
server.properties. Without it, its door turns away anyone sent to it.
With network.enabled on, the server will not start unless the settings are valid: a usable
name, a listen address that parses and can be bound, a secret of at least 32 characters, and
every peer with a usable name and address. The console says which setting is wrong.
Settings
The default file holds these keys:
| Key | Default | Meaning |
|---|---|---|
network.enabled | false | Turns the link on |
network.name | "" | This server's name on the network. 1 to 32 letters, digits, - and _. Every server needs its own |
network.listen | 127.0.0.1:25700 | The ip:port this server listens on for its peers. It must be an IP address, not a host name |
network.secret | "" | The secret every server on the network shares. At least 32 characters |
These are not in the default file, because there are none until you add them:
| Key | Default | Meaning |
|---|---|---|
network.peers.<peer>.address | "" | Where that peer listens (its network.listen), as host:port. This server connects to it there |
network.peers.<peer>.join | "" | The public address players are sent to, host:port or a host on its own for port 25565. Empty means nobody can be sent there |
network.channels.<plugin> | "" | Extra channel namespaces that plugin may use, comma-separated (moderation, chat), or * for every namespace |
<peer> is the other server's network name and <plugin> is a plugin's name, each in letters,
digits, - and _. Always give address its port: one written without a port is taken as 25565,
which is the game port, not the link.
How it behaves
The link
- Connecting. At startup the server opens its listener and starts connecting to each peer. A peer that is down is retried, waiting 1 second at first and doubling up to 30 seconds between tries. The console says when a link comes up, when it is lost and why, and says once that a peer cannot be reached yet rather than on every try.
- Proving the secret. Before anything else is sent, both ends prove they hold the same secret. The secret itself never crosses the wire, a recorded handshake cannot be replayed, and a connection from a name that is not a peer is closed straight away. A handshake has 5 seconds to finish.
- Staying up. A quiet link is pinged every 10 seconds, and a connection silent for 30 seconds is dropped and made again.
- Off the game's tick. The link runs on a thread of its own. A peer that is down, slow or gone does not slow the game.
- Up and down. A peer counts as up when this server's own connection to it is up. Plugins can ask which peers are up.
Messages between plugins
Plugins publish messages on named channels and subscribe to the channels they want to hear.
- A channel belongs to a plugin. A channel is written
<namespace>:<name>, such aschat:global. A plugin may use its own name as the namespace and nothing else, unlessnetwork.channels.<plugin>grants it more. For example,chat: "moderation"lets thechatplugin also usemoderation:...channels, andchat: "*"lets it use any. - Delivery is best effort. A message goes to every peer whose link is up at that moment. If the link drops before it is written, that peer never gets it, and nothing is sent again.
- Arriving messages wait for the tick. A message is handed to its subscribers on the game tick after it arrives, up to 256 a tick. A message that no plugin on this server subscribes to is thrown away when it arrives.
The calls plugins use, and what each one answers, are listed in the
server network host calls. Messages arrive as the
network_message event, and can be changed or handled on the way in at
the network_message hook point.
Who is online where
Each server tells its peers who is online on it, and its max-players. It sends this when a link
comes up, and after that about once a second whenever it has changed. When a peer's link is down,
nobody is listed for it.
- Vanished players are listed with a flag saying they are hidden, so a plugin can show them to staff. They are not counted in a server's online count.
- Fake players are listed as players, but are not counted in any server's online count. Every server can tell a fake from a real player by its uuid.
max-playersis each server's own setting, as it last said it. It shows as 0 until a peer has said.
So a server selector can show "3/20" for each server the way the server list would.
Sending a player to another server
A plugin sends a player to a peer with the game's own transfer packet, to that peer's join
address. The player's client disconnects and logs in to the other server, which treats it as a new
login with its own checks: its whitelist, its bans, its online mode. Nothing the player carries
moves with them: each server keeps its own player data.
The sending server does not check whether the peer is up, because a player can often reach a server that this server cannot.
Limits
- 1 MiB a frame. A message's payload may be at most 1 MiB less 1,024 bytes. A peer that sends a larger frame has its connection closed.
- 200 messages a second from each peer, in bursts of up to 400. Past that, the rest are dropped, and the console says so at most once a minute.
- 8 MiB waiting to go to each peer. If a peer stops reading, what does not fit is dropped.
- 16 MiB waiting for this server's plugins. If plugins cannot keep up, newer messages are dropped, and the console says so at most once a minute.
- 16 connections part-way through a handshake at once. More are turned away, so a flood of connections cannot tie the link up.
- A peer may list at most 10,000 players.
- Bedrock players cannot be sent. The transfer packet is not translated for Bedrock clients, so sending a Bedrock player to another server does nothing for them.
- Servers must run the same link version. A server speaking a different version of the link is turned away at the handshake.
Security and privacy
- The link is authenticated but not encrypted. Anyone who can watch the traffic between two
servers can read every message and every player list. Keep
network.listenon loopback (127.0.0.1) when the servers share a machine. When they are on different machines, use a private network or a tunnel between them, and firewall the port so only your servers can reach it. Ifnetwork.listenis not a loopback or private address, the console warns at startup. - The secret is the network. Any server holding it can join the network under a peer's name,
speak on every plugin's channels, and tell the others who is online. Generate a long random
secret, put the same value in every server's
rustmc.yml, and keep that file private. The secret is never written to the log. If it leaks, change it on every server. - Player lists are shared. Every server on the network learns the name and uuid of everyone online on every other server, including vanished players. Plugins are expected not to show hidden players to anyone but staff, but the server cannot enforce what a plugin does with the list.
- Refused connections are logged sparingly. A connection that fails the handshake is noted in the console, with its address, at most once a minute, so someone scanning the port cannot fill the log.
See also the Network section of rustmc.yml.
From docs/network.md in the RustMC repository at bbd81209ad.