mirror of
https://github.com/PaperMC/Waterfall.git
synced 2024-11-06 18:51:21 +01:00
440 lines
19 KiB
Diff
440 lines
19 KiB
Diff
From c0464d9c47b4a3e21a614e3965052889755536f7 Mon Sep 17 00:00:00 2001
|
|
From: linsaftw <25271111+linsaftw@users.noreply.github.com>
|
|
Date: Fri, 30 Apr 2021 22:54:44 -0300
|
|
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
|
|
index 8957c79ac..fd889644f 100644
|
|
--- 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
|
|
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
|
|
index 81ded2243..8bb61ac11 100644
|
|
--- a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
|
|
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/FlameCordConfiguration.java
|
|
@@ -12,6 +12,15 @@ import net.md_5.bungee.config.Configuration;
|
|
import net.md_5.bungee.config.ConfigurationProvider;
|
|
|
|
public class FlameCordConfiguration {
|
|
+ @Getter
|
|
+ private boolean firewallNotify = true;
|
|
+ @Getter
|
|
+ private boolean firewallEnabled = true;
|
|
+ @Getter
|
|
+ private int firewallSeconds = 60;
|
|
+ @Getter
|
|
+ private Collection<String> firewallNames = new HashSet<>(Arrays.asList(new String[] { "mcspam" }));
|
|
+
|
|
public FlameCordConfiguration(final ConfigurationProvider configurationProvider) {
|
|
try {
|
|
final String fileName = "./flamecord.yml";
|
|
@@ -25,6 +34,11 @@ public class FlameCordConfiguration {
|
|
configuration = configurationProvider.load(configurationFile);
|
|
}
|
|
|
|
+ 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);
|
|
+
|
|
if (!configurationExists) {
|
|
configurationProvider.save(configuration, configurationFile);
|
|
}
|
|
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/configuration/MessagesConfiguration.java
|
|
index ebfaa761c..c88077ade 100644
|
|
--- 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);
|
|
|
|
diff --git a/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java
|
|
new file mode 100644
|
|
index 000000000..6a661898d
|
|
--- /dev/null
|
|
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallException.java
|
|
@@ -0,0 +1,30 @@
|
|
+package dev._2lstudios.flamecord.firewall;
|
|
+
|
|
+import java.net.SocketAddress;
|
|
+
|
|
+public class FirewallException extends Exception {
|
|
+ private static final long serialVersionUID = 1L;
|
|
+
|
|
+ public FirewallException(final SocketAddress address) {
|
|
+ super("The address " + address + " is blocked from the server!");
|
|
+ }
|
|
+
|
|
+ public FirewallException(final String string) {
|
|
+ super(string);
|
|
+ }
|
|
+
|
|
+ public FirewallException(final String string, final Throwable throwable) {
|
|
+ super(string, throwable);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public synchronized Throwable initCause(final Throwable cause)
|
|
+ {
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public synchronized Throwable fillInStackTrace() {
|
|
+ return this;
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
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
|
|
index 000000000..8a4747588
|
|
--- /dev/null
|
|
+++ b/flamecord/src/main/java/dev/_2lstudios/flamecord/firewall/FirewallManager.java
|
|
@@ -0,0 +1,116 @@
|
|
+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) {
|
|
+ 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
|
|
diff --git a/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java b/proxy/src/main/java/dev/_2lstudios/flamecord/commands/FlameCordCommand.java
|
|
index bf6f85386..fa0b59c27 100644
|
|
--- 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<>();
|
|
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
|
|
index 494375cd6..aedfece35 100644
|
|
--- 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
|
|
index deee607dc..3720825af 100644
|
|
--- 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
|
|
index 423af854f..70917b0b0 100644
|
|
--- 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 ) );
|
|
}
|
|
}
|
|
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
|
|
index 7f18b5646..5de0414ec 100644
|
|
--- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
|
|
+++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
|
|
@@ -3,6 +3,7 @@ package net.md_5.bungee.netty;
|
|
import com.google.common.base.Preconditions;
|
|
|
|
import dev._2lstudios.flamecord.FlameCord;
|
|
+import dev._2lstudios.flamecord.firewall.FirewallException;
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
import io.netty.handler.codec.CorruptedFrameException;
|
|
@@ -11,6 +12,7 @@ import io.netty.handler.codec.haproxy.HAProxyMessage;
|
|
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;
|
|
@@ -140,6 +142,23 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter
|
|
{
|
|
boolean logExceptions = !( handler instanceof PingHandler );
|
|
|
|
+ // FlameCord - Don't log firewall exceptions
|
|
+ logExceptions = cause instanceof FirewallException ? false : logExceptions;
|
|
+
|
|
+ // FlameCord - Firewall system
|
|
+ if (cause instanceof DecoderException || cause instanceof IllegalStateException || cause instanceof BadPacketException) {
|
|
+ final SocketAddress remoteAddress = ctx.channel().remoteAddress();
|
|
+
|
|
+ if (remoteAddress != null) {
|
|
+ FlameCord.getInstance().getFirewallManager().addFirewalled(remoteAddress);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // FlameCord - Handle firewall exceptions
|
|
+ if (cause instanceof FirewallException) {
|
|
+ FlameCord.getInstance().getFirewallManager().logBlocked(ctx.channel().remoteAddress());
|
|
+ }
|
|
+
|
|
if ( logExceptions )
|
|
{
|
|
if ( cause instanceof ReadTimeoutException )
|
|
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
|
|
index 1d86aa63c..81987ca39 100644
|
|
--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
|
|
+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
|
|
@@ -3,6 +3,7 @@ package net.md_5.bungee.netty;
|
|
import com.google.common.base.Preconditions;
|
|
|
|
import dev._2lstudios.flamecord.FlameCord;
|
|
+import dev._2lstudios.flamecord.firewall.FirewallException;
|
|
import io.github.waterfallmc.waterfall.event.ConnectionInitEvent;
|
|
import io.netty.buffer.PooledByteBufAllocator;
|
|
import io.netty.channel.Channel;
|
|
@@ -63,6 +64,11 @@ public class PipelineUtils
|
|
{
|
|
SocketAddress remoteAddress = ( ch.remoteAddress() == null ) ? ch.parent().localAddress() : ch.remoteAddress();
|
|
|
|
+ // FlameCord - Firewall system
|
|
+ if (remoteAddress != null && FlameCord.getInstance().getFirewallManager().isFirewalled(remoteAddress)) {
|
|
+ throw new FirewallException(remoteAddress);
|
|
+ }
|
|
+
|
|
if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( remoteAddress ) )
|
|
{
|
|
ch.close();
|
|
--
|
|
2.31.1
|
|
|