Implemented IP Whitelist

Whitelist allows limiting which IP addresses can view the page.

Affects issues:
- Close #1405
This commit is contained in:
Risto Lahtela 2020-06-19 17:25:02 +03:00
parent c66af02477
commit ca9a5cee93
8 changed files with 43 additions and 10 deletions

View File

@ -30,6 +30,8 @@ import com.djrapitops.plan.exceptions.WebUserAuthException;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.PluginLang;
import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.utilities.logging.ErrorContext;
import com.djrapitops.plan.utilities.logging.ErrorLogger;
@ -44,10 +46,7 @@ import org.apache.commons.text.TextStringBuilder;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
/**
* HttpHandler for WebServer request management.
@ -57,6 +56,7 @@ import java.util.Optional;
@Singleton
public class RequestHandler implements HttpHandler {
private final Locale locale;
private final PlanConfig config;
private final DBSystem dbSystem;
private final Addresses addresses;
@ -66,9 +66,11 @@ public class RequestHandler implements HttpHandler {
private final ErrorLogger errorLogger;
private final PassBruteForceGuard bruteForceGuard;
private List<String> ipWhitelist = null;
@Inject
RequestHandler(
Locale locale,
PlanConfig config,
DBSystem dbSystem,
Addresses addresses,
@ -77,6 +79,7 @@ public class RequestHandler implements HttpHandler {
PluginLogger logger,
ErrorLogger errorLogger
) {
this.locale = locale;
this.config = config;
this.dbSystem = dbSystem;
this.addresses = addresses;
@ -111,6 +114,11 @@ public class RequestHandler implements HttpHandler {
}
public Response getResponse(HttpExchange exchange) {
if (ipWhitelist == null) {
ipWhitelist = config.get(WebserverSettings.IP_WHITELIST)
? config.get(WebserverSettings.WHITELIST)
: Collections.emptyList();
}
String accessor = exchange.getRemoteAddress().getAddress().getHostAddress();
Request request = null;
Response response;
@ -118,6 +126,9 @@ public class RequestHandler implements HttpHandler {
request = buildRequest(exchange);
if (bruteForceGuard.shouldPreventRequest(accessor)) {
response = responseFactory.failedLoginAttempts403();
} else if (!ipWhitelist.isEmpty() && !ipWhitelist.contains(accessor)) {
response = responseFactory.ipWhitelist403(accessor);
logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_IP_WHITELIST_BLOCK, accessor, exchange.getRequestURI().toString()));
} else {
response = responseResolver.getResponse(request);
}

View File

@ -349,6 +349,15 @@ public class ResponseFactory {
.build();
}
public Response ipWhitelist403(String accessor) {
return Response.builder()
.setMimeType(MimeType.HTML)
.setContent("<h1>403 Forbidden</h1>" +
"<p>IP-whitelist enabled, \"" + accessor + "\" is not on the list!</p>")
.setStatus(403)
.build();
}
public Response basicAuth() {
try {
String tips = "<br>- Ensure you have registered a user with <b>/plan register</b><br>"

View File

@ -105,6 +105,8 @@ public class WebServer implements SubSystem {
} else {
logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_PORT_BIND, port));
}
} else if (config.get(WebserverSettings.IP_WHITELIST)) {
logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_IP_WHITELIST));
}
requestHandler.getResponseResolver().registerPages();

View File

@ -44,7 +44,7 @@ public class ConfigReader implements Closeable {
// Indent mode assumes the number of spaces used to indent the file.
// If the first found indent is smaller, that will be used instead.
private int indentMode = 4;
private List<String> unboundComment = new ArrayList<>();
private final List<String> unboundComment = new ArrayList<>();
private int lastDepth = -1;
@ -146,7 +146,7 @@ public class ConfigReader implements Closeable {
// Parse a node "Key: value"
// Can not use StringUtils.split(line, ":", 2) - Relies on 2nd empty String for parent node parsing
String[] keyAndValue = line.split(":", 2);
if (keyAndValue.length <= 1) {
if (keyAndValue.length <= 1 || line.startsWith("- ")) {
return handleMultiline(line);
}
String key = keyAndValue[0].trim();

View File

@ -16,10 +16,9 @@
*/
package com.djrapitops.plan.settings.config.paths;
import com.djrapitops.plan.settings.config.paths.key.BooleanSetting;
import com.djrapitops.plan.settings.config.paths.key.IntegerSetting;
import com.djrapitops.plan.settings.config.paths.key.Setting;
import com.djrapitops.plan.settings.config.paths.key.StringSetting;
import com.djrapitops.plan.settings.config.paths.key.*;
import java.util.List;
/**
* {@link Setting} values that are in "Webserver" section.
@ -37,6 +36,8 @@ public class WebserverSettings {
public static final Setting<String> CERTIFICATE_KEYPASS = new StringSetting("Webserver.Security.SSL_certificate.Key_pass");
public static final Setting<String> CERTIFICATE_STOREPASS = new StringSetting("Webserver.Security.SSL_certificate.Store_pass");
public static final Setting<String> CERTIFICATE_ALIAS = new StringSetting("Webserver.Security.SSL_certificate.Alias");
public static final Setting<Boolean> IP_WHITELIST = new BooleanSetting("Webserver.Security.IP_whitelist");
public static final Setting<List<String>> WHITELIST = new StringListSetting("Webserver.Security.IP_whitelist.Whitelist");
public static final Setting<Boolean> DISABLED = new BooleanSetting("Webserver.Disable_Webserver");
public static final Setting<Boolean> DISABLED_AUTHENTICATION = new BooleanSetting("Webserver.Security.Disable_authentication");
public static final Setting<String> EXTERNAL_LINK = new StringSetting("Webserver.External_Webserver_address");

View File

@ -48,6 +48,8 @@ public enum PluginLang implements Lang {
WEB_SERVER_NOTIFY_USING_PROXY_MODE("WebServer - Notify Using Proxy", "WebServer: Proxy-mode HTTPS enabled, make sure that your reverse-proxy is routing using HTTPS and Plan Alternative_IP.Link points to the Proxy"),
WEB_SERVER_NOTIFY_HTTP_USER_AUTH("WebServer - Notify HTTP User Auth", "WebServer: User Authorization Disabled! (Not secure over HTTP)"),
WEB_SERVER_NOTIFY_HTTPS_USER_AUTH("WebServer - Notify HTTPS User Auth", "WebServer: User Authorization Disabled! (Disabled in config)"),
WEB_SERVER_NOTIFY_IP_WHITELIST("Webserver - Notify IP Whitelist", "Webserver: IP Whitelist is enabled."),
WEB_SERVER_NOTIFY_IP_WHITELIST_BLOCK("Webserver - Notify IP Whitelist Block", "Webserver: ${0} was denied access to '${1}'. (not whitelisted)"),
DISABLED("Disable", "Player Analytics Disabled."),
DISABLED_WEB_SERVER("Disable - WebServer", "Webserver has been disabled."),

View File

@ -56,6 +56,10 @@ Webserver:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CORS:
Allow_origin: "*"
IP_whitelist: false
Whitelist:
- "192.168.0.0"
- "0:0:0:0:0:0:0:1"
Disable_Webserver: false
External_Webserver_address: "https://www.example.address"
# -----------------------------------------------------

View File

@ -61,6 +61,10 @@ Webserver:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CORS:
Allow_origin: "*"
IP_whitelist: false
Whitelist:
- "192.168.0.0"
- "0:0:0:0:0:0:0:1"
Disable_Webserver: false
External_Webserver_address: https://www.example.address
# -----------------------------------------------------