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);
}
}, 0L, TimeUnit.SECONDS.toMillis(3L));
DomainBlacklist.init();
DomainBlacklist.init(this);
this.closeInactiveSockets.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {

View file

@ -25,9 +25,13 @@ public interface ConfigurationAdapter {
Collection<String> getPermissions(final String p0);
Collection<String> getBlacklistURLs();
boolean getBlacklistOfflineDownload();
boolean getBlacklistReplits();
boolean getBlacklistOriginless();
AuthServiceInfo getAuthSettings();
Map<String, Object> getMap();

View file

@ -291,7 +291,7 @@ public class YamlConfig implements ConfigurationAdapter {
@Override
public Collection<String> getBlacklistURLs() {
boolean blacklistEnable = this.getBoolean("enable_origin_blacklist", true);
boolean blacklistEnable = this.getBoolean("enable_web_origin_blacklist", true);
if(!blacklistEnable) {
return null;
}
@ -307,7 +307,17 @@ public class YamlConfig implements ConfigurationAdapter {
@Override
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 net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.config.ConfigurationAdapter;
public class DomainBlacklist {
public static final Collection<Pattern> regexBlacklist = new HashSet();
public static final Collection<Pattern> regexLocalBlacklist = new HashSet();
public static final Collection<Pattern> regexBlacklist = new ArrayList();
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");
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> 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 long lastLocalUpdate = 0l;
private static long lastUpdate = 0;
public static boolean test(String origin) {
synchronized(regexBlacklist) {
if(origin.equalsIgnoreCase("null") && BungeeCord.getInstance().getConfigurationAdapter().getBlacklistOfflineDownload()) {
if(blockOfflineDownload && origin.equalsIgnoreCase("null")) {
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) {
if(m.matcher(origin).matches()) {
return true;
@ -50,12 +77,17 @@ public class DomainBlacklist {
return false;
}
public static void init() {
public static void init(BungeeCord bg) {
synchronized(regexBlacklist) {
brokenURLs.clear();
brokenRegex.clear();
regexBlacklist.clear();
regexLocalBlacklist.clear();
regexBlacklistReplit.clear();
ConfigurationAdapter cfg = bg.getConfigurationAdapter();
blacklistSubscriptions = cfg.getBlacklistURLs();
blockOfflineDownload = cfg.getBlacklistOfflineDownload();
blockAllReplits = cfg.getBlacklistReplits();
lastLocalUpdate = 0l;
lastUpdate = System.currentTimeMillis() - updateRate - 1000l;
update();
@ -67,11 +99,12 @@ public class DomainBlacklist {
if((int)(ct - lastUpdate) > updateRate) {
lastUpdate = ct;
synchronized(regexBlacklist) {
Collection<String> blurls = BungeeCord.getInstance().getConfigurationAdapter().getBlacklistURLs();
if(blurls != null) {
if(blacklistSubscriptions != null) {
ArrayList<Pattern> newBlacklist = new ArrayList();
ArrayList<Pattern> newReplitBlacklist = new ArrayList();
HashSet<String> newBlacklistSet = new HashSet();
for(String str : blurls) {
newBlacklistSet.addAll(regexBlacklistReplitInternalStrings);
for(String str : blacklistSubscriptions) {
try {
URL u;
try {
@ -103,6 +136,21 @@ public class DomainBlacklist {
while((ss = is.readLine()) != null) {
if((ss = ss.trim()).length() > 0) {
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;
}
if(newBlacklistSet.add(ss)) {
@ -131,11 +179,14 @@ public class DomainBlacklist {
regexBlacklist.clear();
regexBlacklist.addAll(newBlacklist);
}
if(!newReplitBlacklist.isEmpty()) {
regexBlacklistReplit.clear();
regexBlacklistReplit.addAll(newReplitBlacklist);
}
}else {
brokenURLs.clear();
brokenRegex.clear();
regexBlacklist.clear();
regexLocalBlacklist.clear();
lastLocalUpdate = 0l;
}
}

View file

@ -43,6 +43,7 @@ public class WebSocketListener extends WebSocketServer {
private InetSocketAddress bungeeProxy;
private ProxyServer bungeeCord;
private boolean blockOriginless;
private ListenerInfo info;
private final WebSocketRateLimiter ratelimitIP;
private final WebSocketRateLimiter ratelimitLogin;
@ -57,6 +58,7 @@ public class WebSocketListener extends WebSocketServer {
this.info = info;
this.bungeeProxy = sock;
this.bungeeCord = bungeeCord;
this.blockOriginless = bungeeCord.getConfigurationAdapter().getBlacklistOriginless();
this.ratelimitIP = info.getRateLimitIP();
this.ratelimitLogin = info.getRateLimitLogin();
this.ratelimitMOTD = info.getRateLimitMOTD();
@ -220,12 +222,24 @@ public class WebSocketListener extends WebSocketServer {
if(idx != -1) {
origin = origin.substring(idx + 3);
}
origin = origin.trim();
origin = origin.trim().toLowerCase();
if(DomainBlacklist.test(origin)) {
arg0.send(createRawKickPacket("End of Stream (RIP)"));
arg0.send(createRawKickPacket("End of Stream"));
arg0.close();
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;
if(info.hasForwardedHeaders()) {

View file

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

View file

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