mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-30 18:57:31 +02:00
Print out a warning if we detect local IP addresses during connections
Reference #1055
This commit is contained in:
@ -0,0 +1,38 @@
|
||||
package com.github.games647.fastlogin.bukkit;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
public class InetUtils {
|
||||
|
||||
private InetUtils() {
|
||||
// Utility
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the given IP address is from the local network
|
||||
*
|
||||
* @param address IP address
|
||||
* @return true if address is from local network or even from the device itself (loopback)
|
||||
*/
|
||||
public static boolean isLocalAddress(InetAddress address) {
|
||||
// Loopback addresses like 127.0.* (IPv4) or [::1] (IPv6)
|
||||
return address.isLoopbackAddress()
|
||||
// Example: 10.0.0.0, 172.16.0.0, 192.168.0.0, fec0::/10 (deprecated)
|
||||
// Ref: https://en.wikipedia.org/wiki/IP_address#Private_addresses
|
||||
|| address.isSiteLocalAddress()
|
||||
// Example: 169.254.0.0/16, fe80::/10
|
||||
// Ref: https://en.wikipedia.org/wiki/IP_address#Address_autoconfiguration
|
||||
|| address.isLinkLocalAddress()
|
||||
// non deprecated unique site-local that java doesn't check yet -> fc00::/7
|
||||
|| isIPv6UniqueSiteLocal(address);
|
||||
}
|
||||
|
||||
private static boolean isIPv6UniqueSiteLocal(InetAddress address) {
|
||||
// ref: https://en.wikipedia.org/wiki/Unique_local_address
|
||||
|
||||
// currently undefined but could be used in the near future fc00::/8
|
||||
return (address.getAddress()[0] & 0xFF) == 0xFC
|
||||
// in use for unique site-local fd00::/8
|
||||
|| (address.getAddress()[0] & 0xFF) == 0xFD;
|
||||
}
|
||||
}
|
@ -46,6 +46,7 @@ import com.github.games647.craftapi.model.skin.SkinProperty;
|
||||
import com.github.games647.craftapi.resolver.MojangResolver;
|
||||
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import com.github.games647.fastlogin.bukkit.InetUtils;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.packet.ClientPublicKey;
|
||||
import lombok.val;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -74,7 +75,7 @@ public class VerifyResponseTask implements Runnable {
|
||||
|
||||
static {
|
||||
ENCRYPTION_CLASS = MinecraftReflection.getMinecraftClass(
|
||||
"util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME
|
||||
"util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME
|
||||
);
|
||||
}
|
||||
|
||||
@ -149,10 +150,20 @@ public class VerifyResponseTask implements Runnable {
|
||||
} else {
|
||||
//user tried to fake an authentication
|
||||
disconnect(
|
||||
"invalid-session",
|
||||
"GameProfile {} ({}) tried to log in with an invalid session. ServerId: {}",
|
||||
session.getRequestUsername(), socketAddress, serverId
|
||||
"invalid-session",
|
||||
"GameProfile {} ({}) tried to log in with an invalid session. ServerId: {}",
|
||||
requestedUsername, address, serverId
|
||||
);
|
||||
|
||||
if (InetUtils.isLocalAddress(address)) {
|
||||
plugin.getLog().warn("The incoming request for player {} uses a local IP address. "
|
||||
+ "This indicates the use of reverse-proxy like HAProxy, TCPShield, BungeeCord, Velocity, "
|
||||
+ "etc. By default, configurable, this plugin requests Mojang to verify the connecting IP "
|
||||
+ "to this server with the one used to log into Minecraft to prevent MITM attacks. In "
|
||||
+ "order to work this security feature, the actual client IP needs to be forwarding "
|
||||
+ "(keyword IP forwarding). This process will also be useful for other server "
|
||||
+ "features like IP banning, so that it doesn't ban the proxy IP", requestedUsername);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioEx) {
|
||||
disconnect("error-kick", "Failed to connect to session server", ioEx);
|
||||
@ -217,15 +228,15 @@ public class VerifyResponseTask implements Runnable {
|
||||
try {
|
||||
// Try to get the old (pre MC 1.16.4) encryption method
|
||||
encryptMethod = FuzzyReflection.fromClass(networkManagerClass)
|
||||
.getMethodByParameters("a", SecretKey.class);
|
||||
.getMethodByParameters("a", SecretKey.class);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
// Get the new encryption method
|
||||
encryptMethod = FuzzyReflection.fromClass(networkManagerClass)
|
||||
.getMethodByParameters("a", Cipher.class, Cipher.class);
|
||||
.getMethodByParameters("a", Cipher.class, Cipher.class);
|
||||
|
||||
// Get the needed Cipher helper method (used to generate ciphers from login key)
|
||||
cipherMethod = FuzzyReflection.fromClass(ENCRYPTION_CLASS)
|
||||
.getMethodByParameters("a", int.class, Key.class);
|
||||
.getMethodByParameters("a", int.class, Key.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,7 +287,7 @@ public class VerifyResponseTask implements Runnable {
|
||||
|
||||
EquivalentConverter<WrappedProfileKeyData> converter = BukkitConverters.getWrappedPublicKeyDataConverter();
|
||||
val wrappedKey = Optional.ofNullable(clientKey).map(key ->
|
||||
new WrappedProfileKeyData(clientKey.expiry(), clientKey.key(), clientKey.signature())
|
||||
new WrappedProfileKeyData(clientKey.expiry(), clientKey.key(), clientKey.signature())
|
||||
);
|
||||
|
||||
startPacket.getOptionals(converter).write(0, wrappedKey);
|
||||
|
Reference in New Issue
Block a user