diff --git a/api/src/main/java/com/velocitypowered/api/proxy/config/ProxyConfig.java b/api/src/main/java/com/velocitypowered/api/proxy/config/ProxyConfig.java index 7b4d0bae2..6e5de2371 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/config/ProxyConfig.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/config/ProxyConfig.java @@ -62,6 +62,15 @@ public interface ProxyConfig { */ boolean isOnlineMode(); + /** + * If client's ISP/AS sent from this proxy is different from the one from Mojang's + * authentication server, the player is kicked. This disallows some VPN and proxy + * connections but is a weak form of protection. + * + * @return whether to prevent client proxy connections by checking the IP with Mojang servers + */ + boolean shouldPreventClientProxyConnections(); + /** * Get a Map of all servers registered in velocity.toml. This method does * not return all the servers currently in memory, although in most cases it diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java index 67d9fcd7f..3b83c4380 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -54,6 +54,14 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi @ConfigKey("online-mode") private boolean onlineMode = true; + @Comment({ + "If client's ISP/AS sent from this proxy is different from the one from Mojang's", + "authentication server, the player is kicked. This disallows some VPN and proxy", + "connections but is a weak form of protection." + }) + @ConfigKey("prevent-client-proxy-connections") + private boolean preventClientProxyConnections = false; + @Comment({ "Should we forward IP addresses and other data to backend servers?", "Available options:", @@ -328,6 +336,11 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi return onlineMode; } + @Override + public boolean shouldPreventClientProxyConnections() { + return preventClientProxyConnections; + } + public PlayerInfoForwarding getPlayerInfoForwardingMode() { return playerInfoForwardingMode; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java index 6fb58ffea..e367174c9 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java @@ -50,7 +50,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler { private static final Logger logger = LogManager.getLogger(LoginSessionHandler.class); private static final String MOJANG_HASJOINED_URL = - "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s&ip=%s"; + "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s"; private final VelocityServer server; private final MinecraftConnection mcConnection; @@ -96,8 +96,11 @@ public class LoginSessionHandler implements MinecraftSessionHandler { String playerIp = ((InetSocketAddress) mcConnection.getRemoteAddress()).getHostString(); String url = String.format(MOJANG_HASJOINED_URL, - urlFormParameterEscaper().escape(login.getUsername()), serverId, - urlFormParameterEscaper().escape(playerIp)); + urlFormParameterEscaper().escape(login.getUsername()), serverId); + + if (server.getConfiguration().shouldPreventClientProxyConnections()) { + url += "&ip=" + urlFormParameterEscaper().escape(playerIp); + } ListenableFuture hasJoinedResponse = server.getAsyncHttpClient().prepareGet(url) .execute();