Why servers block VPNs
A ban is only as strong as the address it's tied to. When a banned player can switch to a VPN or proxy and create a new account, every ban, mute and alt check becomes a speed bump. Server owners block VPNs mainly to:
- Make bans stick. Ban evasion through alt accounts often runs through VPNs, proxies or cheap data-center servers.
- Slow down bot and alt waves. Join floods often come from data-center ranges that detection services already know.
- Keep community rules meaningful, like one account per player in events or economies.
There's a cost: some honest players use a VPN for privacy, at school or on work networks. A good setup blocks the abuse and gives those players a way in. That's why this guide starts with alerts and only then turns on kicks.
Is prevent-proxy-connections enough?
Vanilla server.properties has a setting called prevent-proxy-connections (off by default). The Minecraft Wiki describes it as kicking players whose network, as seen by your server, differs from the one Mojang's authentication server saw.
That catches a narrow case: a player who signs in through one network and connects through another. A player who runs the whole game through a VPN signs in and connects from the same VPN address, so the check passes. It also can't tell you which country a player connects from, and it can't alert staff instead of kicking.
Use prevent-proxy-connections as a small extra if you like, not as your VPN protection.
How anti-VPN plugins work
An anti-VPN plugin checks the player's IP address during login, before they join the world:
- The plugin asks one or more IP intelligence services about the address. These services track which ranges belong to VPN providers, public proxies, Tor exit nodes and hosting companies.
- Each service answers whether the address looks like a VPN or proxy, often with its country, network and a risk score.
- The plugin applies your rules: refuse the connection, alert staff, post to Discord, or let the player in.
- The answer is cached, so the next login from the same address costs no lookup and no time.
No service knows every address. Fresh VPN ranges, residential proxies and mobile networks can slip through, and occasionally a legitimate address gets flagged. That's why it helps to choose your services deliberately, and to let several services vote when one isn't enough.
Step by step with Connection Guard
Connection Guard is a free, open-source anti-VPN plugin that runs on Paper, Spigot, BungeeCord and Velocity from one JAR. The steps are the same everywhere; only the install location differs.
1. Install it in the right place
On a single server, put the JAR into that server's plugins folder. On a network, install it only on the proxy that players connect to. The proxy sees their real address and one installation protects every backend. Platform notes: Paper and Spigot, BungeeCord and Waterfall, Velocity.
2. Choose your detection services
Out of the box, Connection Guard checks VPNs with ProxyCheck and looks up countries with IP-API. You can also enable IPHub, VPNAPI, or any REST API you configure yourself.
| Service | Used for | Good to know |
|---|---|---|
| ProxyCheck | VPN/proxy and country | Default VPN service. Works without a key; a free account raises the daily allowance. |
| IP-API | VPN/proxy and country | Default country service. The free endpoint is non-commercial, uses HTTP and allows 45 requests per minute. |
| IPHub | VPN/proxy | Needs an API key. |
| VPNAPI | VPN/proxy | Needs an API key. |
| Custom | VPN/proxy | Any GET or POST API; you map the response fields. |
Limits and terms change, so check each service's own pages before going live. If you enable several VPN services, required-positive-flags sets how many must agree before a player is flagged.
3. Watch before you block
The shipped config already kicks VPN players and blocks connections from China and Russia. If you'd rather see who would be affected first, switch kicks off and staff alerts on:
behavior:
vpn:
kick-player: false
notify-staff: true
geo:
kick-player: false
notify-staff: true
type: 'BLACKLIST'
list: []This is a partial example: change these fields in the generated config.yml and keep everything else. Staff with connectionguard.notify.vpn and connectionguard.notify.geo now see an alert whenever a rule matches. Run /cg reload after changing these settings; after changing services or the cache, restart.
4. Look at real results
Give it a few days. When an alert looks wrong, run /cg info <IP or player> to see exactly what each service reported. If a service keeps flagging addresses you trust, add another service and raise required-positive-flags, or exempt specific players.
5. Turn on blocking
When you're happy with what you see, set behavior.vpn.kick-player: true. Add exemptions for trusted players under behavior.vpn.exemptions by UUID or IP address; with LuckPerms you can exempt by permission instead.
Write a fair kick message
The kick screen is the only thing a refused player sees. A good message names the rule and says how to get help, for example: "VPNs and proxies aren't allowed on this server. Turn yours off, or ask for an exemption on our Discord." Edit it in the generated translation/en.yml, and never put keys or internal details in player-facing text.
Quotas and caching
Every first-time address costs one lookup per enabled VPN service, plus one country lookup. As an illustration rather than a measurement: 100 new addresses with one VPN and one country service can mean 200 requests, and both may draw from the same account if you use one provider for both.
Caching keeps that in check. By default Connection Guard remembers VPN answers for 24 hours and country answers for 72 hours, in SQLite or, on larger networks, Redis. Clearing the cache with /cg clear makes everyone look new again, so use it sparingly.
When a detection service is down
Services have outages and rate limits. Connection Guard never treats a missing answer as a VPN: if not enough services answer positively, the player gets in, subject to your country rules and other plugins. Incomplete results aren't cached, so the next login asks again. If you need a stricter policy, use two services so one outage doesn't leave you blind.