Proxy Companion
A light companion plugin for Velocity or BungeeCord that denies banned players at the proxy, before they ever touch a backend. It reads the same database your backends already use, so there is nothing to keep in sync.
The Paper plugin already enforces bans on every backend. The proxy companion moves that check one hop earlier: a banned player is stopped at the proxy login screen instead of being passed to a backend and kicked there. The result is a cleaner reject (no fallback-server flicker) and one fewer connection to your backends.
The proxy companion is optional. PhantomBans works fully without it. Add it only if you run a Velocity or BungeeCord network and want bans enforced at the proxy edge.
What it does
- Boundary ban gate. On login, the proxy looks up the connecting player (by UUID and by IP) in your PhantomBans database. If they have an active ban or IP-ban, the proxy denies the connection with your ban screen.
- Reads your existing data. It queries the same
vg_punishmentstable the Paper plugin writes. No new tables, no extra service. - Fail-open. If the database is unreachable, the proxy lets the player through and the backend still enforces the ban on join. A database blip never locks everyone out of the network.
The proxy gate only handles bans and IP-bans. Mutes, warns, GeoIP/VPN blocking, alt detection, reports, and every GUI stay on the Paper backend. The companion is a narrow boundary gate, not a second copy of the plugin.
Requirements
- A Velocity or BungeeCord/Waterfall proxy.
- A shared MySQL or MariaDB database that your Paper backends already use (
database.type: mysql). SQLite cannot be shared with a proxy. - The matching companion jar for your proxy (
PhantomBans-Velocity-<version>.jarorPhantomBans-Bungee-<version>.jar).
Setup
Install the companion jar
Drop the matching jar into your proxy’s plugins/ folder and start the proxy once. It generates a config.properties in its data folder (plugins/phantombans/ on Velocity, plugins/PhantomBans/ on BungeeCord), then logs that the gate is disabled.
Point it at your database
Open config.properties and fill in the same MySQL/MariaDB the backends use, then set enabled=true:
enabled=true
db-host=127.0.0.1
db-port=3306
db-name=phantombans
db-user=root
db-password=
db-pool-size=4
db-connection-timeout-ms=30000
ban-screen=&cYou are banned from this network.\n&7Reason: &f{reason}\n&7Staff: &f{operator}\n&7Expires: &f{expiry}Restart the proxy
Restart so the gate picks up the new settings. The console logs that the gate is active. A banned player now gets the ban screen at the proxy.
Config keys
| Key | Default | What it does |
|---|---|---|
enabled | false | Master switch. Leave false to install the jar without gating yet. |
db-host | 127.0.0.1 | MySQL/MariaDB host (same DB as the backends). |
db-port | 3306 | Database port. |
db-name | phantombans | Database name. |
db-user | root | Database user. |
db-password | (blank) | Database password. |
db-pool-size | 4 | Connection pool size for the gate. The gate is read-only and light, so it stays small. |
db-connection-timeout-ms | 30000 | How long to wait for a connection before failing open. |
ban-screen | (see below) | The disconnect screen shown to a banned player. |
Ban screen
The ban-screen value uses legacy & colour codes and \n for line breaks. These placeholders are filled per player:
{reason}- the ban reason.{operator}- the staff member who issued the ban.{expiry}- the expiry date, orneverfor a permanent ban.
Backend handoff (proxy-gating)
By default the proxy denies the player and the backend would also deny them on the (now blocked) join. To make the handoff clean, set proxy-gating: true in each backend’s network.yml:
network:
enabled: true
proxy-gating: trueWith proxy-gating: true, the backend stops running its own pre-login ban deny and lets the proxy own the ban screen. This avoids a double-denial and the brief fallback-screen flicker some setups show. GeoIP and VPN checks stay on the backend either way: the proxy gate does not handle them.
proxy-gating is independent of network sync’s transport. You can run it with db-poll (recommended) or the experimental redis transport. See Network Sync for the backend-to-backend layer.
How the two proxies differ
Velocity
Velocity isolates each plugin in its own classloader, so the companion bundles its database driver cleanly with no relocation. The ban screen is rendered with Velocity’s own component serializer.
Both jars read the same config.properties keys and the same database, and behave identically from an operator’s point of view.
Recommended: Velocity. The Velocity companion is the path we test first and is verified on a live network. By 2026 most networks have moved to Velocity, so pick it for a new setup. The one good reason to stay on Bungee is a custom BungeeCord fork you prefer, which is completely fine to keep using; the Bungee companion targets standard BungeeCord and Waterfall.
The BungeeCord companion is experimental. It is built and jar-verified but has not been live-tested on a real proxy yet. Run it if you are on Bungee, but treat it as experimental and please report anything that misbehaves in our Discord so we can confirm it and fix fast. The Velocity companion is verified.
Limits in this release
- Bans and IP-bans only. Mutes, warns, and every other punishment type stay on the backend.
- No geo/VPN gating at the proxy. Those checks remain a backend responsibility.
- One database, shared. The proxy must reach the same MySQL/MariaDB the backends use; SQLite installs cannot use the companion.