improved origin blacklist (update bungee)

This commit is contained in:
LAX1DUDE 2022-05-26 20:47:59 -07:00
parent dac4c51920
commit a9edd1fa7b
10 changed files with 99 additions and 14 deletions

View File

@ -252,7 +252,7 @@ public class BungeeCord extends ProxyServer {
BanList.maybeReloadBans(null); BanList.maybeReloadBans(null);
} }
}, 0L, TimeUnit.SECONDS.toMillis(3L)); }, 0L, TimeUnit.SECONDS.toMillis(3L));
DomainBlacklist.init(); DomainBlacklist.init(this);
this.closeInactiveSockets.scheduleAtFixedRate(new TimerTask() { this.closeInactiveSockets.scheduleAtFixedRate(new TimerTask() {
@Override @Override
public void run() { public void run() {

View File

@ -28,6 +28,10 @@ public interface ConfigurationAdapter {
boolean getBlacklistOfflineDownload(); boolean getBlacklistOfflineDownload();
boolean getBlacklistReplits();
boolean getBlacklistOriginless();
AuthServiceInfo getAuthSettings(); AuthServiceInfo getAuthSettings();
Map<String, Object> getMap(); Map<String, Object> getMap();

View File

@ -291,7 +291,7 @@ public class YamlConfig implements ConfigurationAdapter {
@Override @Override
public Collection<String> getBlacklistURLs() { public Collection<String> getBlacklistURLs() {
boolean blacklistEnable = this.getBoolean("enable_origin_blacklist", true); boolean blacklistEnable = this.getBoolean("enable_web_origin_blacklist", true);
if(!blacklistEnable) { if(!blacklistEnable) {
return null; return null;
} }
@ -307,7 +307,17 @@ public class YamlConfig implements ConfigurationAdapter {
@Override @Override
public boolean getBlacklistOfflineDownload() { public boolean getBlacklistOfflineDownload() {
return this.getBoolean("enable_offline_download_blacklist", false); return this.getBoolean("origin_blacklist_block_offline_download", false);
}
@Override
public boolean getBlacklistReplits() {
return this.getBoolean("origin_blacklist_block_replit_clients", false);
}
@Override
public boolean getBlacklistOriginless() {
return this.getBoolean("origin_blacklist_block_missing_origin_header", false);
} }
} }

View File

@ -18,24 +18,51 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import net.md_5.bungee.BungeeCord; import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.config.ConfigurationAdapter;
public class DomainBlacklist { public class DomainBlacklist {
public static final Collection<Pattern> regexBlacklist = new HashSet(); public static final Collection<Pattern> regexBlacklist = new ArrayList();
public static final Collection<Pattern> regexLocalBlacklist = new HashSet(); public static final Collection<Pattern> regexLocalBlacklist = new ArrayList();
public static final Collection<Pattern> regexBlacklistReplit = new ArrayList();
public static final File localBlacklist = new File("origin_blacklist.txt"); public static final File localBlacklist = new File("origin_blacklist.txt");
private static Collection<String> blacklistSubscriptions = null;
private static boolean blockOfflineDownload = false;
private static boolean blockAllReplits = false;
private static final HashSet<String> brokenURLs = new HashSet(); private static final HashSet<String> brokenURLs = new HashSet();
private static final HashSet<String> brokenRegex = new HashSet(); private static final HashSet<String> brokenRegex = new HashSet();
public static final HashSet<String> regexBlacklistReplitInternalStrings = new HashSet();
public static final Collection<Pattern> regexBlacklistReplitInternal = new ArrayList();
static {
regexBlacklistReplitInternalStrings.add(".*repl(it)?\\..{1,5}$");
for(String s : regexBlacklistReplitInternalStrings) {
regexBlacklistReplitInternal.add(Pattern.compile(s));
}
}
private static int updateRate = 15 * 60 * 1000; private static int updateRate = 15 * 60 * 1000;
private static long lastLocalUpdate = 0l; private static long lastLocalUpdate = 0l;
private static long lastUpdate = 0; private static long lastUpdate = 0;
public static boolean test(String origin) { public static boolean test(String origin) {
synchronized(regexBlacklist) { synchronized(regexBlacklist) {
if(origin.equalsIgnoreCase("null") && BungeeCord.getInstance().getConfigurationAdapter().getBlacklistOfflineDownload()) { if(blockOfflineDownload && origin.equalsIgnoreCase("null")) {
return true; return true;
} }
if(blockAllReplits) {
for(Pattern m : regexBlacklistReplitInternal) {
if(m.matcher(origin).matches()) {
return true;
}
}
for(Pattern m : regexBlacklistReplit) {
if(m.matcher(origin).matches()) {
return true;
}
}
}
for(Pattern m : regexBlacklist) { for(Pattern m : regexBlacklist) {
if(m.matcher(origin).matches()) { if(m.matcher(origin).matches()) {
return true; return true;
@ -50,12 +77,17 @@ public class DomainBlacklist {
return false; return false;
} }
public static void init() { public static void init(BungeeCord bg) {
synchronized(regexBlacklist) { synchronized(regexBlacklist) {
brokenURLs.clear(); brokenURLs.clear();
brokenRegex.clear(); brokenRegex.clear();
regexBlacklist.clear(); regexBlacklist.clear();
regexLocalBlacklist.clear(); regexLocalBlacklist.clear();
regexBlacklistReplit.clear();
ConfigurationAdapter cfg = bg.getConfigurationAdapter();
blacklistSubscriptions = cfg.getBlacklistURLs();
blockOfflineDownload = cfg.getBlacklistOfflineDownload();
blockAllReplits = cfg.getBlacklistReplits();
lastLocalUpdate = 0l; lastLocalUpdate = 0l;
lastUpdate = System.currentTimeMillis() - updateRate - 1000l; lastUpdate = System.currentTimeMillis() - updateRate - 1000l;
update(); update();
@ -67,11 +99,12 @@ public class DomainBlacklist {
if((int)(ct - lastUpdate) > updateRate) { if((int)(ct - lastUpdate) > updateRate) {
lastUpdate = ct; lastUpdate = ct;
synchronized(regexBlacklist) { synchronized(regexBlacklist) {
Collection<String> blurls = BungeeCord.getInstance().getConfigurationAdapter().getBlacklistURLs(); if(blacklistSubscriptions != null) {
if(blurls != null) {
ArrayList<Pattern> newBlacklist = new ArrayList(); ArrayList<Pattern> newBlacklist = new ArrayList();
ArrayList<Pattern> newReplitBlacklist = new ArrayList();
HashSet<String> newBlacklistSet = new HashSet(); HashSet<String> newBlacklistSet = new HashSet();
for(String str : blurls) { newBlacklistSet.addAll(regexBlacklistReplitInternalStrings);
for(String str : blacklistSubscriptions) {
try { try {
URL u; URL u;
try { try {
@ -103,6 +136,21 @@ public class DomainBlacklist {
while((ss = is.readLine()) != null) { while((ss = is.readLine()) != null) {
if((ss = ss.trim()).length() > 0) { if((ss = ss.trim()).length() > 0) {
if(ss.startsWith("#")) { if(ss.startsWith("#")) {
ss = ss.substring(1).trim();
if(ss.startsWith("replit-wildcard:")) {
ss = ss.substring(16).trim();
if(newBlacklistSet.add(ss)) {
try {
newReplitBlacklist.add(Pattern.compile(ss));
}catch(PatternSyntaxException shit) {
if(brokenRegex.add(ss)) {
System.err.println("ERROR: the blacklist replit wildcard regex '" + ss + "' is invalid");
continue;
}
}
brokenRegex.remove(ss);
}
}
continue; continue;
} }
if(newBlacklistSet.add(ss)) { if(newBlacklistSet.add(ss)) {
@ -131,11 +179,14 @@ public class DomainBlacklist {
regexBlacklist.clear(); regexBlacklist.clear();
regexBlacklist.addAll(newBlacklist); regexBlacklist.addAll(newBlacklist);
} }
if(!newReplitBlacklist.isEmpty()) {
regexBlacklistReplit.clear();
regexBlacklistReplit.addAll(newReplitBlacklist);
}
}else { }else {
brokenURLs.clear(); brokenURLs.clear();
brokenRegex.clear(); brokenRegex.clear();
regexBlacklist.clear(); regexBlacklist.clear();
regexLocalBlacklist.clear();
lastLocalUpdate = 0l; lastLocalUpdate = 0l;
} }
} }

View File

@ -43,6 +43,7 @@ public class WebSocketListener extends WebSocketServer {
private InetSocketAddress bungeeProxy; private InetSocketAddress bungeeProxy;
private ProxyServer bungeeCord; private ProxyServer bungeeCord;
private boolean blockOriginless;
private ListenerInfo info; private ListenerInfo info;
private final WebSocketRateLimiter ratelimitIP; private final WebSocketRateLimiter ratelimitIP;
private final WebSocketRateLimiter ratelimitLogin; private final WebSocketRateLimiter ratelimitLogin;
@ -57,6 +58,7 @@ public class WebSocketListener extends WebSocketServer {
this.info = info; this.info = info;
this.bungeeProxy = sock; this.bungeeProxy = sock;
this.bungeeCord = bungeeCord; this.bungeeCord = bungeeCord;
this.blockOriginless = bungeeCord.getConfigurationAdapter().getBlacklistOriginless();
this.ratelimitIP = info.getRateLimitIP(); this.ratelimitIP = info.getRateLimitIP();
this.ratelimitLogin = info.getRateLimitLogin(); this.ratelimitLogin = info.getRateLimitLogin();
this.ratelimitMOTD = info.getRateLimitMOTD(); this.ratelimitMOTD = info.getRateLimitMOTD();
@ -220,12 +222,24 @@ public class WebSocketListener extends WebSocketServer {
if(idx != -1) { if(idx != -1) {
origin = origin.substring(idx + 3); origin = origin.substring(idx + 3);
} }
origin = origin.trim(); origin = origin.trim().toLowerCase();
if(DomainBlacklist.test(origin)) { if(DomainBlacklist.test(origin)) {
arg0.send(createRawKickPacket("End of Stream (RIP)")); arg0.send(createRawKickPacket("End of Stream"));
arg0.close(); arg0.close();
return; return;
} }
}else {
if(blockOriginless) {
arg0.send(createRawKickPacket("End of Stream"));
arg0.close();
return;
}
}
String ua = arg1.getFieldValue("User-Agent");
if(blockOriginless && (ua == null || (ua = ua.toLowerCase()).contains("java-websocket") || ua.contains("tootallnate") || ua.contains("eaglercraft"))) {
arg0.send(createRawKickPacket("End of Stream"));
arg0.close();
return;
} }
InetAddress addr; InetAddress addr;
if(info.hasForwardedHeaders()) { if(info.hasForwardedHeaders()) {

View File

@ -61,6 +61,7 @@ permissions:
default: default:
- bungeecord.command.server - bungeecord.command.server
- bungeecord.command.list - bungeecord.command.list
- bungeecord.command.eag.domain
admin: admin:
- bungeecord.command.alert - bungeecord.command.alert
- bungeecord.command.end - bungeecord.command.end
@ -75,4 +76,7 @@ permissions:
- bungeecord.command.eag.banlist - bungeecord.command.eag.banlist
- bungeecord.command.eag.unban - bungeecord.command.eag.unban
- bungeecord.command.eag.ratelimit - bungeecord.command.eag.ratelimit
- bungeecord.command.eag.blockdomain
- bungeecord.command.eag.blockdomainname
- bungeecord.command.eag.unblockdomain
groups: {} groups: {}

View File

@ -8,6 +8,8 @@
.*qwasz.* .*qwasz.*
.*x.?ray.* .*x.?ray.*
# replit-wildcard: .*repl(it)?\..{1,5}$
# ayuncraft has not been removed because ayunami is removing the flyhack # ayuncraft has not been removed because ayunami is removing the flyhack
# snitch other domains out at https://g.eags.us/eaglercraft/report.html # snitch other domains out at https://g.eags.us/eaglercraft/report.html