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();