Waterfall/Waterfall-Proxy-Patches/0028-Firewall-System.patch

431 lines
20 KiB
Diff
Raw Normal View History

From d1d73f437bc7e61be80eed98c4d8485f53b38a02 Mon Sep 17 00:00:00 2001
2021-05-01 03:59:29 +02:00
From: linsaftw <25271111+linsaftw@users.noreply.github.com>
Date: Fri, 30 Apr 2021 22:54:44 -0300
2021-05-01 00:26:03 +02:00
Subject: [PATCH] Firewall System
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java
2021-05-01 18:00:30 +02:00
index 8957c79a..fd889644 100644
2021-05-01 00:26:03 +02:00
--- a/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/FlameCord.java
@@ -6,6 +6,7 @@ import java.util.logging.Logger;
import dev._2lstudios.flamecord.configuration.FlameCordConfiguration;
import dev._2lstudios.flamecord.configuration.MessagesConfiguration;
import dev._2lstudios.flamecord.configuration.ModulesConfiguration;
+import dev._2lstudios.flamecord.firewall.FirewallManager;
import lombok.Getter;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
@@ -14,12 +15,15 @@ public class FlameCord {
@Getter
private static FlameCord instance;
@Getter
+ private final FirewallManager firewallManager;
+ @Getter
private final FlameCordConfiguration flameCordConfiguration;
@Getter
private final ModulesConfiguration modulesConfiguration;
@Getter
private final MessagesConfiguration messagesConfiguration;
@Getter
+ private final Thread thread;
private boolean running = true;
public static void renew(final Logger logger, final Collection<String> whitelistedAddresses) {
@@ -36,7 +40,29 @@ public class FlameCord {
final ConfigurationProvider configurationProvider = ConfigurationProvider.getProvider(YamlConfiguration.class);
this.flameCordConfiguration = new FlameCordConfiguration(configurationProvider);
+ this.firewallManager = new FirewallManager(logger, whitelistedAddresses,
+ flameCordConfiguration.getFirewallSeconds());
this.modulesConfiguration = new ModulesConfiguration(configurationProvider);
this.messagesConfiguration = new MessagesConfiguration(logger, configurationProvider);
+ this.thread = new Thread() {
+ @Override
+ public void run() {
+ while (running) {
+ try {
+ sleep(1000L);
+
+ if (!running) {
+ return;
+ }
+
+ firewallManager.tick();
+ } catch (final Exception e) {
+ // Ignored
+ }
+ }
+ }
+ };
+
+ this.thread.start();
}
}
\ No newline at end of file
2021-05-01 00:41:58 +02:00
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
2021-05-01 18:00:30 +02:00
index 81ded224..8bb61ac1 100644
2021-05-01 00:41:58 +02:00
--- a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
2021-05-01 15:24:17 +02:00
@@ -12,6 +12,15 @@ import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
2021-05-01 00:41:58 +02:00
public class FlameCordConfiguration {
2021-05-01 15:24:17 +02:00
+ @Getter
+ private boolean firewallNotify = true;
+ @Getter
+ private boolean firewallEnabled = true;
2021-05-01 00:41:58 +02:00
+ @Getter
+ private int firewallSeconds = 60;
+ @Getter
+ private Collection<String> firewallNames = new HashSet<>(Arrays.asList(new String[] { "mcspam" }));
2021-05-01 15:24:17 +02:00
+
2021-05-01 00:41:58 +02:00
public FlameCordConfiguration(final ConfigurationProvider configurationProvider) {
try {
2021-05-01 15:24:17 +02:00
final String fileName = "./flamecord.yml";
@@ -25,6 +34,11 @@ public class FlameCordConfiguration {
configuration = configurationProvider.load(configurationFile);
}
2021-05-01 00:41:58 +02:00
+ this.firewallEnabled = setIfUnexistant("firewall.enabled", this.firewallEnabled, configuration);
+ this.firewallNotify = setIfUnexistant("firewall.notify", this.firewallNotify, configuration);
+ this.firewallSeconds = setIfUnexistant("firewall.seconds", this.firewallSeconds, configuration);
+ this.firewallNames = setIfUnexistant("firewall.names", this.firewallNames, configuration);
2021-05-01 15:24:17 +02:00
+
2021-05-01 00:41:58 +02:00
if (!configurationExists) {
configurationProvider.save(configuration, configurationFile);
2021-05-01 15:24:17 +02:00
}
2021-05-01 00:41:58 +02:00
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java
2021-05-01 18:00:30 +02:00
index ebfaa761..c88077ad 100644
2021-05-01 00:41:58 +02:00
--- a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java
@@ -82,9 +82,17 @@ public class MessagesConfiguration {
setIfUnexistant("command_ip", "&9IP of {0} is {1}", configuration);
// FlameCord
+ setIfUnexistant("firewall_added", "&e{0}&c had been firewalled from the proxy!", configuration);
+ setIfUnexistant("firewall_blocked", "&e{0}&c is firewalled from the proxy, request blocked!",
+ configuration);
+ setIfUnexistant("firewall_info",
+ "&aThere are&b {0} &aaddresses firewalled!\n&aThe firewall will clear in &b{1} &aseconds!",
+ configuration);
+ setIfUnexistant("firewall_cleared", "&b{0}&a addresses had been automatically removed from the firewall!",
+ configuration);
setIfUnexistant("flamecord_reload", "&aAll files had been successfully reloaded!", configuration);
setIfUnexistant("flamecord_help",
- "&aFlameCord&b {0}&a by&b LinsaFTW&a &&b Sammwy&r\n&e /flamecord reload&7 >&b Reloads FlameCord files!\n&e /flamecord help&7 >&b Shows this message!",
+ "&aFlameCord&b {0}&a by&b LinsaFTW&a &&b Sammwy&r\n&e /flamecord reload&7 >&b Reloads FlameCord files!\n&e /flamecord firewall&7 >&b Shows information about the Firewall!\n&e /flamecord help&7 >&b Shows this message!",
configuration);
setIfUnexistant("flamecord_nopermission", "&cYou don't have permission to do this!", configuration);
2021-05-01 00:26:03 +02:00
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java
new file mode 100644
2021-05-01 18:00:30 +02:00
index 00000000..dfb5c6d3
2021-05-01 00:26:03 +02:00
--- /dev/null
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java
2021-05-01 16:25:34 +02:00
@@ -0,0 +1,120 @@
2021-05-01 00:26:03 +02:00
+package dev._2lstudios.flamecord.firewall;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.logging.Logger;
+
+import dev._2lstudios.flamecord.FlameCord;
+import dev._2lstudios.flamecord.configuration.FlameCordConfiguration;
+import lombok.Getter;
+
+public class FirewallManager {
+ private final Logger logger;
+ private final Collection<String> whitelistedAddresses;
+ private final Collection<String> firewalled;
+ private final int defaultSeconds;
+ @Getter
+ private int seconds;
+
+ public FirewallManager(final Logger logger, final Collection<String> whitelistedAddresses,
+ final int defaultSeconds) {
+ this.logger = logger;
+ this.whitelistedAddresses = whitelistedAddresses;
+ this.firewalled = new HashSet<>();
+ this.defaultSeconds = defaultSeconds;
+ this.seconds = defaultSeconds;
+ }
+
+ public boolean isWhitelisted(final SocketAddress address) {
+ final String addressString = address.toString();
+
+ for (final String whitelistedAddressString : whitelistedAddresses) {
+ if (addressString.endsWith(whitelistedAddressString)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void addFirewalled(final SocketAddress address) {
2021-05-01 16:25:34 +02:00
+ if (address == null) {
+ return;
+ }
+
2021-05-01 00:26:03 +02:00
+ if (FlameCord.getInstance().getFlameCordConfiguration().isFirewallEnabled() && !isWhitelisted(address)) {
+ final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address;
+ final String hostString = iNetSocketAddress.getHostString();
+
+ if (!this.firewalled.contains(hostString)) {
+ this.firewalled.add(hostString);
+ logAdded(address);
+ }
+ }
+ }
+
+ public void logAdded(final SocketAddress address) {
+ final FlameCord flameCord = FlameCord.getInstance();
+ final FlameCordConfiguration flameCordConfiguration = flameCord.getFlameCordConfiguration();
+
+ if (flameCordConfiguration.isFirewallNotify()) {
+ final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address;
+ final String hostString = iNetSocketAddress.getHostString();
+
+ this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_added", hostString));
+ }
+ }
+
+ public void logBlocked(final SocketAddress address) {
+ final FlameCord flameCord = FlameCord.getInstance();
+ final FlameCordConfiguration flameCordConfiguration = flameCord.getFlameCordConfiguration();
+
+ if (flameCordConfiguration.isFirewallNotify()) {
+ final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address;
+ final String hostString = iNetSocketAddress.getHostString();
+
+ this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_blocked", hostString));
+ }
+ }
+
+ public Collection<String> getFirewalled() {
+ return this.firewalled;
+ }
+
+ public boolean isFirewalled(final SocketAddress address) {
+ final InetSocketAddress iNetSocketAddress = (InetSocketAddress) address;
+
+ return this.firewalled.contains(iNetSocketAddress.getHostString());
+ }
+
+ public boolean isFirewalled(final String name) {
+ final String nameLowerCase = name.toLowerCase();
+
+ for (final String string : FlameCord.getInstance().getFlameCordConfiguration().getFirewallNames()) {
+ if (nameLowerCase.contains(string)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void tick() {
+ if (--seconds <= 0) {
+ final FlameCord flameCord = FlameCord.getInstance();
+ final int size = this.firewalled.size();
+
+ if (size > 0) {
+ if (flameCord.getFlameCordConfiguration().isFirewallNotify()) {
+ this.logger.info(flameCord.getMessagesConfiguration().getTranslation("firewall_cleared", size));
+ }
+
+ this.firewalled.clear();
+ }
+
+ this.seconds = defaultSeconds;
+ }
+ }
+}
\ No newline at end of file
2021-05-01 16:25:34 +02:00
diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
index f0761a4f..31873afc 100644
2021-05-01 16:25:34 +02:00
--- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
+++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java
2021-05-01 18:00:30 +02:00
@@ -46,8 +46,14 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
2021-05-01 16:25:34 +02:00
final int capacity = in.capacity();
if (readableBytes > 2097152) {
2021-05-01 18:00:30 +02:00
+ // FlameCord - Firewall system
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ctx.channel().remoteAddress());
+
2021-05-01 16:25:34 +02:00
throw new FastDecoderException("Error decoding packet with too many readableBytes: " + readableBytes);
} else if (capacity > 2097152) {
2021-05-01 18:00:30 +02:00
+ // FlameCord - Firewall system
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ctx.channel().remoteAddress());
+
throw new FastDecoderException("Error decoding packet with too big capacity: " + capacity);
}
}
@@ -108,6 +114,9 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
2021-05-01 16:46:41 +02:00
} else {
2021-05-01 16:25:34 +02:00
packetTypeStr = "unknown";
}
2021-05-01 16:46:41 +02:00
+
2021-05-01 16:25:34 +02:00
+ // FlameCord - Firewall system
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ctx.channel().remoteAddress());
2021-05-01 16:43:08 +02:00
throw new FastDecoderException("Error decoding packet " + packetTypeStr + " with contents:\n" + ByteBufUtil.prettyHexDump(slice), e); // Waterfall
2021-05-01 16:25:34 +02:00
} finally
2021-05-01 16:36:56 +02:00
{
2021-05-01 00:26:03 +02:00
diff --git a/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java b/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java
2021-05-01 18:00:30 +02:00
index bf6f8538..fa0b59c2 100644
2021-05-01 00:26:03 +02:00
--- a/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java
+++ b/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java
@@ -5,6 +5,7 @@ import java.util.HashSet;
import dev._2lstudios.flamecord.FlameCord;
import dev._2lstudios.flamecord.configuration.MessagesConfiguration;
+import dev._2lstudios.flamecord.firewall.FirewallManager;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
@@ -30,6 +31,15 @@ private final BungeeCord bungeeCord;
final String arg0 = args[0];
switch (arg0) {
+ case "firewall": {
+ final FirewallManager firewallManager = flameCord.getFirewallManager();
+ final int amount = firewallManager.getFirewalled().size(),
+ seconds = firewallManager.getSeconds();
+
+ sender.sendMessage(TextComponent.fromLegacyText(
+ messagesConfiguration.getTranslation("firewall_info", amount, seconds)));
+ break;
+ }
case "reload": {
// FlameCord - Collect ips from servers
final Collection<String> whitelistedAddresses = new HashSet<>();
2021-05-01 16:17:29 +02:00
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
2021-05-01 18:00:30 +02:00
index 494375cd..aedfece3 100644
2021-05-01 16:17:29 +02:00
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
@@ -165,6 +165,9 @@ public class ServerConnector extends PacketHandler
{
if ( packet.packet == null )
{
+ // FlameCord - Firewall on unexpected packet
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ch.getRemoteAddress());
+
throw new QuietException( "Unexpected packet received during server connector process!\n" + BufUtil.dump(packet.buf, 16) );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
2021-05-01 18:00:30 +02:00
index deee607d..3720825a 100644
2021-05-01 16:17:29 +02:00
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -154,6 +154,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{
if ( packet.packet == null )
{
+ // FlameCord - Firewall on unexpected packet
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ch.getRemoteAddress());
+
throw new QuietException( "Unexpected packet received during server login process!\n" + BufUtil.dump(packet.buf, 16) );
}
}
@@ -396,6 +399,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection
}
break;
default:
+ // FlameCord - Firewall on unexpected packet
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ch.getRemoteAddress());
+
throw new QuietException( "Cannot request protocol " + handshake.getRequestedProtocol() );
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java
2021-05-01 18:00:30 +02:00
index 423af854..70917b0b 100644
2021-05-01 16:17:29 +02:00
--- a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java
@@ -2,6 +2,7 @@ package net.md_5.bungee.connection;
import com.google.gson.Gson;
+import dev._2lstudios.flamecord.FlameCord;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.BungeeCord;
@@ -59,6 +60,9 @@ public class PingHandler extends PacketHandler
{
if ( packet.packet == null )
{
+ // FlameCord - Firewall on unexpected packet
+ FlameCord.getInstance().getFirewallManager().addFirewalled(channel.getRemoteAddress());
+
throw new QuietException( "Unexpected packet received during ping process! " + BufUtil.dump( packet.buf, 16 ) );
}
}
2021-05-01 00:26:03 +02:00
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
2021-05-01 18:00:30 +02:00
index 7f18b564..616651ba 100644
2021-05-01 00:26:03 +02:00
--- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
2021-05-01 18:00:30 +02:00
@@ -11,6 +11,7 @@ import io.netty.handler.codec.haproxy.HAProxyMessage;
2021-05-01 00:26:03 +02:00
import io.netty.handler.timeout.ReadTimeoutException;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.logging.Level;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.connection.CancelSendSignal;
diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
2021-05-01 18:00:30 +02:00
index 1d86aa63..915c162f 100644
2021-05-01 00:26:03 +02:00
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
2021-05-01 18:00:30 +02:00
@@ -63,6 +63,13 @@ public class PipelineUtils
2021-05-01 00:26:03 +02:00
{
SocketAddress remoteAddress = ( ch.remoteAddress() == null ) ? ch.parent().localAddress() : ch.remoteAddress();
+ // FlameCord - Firewall system
2021-05-01 18:00:30 +02:00
+ if ( FlameCord.getInstance().getFirewallManager().isFirewalled( remoteAddress ) ) {
+ FlameCord.getInstance().getFirewallManager().logBlocked( remoteAddress );
+ ch.close();
+ return;
2021-05-01 00:26:03 +02:00
+ }
+
if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( remoteAddress ) )
{
ch.close();
2021-05-01 16:25:34 +02:00
diff --git a/query/src/main/java/net/md_5/bungee/query/QueryHandler.java b/query/src/main/java/net/md_5/bungee/query/QueryHandler.java
2021-05-01 18:00:30 +02:00
index b3bdfd05..49d53f17 100644
2021-05-01 16:25:34 +02:00
--- a/query/src/main/java/net/md_5/bungee/query/QueryHandler.java
+++ b/query/src/main/java/net/md_5/bungee/query/QueryHandler.java
@@ -2,6 +2,8 @@ package net.md_5.bungee.query;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+
+import dev._2lstudios.flamecord.FlameCord;
import io.github.waterfallmc.waterfall.QueryResult;
import io.github.waterfallmc.waterfall.event.ProxyQueryEvent;
import io.netty.buffer.ByteBuf;
@@ -70,6 +72,9 @@ public class QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
ByteBuf in = msg.content();
if ( in.readUnsignedByte() != 0xFE || in.readUnsignedByte() != 0xFD )
{
+ // FlameCord - Firewall system
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ctx.channel().remoteAddress());
+
bungee.getLogger().log( Level.WARNING, "Query - Incorrect magic!: {0}", msg.sender() );
// FlameCord - Close on incorrect magic
ctx.close();
@@ -164,6 +169,9 @@ public class QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
out.writeByte( 0x00 ); // Null
} else
{
+ // FlameCord - Firewall system
+ FlameCord.getInstance().getFirewallManager().addFirewalled(ctx.channel().remoteAddress());
+
// Error!
throw new IllegalStateException( "Invalid data request packet" );
}
2021-05-01 00:26:03 +02:00
--
2.31.1