From 70abda9c5bf4cccd2cf52a58936c1a25cf5cad48 Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 2 Jun 2020 21:56:50 +0100 Subject: [PATCH 1/3] Implement legacy forwarding BungeeGuard handshake support --- .../proxy/config/PlayerInfoForwarding.java | 1 + .../proxy/config/VelocityConfiguration.java | 4 +++ .../backend/VelocityServerConnection.java | 26 +++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java b/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java index e0c2c3558..908a26a31 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/PlayerInfoForwarding.java @@ -3,5 +3,6 @@ package com.velocitypowered.proxy.config; public enum PlayerInfoForwarding { NONE, LEGACY, + BUNGEEGUARD, MODERN } 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 806ef44ce..ffe8ea832 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -61,6 +61,9 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi " proxy and will have offline-mode UUIDs.", "- \"legacy\": Forward player IPs and UUIDs in a BungeeCord-compatible format. Use this if", " you run servers using Minecraft 1.12 or lower.", + "- \"bungeeguard\": Forward player IPs and UUIDs in a format supported by the BungeeGuard", + " plugin. Use this if you run servers using Minecraft 1.12 or lower, and are", + " unable to implement network level firewalling (on a shared host).", "- \"modern\": Forward player IPs and UUIDs as part of the login process using Velocity's ", " native forwarding. Only applicable for Minecraft 1.13 or higher." }) @@ -185,6 +188,7 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi + "from the proxy and will have offline-mode UUIDs."); break; case MODERN: + case BUNGEEGUARD: if (forwardingSecret == null || forwardingSecret.length == 0) { logger.error("You don't have a forwarding secret set. This is required for security."); valid = false; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index b91522507..5b87b95b9 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -13,10 +13,12 @@ import static com.velocitypowered.proxy.network.Connections.MINECRAFT_ENCODER; import static com.velocitypowered.proxy.network.Connections.READ_TIMEOUT; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.proxy.server.ServerInfo; +import com.velocitypowered.api.util.GameProfile.Property; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.config.PlayerInfoForwarding; import com.velocitypowered.proxy.connection.ConnectionTypes; @@ -41,8 +43,11 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelInitializer; import io.netty.handler.flow.FlowControlHandler; import io.netty.handler.timeout.ReadTimeoutHandler; +import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.function.UnaryOperator; import org.checkerframework.checker.nullness.qual.Nullable; public class VelocityServerConnection implements MinecraftConnectionAssociation, ServerConnection { @@ -106,7 +111,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, return result; } - private String createLegacyForwardingAddress() { + private String createLegacyForwardingAddress(UnaryOperator> propertiesTransform) { // BungeeCord IP forwarding is simply a special injection after the "address" in the handshake, // separated by \0 (the null byte). In order, you send the original host, the player's IP, their // UUID (undashed), and if you are in online-mode, their login properties (from Mojang). @@ -117,10 +122,24 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, .append('\0') .append(proxyPlayer.getGameProfile().getUndashedId()) .append('\0'); - GSON.toJson(proxyPlayer.getGameProfile().getProperties(), data); + GSON.toJson(propertiesTransform.apply(proxyPlayer.getGameProfile().getProperties()), data); return data.toString(); } + private String createLegacyForwardingAddress() { + return createLegacyForwardingAddress(UnaryOperator.identity()); + } + + private String createBungeeGuardForwardingAddress(byte[] forwardingSecret) { + // Append forwarding secret as a BungeeGuard token. + Property property = new Property("bungeeguard-token", + new String(forwardingSecret, StandardCharsets.UTF_8), ""); + return createLegacyForwardingAddress(properties -> ImmutableList.builder() + .addAll(properties) + .add(property) + .build()); + } + private void startHandshake() { final MinecraftConnection mc = ensureConnected(); PlayerInfoForwarding forwardingMode = server.getConfiguration().getPlayerInfoForwardingMode(); @@ -132,6 +151,9 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation, handshake.setProtocolVersion(protocolVersion); if (forwardingMode == PlayerInfoForwarding.LEGACY) { handshake.setServerAddress(createLegacyForwardingAddress()); + } else if (forwardingMode == PlayerInfoForwarding.BUNGEEGUARD) { + byte[] secret = server.getConfiguration().getForwardingSecret(); + handshake.setServerAddress(createBungeeGuardForwardingAddress(secret)); } else if (proxyPlayer.getConnection().getType() == ConnectionTypes.LEGACY_FORGE) { handshake.setServerAddress(handshake.getServerAddress() + HANDSHAKE_HOSTNAME_TOKEN); } else { From c563372ffdd69a1276ca352eb4d03798d9876df7 Mon Sep 17 00:00:00 2001 From: Luck Date: Wed, 3 Jun 2020 00:35:04 +0100 Subject: [PATCH 2/3] Remove unnecessary imports --- .../proxy/connection/backend/VelocityServerConnection.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java index 4d14e94c0..86a17870d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/VelocityServerConnection.java @@ -26,13 +26,9 @@ import com.velocitypowered.proxy.server.VelocityRegisteredServer; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelInitializer; -import io.netty.handler.flow.FlowControlHandler; -import io.netty.handler.timeout.ReadTimeoutHandler; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; import java.util.function.UnaryOperator; import org.checkerframework.checker.nullness.qual.Nullable; From 4263c4e2d47f4380a204f4b77ef26ce57e6d1ffb Mon Sep 17 00:00:00 2001 From: Luck Date: Wed, 3 Jun 2020 00:58:26 +0100 Subject: [PATCH 3/3] Fix config formatting --- .../proxy/config/VelocityConfiguration.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 7ce85543e..3522d1523 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java @@ -65,21 +65,21 @@ public class VelocityConfiguration extends AnnotatedConfig implements ProxyConfi @Comment({ "Should we forward IP addresses and other data to backend servers?", "Available options:", - "- \"none\": No forwarding will be done. All players will appear to be connecting from the", - " proxy and will have offline-mode UUIDs.", - "- \"legacy\": Forward player IPs and UUIDs in a BungeeCord-compatible format. Use this if", - " you run servers using Minecraft 1.12 or lower.", + "- \"none\": No forwarding will be done. All players will appear to be connecting", + " from the proxy and will have offline-mode UUIDs.", + "- \"legacy\": Forward player IPs and UUIDs in a BungeeCord-compatible format. Use this", + " if you run servers using Minecraft 1.12 or lower.", "- \"bungeeguard\": Forward player IPs and UUIDs in a format supported by the BungeeGuard", - " plugin. Use this if you run servers using Minecraft 1.12 or lower, and are", - " unable to implement network level firewalling (on a shared host).", - "- \"modern\": Forward player IPs and UUIDs as part of the login process using Velocity's ", - " native forwarding. Only applicable for Minecraft 1.13 or higher." + " plugin. Use this if you run servers using Minecraft 1.12 or lower, and are", + " unable to implement network level firewalling (on a shared host).", + "- \"modern\": Forward player IPs and UUIDs as part of the login process using", + " Velocity's native forwarding. Only applicable for Minecraft 1.13 or higher." }) @ConfigKey("player-info-forwarding-mode") private PlayerInfoForwarding playerInfoForwardingMode = PlayerInfoForwarding.NONE; @StringAsBytes - @Comment("If you are using modern IP forwarding, configure an unique secret here.") + @Comment("If you are using modern or BungeeGuard IP forwarding, configure an unique secret here.") @ConfigKey("forwarding-secret") private byte[] forwardingSecret = generateRandomString(12).getBytes(StandardCharsets.UTF_8);