Ip filtering: Use settings file instead of own configuration
This will allow in the future to make this a dynamic setting, which can also be shared accress the cluster instead of having to use (and distribute) files. Another change is, that the order of `deny` and `allow` now does not matter anymore. Allow will win over deny. The last change is that `all` now is `_all` in order to align with the rest of Elasticsearch Documentation has been updated accordingly. Original commit: elastic/x-pack-elasticsearch@daa0b18343
This commit is contained in:
parent
b31beb1e36
commit
f1e5de40f5
|
@ -56,7 +56,7 @@ public class SecuredTransportModule extends AbstractShieldModule.Spawn implement
|
|||
|
||||
bind(ServerTransportFilter.class).to(ServerTransportFilter.Node.class).asEagerSingleton();
|
||||
bind(ClientTransportFilter.class).to(ClientTransportFilter.Node.class).asEagerSingleton();
|
||||
if (settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true)) {
|
||||
if (settings.getAsBoolean("shield.transport.filter.enabled", true)) {
|
||||
bind(IPFilteringN2NAuthenticator.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,113 +7,72 @@ package org.elasticsearch.shield.transport.n2n;
|
|||
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.jackson.dataformat.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.net.InetAddresses;
|
||||
import org.elasticsearch.common.netty.handler.ipfilter.IpFilterRule;
|
||||
import org.elasticsearch.common.netty.handler.ipfilter.IpSubnetFilterRule;
|
||||
import org.elasticsearch.common.netty.handler.ipfilter.PatternRule;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.shield.ShieldPlugin;
|
||||
import org.elasticsearch.watcher.FileChangesListener;
|
||||
import org.elasticsearch.watcher.FileWatcher;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class IPFilteringN2NAuthenticator extends AbstractComponent implements N2NAuthenticator {
|
||||
|
||||
private static final Pattern COMMA_DELIM = Pattern.compile("\\s*,\\s*");
|
||||
private static final String DEFAULT_FILE = "ip_filter.yml";
|
||||
private static final ProfileIpFilterRule[] NO_RULES = new ProfileIpFilterRule[0];
|
||||
|
||||
private final Path file;
|
||||
|
||||
private volatile ProfileIpFilterRule[] rules = NO_RULES;
|
||||
|
||||
@Inject
|
||||
public IPFilteringN2NAuthenticator(Settings settings, Environment env, ResourceWatcherService watcherService) {
|
||||
public IPFilteringN2NAuthenticator(Settings settings) {
|
||||
super(settings);
|
||||
file = resolveFile(componentSettings, env);
|
||||
rules = parseFile(file, logger);
|
||||
FileWatcher watcher = new FileWatcher(file.getParent().toFile());
|
||||
watcher.addListener(new FileListener());
|
||||
watcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
parseSettings();
|
||||
}
|
||||
|
||||
private Path resolveFile(Settings settings, Environment env) {
|
||||
String location = settings.get("ip_filter.file");
|
||||
if (location == null) {
|
||||
return ShieldPlugin.resolveConfigFile(env, DEFAULT_FILE);
|
||||
}
|
||||
return Paths.get(location);
|
||||
}
|
||||
|
||||
public static ProfileIpFilterRule[] parseFile(Path path, ESLogger logger) {
|
||||
if (!Files.exists(path)) {
|
||||
return NO_RULES;
|
||||
}
|
||||
|
||||
private void parseSettings() {
|
||||
String[] allowed = settings.getAsArray("shield.transport.filter.allow");
|
||||
String[] denied = settings.getAsArray("shield.transport.filter.deny");
|
||||
List<ProfileIpFilterRule> rules = new ArrayList<>();
|
||||
|
||||
try (XContentParser parser = YamlXContent.yamlXContent.createParser(Files.newInputStream(path))) {
|
||||
XContentParser.Token token;
|
||||
String currentFieldName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT && token != null) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
if (!currentFieldName.endsWith("allow") && !currentFieldName.endsWith("deny")) {
|
||||
throw new ElasticsearchParseException("Field name [" + currentFieldName + "] not valid. Must be [allow] or [deny] or using a profile");
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_STRING && currentFieldName != null) {
|
||||
String value = parser.text();
|
||||
if (!Strings.hasLength(value)) {
|
||||
throw new ElasticsearchParseException("Field value for fieldname [" + currentFieldName + "] must not be empty");
|
||||
}
|
||||
try {
|
||||
rules.addAll(parseValue(allowed, "default", true));
|
||||
rules.addAll(parseValue(denied, "default", false));
|
||||
|
||||
boolean isAllowRule = currentFieldName.endsWith("allow");
|
||||
String profile = currentFieldName.contains(".") ? currentFieldName.substring(0, currentFieldName.indexOf(".")) : "default";
|
||||
|
||||
if (value.contains(",")) {
|
||||
for (String rule : COMMA_DELIM.split(parser.text().trim())) {
|
||||
rules.add(new ProfileIpFilterRule(profile, getRule(isAllowRule, rule)));
|
||||
}
|
||||
} else {
|
||||
rules.add(new ProfileIpFilterRule(profile, getRule(isAllowRule, value)));
|
||||
}
|
||||
|
||||
}
|
||||
Map<String, Settings> groupedSettings = settings.getGroups("transport.profiles.");
|
||||
for (Map.Entry<String, Settings> entry : groupedSettings.entrySet()) {
|
||||
String profile = entry.getKey();
|
||||
Settings settings = entry.getValue().getByPrefix("shield.filter.");
|
||||
rules.addAll(parseValue(settings.getAsArray("allow"), profile, true));
|
||||
rules.addAll(parseValue(settings.getAsArray("deny"), profile, false));
|
||||
}
|
||||
} catch (IOException | YAMLException e) {
|
||||
throw new ElasticsearchParseException("Failed to read & parse host access file [" + path.toAbsolutePath() + "]", e);
|
||||
}
|
||||
|
||||
if (rules.size() == 0) {
|
||||
return NO_RULES;
|
||||
} catch (IOException | YAMLException e) {
|
||||
throw new ElasticsearchParseException("Failed to read & parse rules from settings", e);
|
||||
}
|
||||
|
||||
logger.debug("Loaded {} ip filtering rules", rules.size());
|
||||
return rules.toArray(new ProfileIpFilterRule[rules.size()]);
|
||||
this.rules = rules.toArray(new ProfileIpFilterRule[rules.size()]);
|
||||
}
|
||||
|
||||
private Collection<? extends ProfileIpFilterRule> parseValue(String[] values, String profile, boolean isAllowRule) throws UnknownHostException {
|
||||
List<ProfileIpFilterRule> rules = new ArrayList<>();
|
||||
for (String value : values) {
|
||||
rules.add(new ProfileIpFilterRule(profile, getRule(isAllowRule, value)));
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
private static IpFilterRule getRule(boolean isAllowRule, String value) throws UnknownHostException {
|
||||
if ("all".equals(value)) {
|
||||
if ("_all".equals(value)) {
|
||||
return new PatternRule(isAllowRule, "n:*");
|
||||
} else if (value.contains("/")) {
|
||||
return new IpSubnetFilterRule(isAllowRule, value);
|
||||
|
@ -137,27 +96,4 @@ public class IPFilteringN2NAuthenticator extends AbstractComponent implements N2
|
|||
logger.trace("Allowing host {}", peerAddress);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class FileListener extends FileChangesListener {
|
||||
@Override
|
||||
public void onFileCreated(File file) {
|
||||
if (file.equals(IPFilteringN2NAuthenticator.this.file.toFile())) {
|
||||
rules = parseFile(file.toPath(), logger);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileDeleted(File file) {
|
||||
if (file.equals(IPFilteringN2NAuthenticator.this.file.toFile())) {
|
||||
rules = NO_RULES;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileChanged(File file) {
|
||||
if (file.equals(IPFilteringN2NAuthenticator.this.file.toFile())) {
|
||||
rules = parseFile(file.toPath(), logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class NettySecuredHttpServerTransport extends NettyHttpServerTransport {
|
|||
this.ssl = settings.getAsBoolean("shield.http.ssl", false);
|
||||
this.sslService = sslService;
|
||||
assert !ssl || sslService != null : "ssl is enabled yet the ssl service is null";
|
||||
this.ipFilterEnabled = settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true);
|
||||
this.ipFilterEnabled = settings.getAsBoolean("shield.transport.filter.enabled", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,7 +36,7 @@ public class NettySecuredTransport extends NettyTransport {
|
|||
@Nullable IPFilteringN2NAuthenticator authenticator, @Nullable SSLService sslService) {
|
||||
super(settings, threadPool, networkService, bigArrays, version);
|
||||
this.authenticator = authenticator;
|
||||
this.ipFilterEnabled = settings.getAsBoolean("shield.transport.n2n.ip_filter.enabled", true);
|
||||
this.ipFilterEnabled = settings.getAsBoolean("shield.transport.filter.enabled", true);
|
||||
this.sslService = sslService;
|
||||
this.ssl = settings.getAsBoolean("shield.transport.ssl", false);
|
||||
assert !ssl || sslService != null : "ssl is enabled yet the ssl service is null";
|
||||
|
|
|
@ -19,8 +19,8 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.plugins.PluginsService;
|
||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||
import org.elasticsearch.shield.ShieldPlugin;
|
||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||
import org.elasticsearch.shield.transport.netty.NettySecuredTransport;
|
||||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
|
@ -54,7 +54,6 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest
|
|||
protected static final String DEFAULT_TRANSPORT_CLIENT_ROLE = "trans_client_user";
|
||||
protected static final String DEFAULT_TRANSPORT_CLIENT_USER_NAME = "test_trans_client_user";
|
||||
|
||||
public static final String CONFIG_IPFILTER_ALLOW_ALL = "allow: all\n";
|
||||
public static final String CONFIG_STANDARD_USER =
|
||||
DEFAULT_USER_NAME + ":{plain}" + DEFAULT_PASSWORD + "\n" +
|
||||
DEFAULT_TRANSPORT_CLIENT_USER_NAME + ":{plain}" + DEFAULT_PASSWORD + "\n";
|
||||
|
@ -88,7 +87,6 @@ public abstract class ShieldIntegrationTest extends ElasticsearchIntegrationTest
|
|||
.put("shield.authc.esusers.files.users", writeFile(folder, "users", configUsers()))
|
||||
.put("shield.authc.esusers.files.users_roles", writeFile(folder, "users_roles", configUsersRoles()))
|
||||
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", configRole()))
|
||||
.put("shield.transport.n2n.ip_filter.file", writeFile(folder, "ip_filter.yml", CONFIG_IPFILTER_ALLOW_ALL))
|
||||
.put(getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks", "testnode"))
|
||||
.put("shield.audit.enabled", true)
|
||||
.put("plugins.load_classpath_plugins", false);
|
||||
|
|
|
@ -5,24 +5,13 @@
|
|||
*/
|
||||
package org.elasticsearch.shield.transport.n2n;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.base.Charsets;
|
||||
import org.elasticsearch.common.net.InetAddresses;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.elasticsearch.test.junit.annotations.Network;
|
||||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -41,31 +30,15 @@ public class IPFilteringN2NAuthenticatorTests extends ElasticsearchTestCase {
|
|||
}
|
||||
};
|
||||
|
||||
private final Settings resourceWatcherServiceSettings = settingsBuilder()
|
||||
.put("watcher.interval.high", TimeValue.timeValueMillis(200))
|
||||
.build();
|
||||
|
||||
private ResourceWatcherService resourceWatcherService;
|
||||
private File configFile;
|
||||
private IPFilteringN2NAuthenticator ipFilteringN2NAuthenticator;
|
||||
private ThreadPool threadPool;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
configFile = newTempFile();
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdown() {
|
||||
resourceWatcherService.stop();
|
||||
if (threadPool != null) {
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatIpV4AddressesCanBeProcessed() throws Exception {
|
||||
writeConfigFile("allow: 127.0.0.1\ndeny: 10.0.0.0/8");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "127.0.0.1")
|
||||
.put("shield.transport.filter.deny", "10.0.0.0/8")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
assertAddressIsDenied("10.2.3.4");
|
||||
|
@ -75,7 +48,11 @@ public class IPFilteringN2NAuthenticatorTests extends ElasticsearchTestCase {
|
|||
public void testThatIpV6AddressesCanBeProcessed() throws Exception {
|
||||
// you have to use the shortest possible notation in order to match, so
|
||||
// 1234:0db8:85a3:0000:0000:8a2e:0370:7334 becomes 1234:db8:85a3:0:0:8a2e:370:7334
|
||||
writeConfigFile("allow: 2001:0db8:1234::/48\ndeny: 1234:db8:85a3:0:0:8a2e:370:7334\ndeny: 4321:db8:1234::/48");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "2001:0db8:1234::/48")
|
||||
.putArray("shield.transport.filter.deny", "1234:db8:85a3:0:0:8a2e:370:7334", "4321:db8:1234::/48")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
assertAddressIsAllowed("2001:0db8:1234:0000:0000:8a2e:0370:7334");
|
||||
assertAddressIsDenied("1234:0db8:85a3:0000:0000:8a2e:0370:7334");
|
||||
|
@ -85,67 +62,36 @@ public class IPFilteringN2NAuthenticatorTests extends ElasticsearchTestCase {
|
|||
@Test
|
||||
@Network // requires network for name resolution
|
||||
public void testThatHostnamesCanBeProcessed() throws Exception {
|
||||
writeConfigFile("allow: localhost\ndeny: '*.google.com'");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "127.0.0.1")
|
||||
.put("shield.transport.filter.deny", "*.google.com")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
assertAddressIsDenied("8.8.8.8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatFileDeletionResultsInAllowingAll() throws Exception {
|
||||
writeConfigFile("deny: 127.0.0.1");
|
||||
|
||||
assertAddressIsDenied("127.0.0.1");
|
||||
|
||||
configFile.delete();
|
||||
assertThat(configFile.exists(), is(false));
|
||||
|
||||
sleep(250);
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatAnAllowAllAuthenticatorWorks() throws Exception {
|
||||
writeConfigFile("allow: all");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "_all")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
assertAddressIsAllowed("173.194.70.100");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatCommaSeparatedValuesWork() throws Exception {
|
||||
writeConfigFile("allow: 192.168.23.0/24, localhost\ndeny: all");
|
||||
|
||||
assertAddressIsAllowed("192.168.23.1");
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
assertAddressIsDenied("10.1.2.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatOrderIsImportant() throws Exception {
|
||||
writeConfigFile("deny: localhost\nallow: localhost");
|
||||
|
||||
assertAddressIsDenied("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatOrderIsImportantViceVersa() throws Exception {
|
||||
writeConfigFile("allow: localhost\ndeny: localhost");
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatEmptyFileDoesNotLeadIntoLoop() throws Exception {
|
||||
writeConfigFile("# \n\n");
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestLogging("_root:TRACE")
|
||||
public void testThatProfilesAreSupported() throws Exception {
|
||||
writeConfigFile("allow: localhost\ndeny: all\nclient.allow: 192.168.0.1\nclient.deny: all");
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "localhost")
|
||||
.put("shield.transport.filter.deny", "_all")
|
||||
.put("transport.profiles.client.shield.filter.allow", "192.168.0.1")
|
||||
.put("transport.profiles.client.shield.filter.deny", "_all")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
assertAddressIsAllowed("127.0.0.1");
|
||||
assertAddressIsDenied("192.168.0.1");
|
||||
|
@ -153,18 +99,16 @@ public class IPFilteringN2NAuthenticatorTests extends ElasticsearchTestCase {
|
|||
assertAddressIsDeniedForProfile("client", "192.168.0.2");
|
||||
}
|
||||
|
||||
@Test(expected = ElasticsearchParseException.class)
|
||||
public void testThatInvalidFileThrowsCorrectException() throws Exception {
|
||||
writeConfigFile("deny: all allow: all \n\n");
|
||||
IPFilteringN2NAuthenticator.parseFile(configFile.toPath(), logger);
|
||||
}
|
||||
@Test
|
||||
public void testThatAllowWinsOverDeny() throws Exception {
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "10.0.0.1")
|
||||
.put("shield.transport.filter.deny", "10.0.0.0/8")
|
||||
.build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
private void writeConfigFile(String data) throws IOException {
|
||||
Files.write(data.getBytes(Charsets.UTF_8), configFile);
|
||||
threadPool = new ThreadPool("resourceWatcher");
|
||||
resourceWatcherService = new ResourceWatcherService(resourceWatcherServiceSettings, threadPool).start();
|
||||
Settings settings = settingsBuilder().put("shield.transport.n2n.ip_filter.file", configFile.getPath()).build();
|
||||
ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings, new Environment(), resourceWatcherService);
|
||||
assertAddressIsAllowed("10.0.0.1");
|
||||
assertAddressIsDenied("10.0.0.2");
|
||||
}
|
||||
|
||||
private void assertAddressIsAllowedForProfile(String profile, String ... inetAddresses) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
package org.elasticsearch.shield.transport.n2n;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
|
@ -16,7 +15,6 @@ import org.elasticsearch.shield.test.ShieldIntegrationTest;
|
|||
import org.elasticsearch.transport.Transport;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
|
@ -33,17 +31,13 @@ import static org.hamcrest.Matchers.is;
|
|||
@ClusterScope(scope = Scope.SUITE, numDataNodes = 1, numClientNodes = 0, transportClientRatio = 0.0)
|
||||
public class IpFilteringIntegrationTests extends ShieldIntegrationTest {
|
||||
|
||||
private static final String CONFIG_IPFILTER_DENY_ALL = "deny: all\n";
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
ImmutableSettings.Builder builder = settingsBuilder().put(super.nodeSettings(nodeOrdinal));
|
||||
builder.put(InternalNode.HTTP_ENABLED, true);
|
||||
|
||||
File folder = newFolder();
|
||||
builder.put("shield.transport.n2n.ip_filter.file", writeFile(folder, "ip_filter.yml", CONFIG_IPFILTER_DENY_ALL));
|
||||
|
||||
return builder.build();
|
||||
return settingsBuilder()
|
||||
.put(super.nodeSettings(nodeOrdinal))
|
||||
.put(InternalNode.HTTP_ENABLED, true)
|
||||
.put("shield.transport.filter.deny", "_all")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = SocketException.class)
|
||||
|
|
|
@ -5,22 +5,14 @@
|
|||
*/
|
||||
package org.elasticsearch.shield.transport.netty;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import org.elasticsearch.common.netty.channel.*;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.shield.transport.n2n.IPFilteringN2NAuthenticator;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
|
@ -33,28 +25,19 @@ import static org.hamcrest.Matchers.is;
|
|||
public class N2NNettyUpstreamHandlerTests extends ElasticsearchTestCase {
|
||||
|
||||
private N2NNettyUpstreamHandler nettyUpstreamHandler;
|
||||
private ThreadPool threadPool;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
File configFile = newTempFile();
|
||||
threadPool = new ThreadPool("resourceWatcher");
|
||||
ResourceWatcherService resourceWatcherService = new ResourceWatcherService(ImmutableSettings.EMPTY, threadPool).start();
|
||||
Settings settings = settingsBuilder()
|
||||
.put("shield.transport.filter.allow", "127.0.0.1")
|
||||
.put("shield.transport.filter.deny", "10.0.0.0/8")
|
||||
.build();
|
||||
|
||||
String testData = "allow: 127.0.0.1\ndeny: 10.0.0.0/8";
|
||||
Files.write(testData.getBytes(Charsets.UTF_8), configFile);
|
||||
|
||||
Settings settings = settingsBuilder().put("shield.transport.n2n.ip_filter.file", configFile.getPath()).build();
|
||||
IPFilteringN2NAuthenticator ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings, new Environment(), resourceWatcherService);
|
||||
IPFilteringN2NAuthenticator ipFilteringN2NAuthenticator = new IPFilteringN2NAuthenticator(settings);
|
||||
|
||||
nettyUpstreamHandler = new N2NNettyUpstreamHandler(ipFilteringN2NAuthenticator, "default");
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdownThreadPool() {
|
||||
threadPool.shutdownNow();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatFilteringWorksByIp() throws Exception {
|
||||
InetSocketAddress localhostAddr = new InetSocketAddress(InetAddresses.forString("127.0.0.1"), 12345);
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
package org.elasticsearch.shield.transport.ssl;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.transport.NoNodeAvailableException;
|
||||
import org.elasticsearch.client.transport.TransportClient;
|
||||
|
@ -24,10 +22,7 @@ import org.elasticsearch.node.internal.InternalNode;
|
|||
import org.elasticsearch.plugins.PluginsService;
|
||||
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.shield.test.ShieldIntegrationTest;
|
||||
import org.elasticsearch.shield.transport.SecuredTransportService;
|
||||
import org.elasticsearch.shield.transport.netty.NettySecuredTransport;
|
||||
import org.elasticsearch.transport.Transport;
|
||||
import org.elasticsearch.transport.TransportModule;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
|
@ -39,7 +34,6 @@ import java.util.Locale;
|
|||
|
||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||
import static org.elasticsearch.shield.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class SslIntegrationTests extends ShieldIntegrationTest {
|
||||
|
@ -136,7 +130,6 @@ public class SslIntegrationTests extends ShieldIntegrationTest {
|
|||
|
||||
.put("request.headers.Authorization", basicAuthHeaderValue(getClientUsername(), getClientPassword()))
|
||||
.put("plugins." + PluginsService.LOAD_PLUGIN_FROM_CLASSPATH, true)
|
||||
.put("shield.transport.n2n.ip_filter.file", writeFile(folder, "ip_filter.yml", ShieldIntegrationTest.CONFIG_IPFILTER_ALLOW_ALL))
|
||||
|
||||
.put(getSSLSettingsForStore("certs/simple/testclient.jks", "testclient"))
|
||||
.build();
|
||||
|
|
|
@ -50,7 +50,6 @@ public class ShieldRestTests extends ElasticsearchRestTests {
|
|||
protected static final String DEFAULT_PASSWORD = "changeme";
|
||||
protected static final String DEFAULT_ROLE = "user";
|
||||
|
||||
public static final String CONFIG_IPFILTER_ALLOW_ALL = "allow: all\n";
|
||||
public static final String CONFIG_STANDARD_USER = DEFAULT_USER_NAME + ":{plain}" + DEFAULT_PASSWORD + "\n";
|
||||
public static final String CONFIG_STANDARD_USER_ROLES = DEFAULT_ROLE + ":" + DEFAULT_USER_NAME+ "\n";
|
||||
public static final String CONFIG_ROLE_ALLOW_ALL =
|
||||
|
@ -108,7 +107,6 @@ public class ShieldRestTests extends ElasticsearchRestTests {
|
|||
.put("shield.authc.esusers.files.users", createFile(folder, "users", CONFIG_STANDARD_USER))
|
||||
.put("shield.authc.esusers.files.users_roles", createFile(folder, "users_roles", CONFIG_STANDARD_USER_ROLES))
|
||||
.put("shield.authz.store.files.roles", createFile(folder, "roles.yml", CONFIG_ROLE_ALLOW_ALL))
|
||||
.put("shield.transport.n2n.ip_filter.file", createFile(folder, "ip_filter.yml", CONFIG_IPFILTER_ALLOW_ALL))
|
||||
.put("shield.transport.ssl", ENABLE_TRANSPORT_SSL)
|
||||
.put("shield.ssl.keystore.path", store.getPath())
|
||||
.put("shield.ssl.keystore.password", password)
|
||||
|
@ -138,14 +136,11 @@ public class ShieldRestTests extends ElasticsearchRestTests {
|
|||
throw new ElasticsearchException("Error reading test client cert", e);
|
||||
}
|
||||
|
||||
File folder = createFolder();
|
||||
|
||||
return ImmutableSettings.builder()
|
||||
.put("request.headers.Authorization", basicAuthHeaderValue(DEFAULT_USER_NAME, SecuredStringTests.build(DEFAULT_PASSWORD)))
|
||||
.put(TransportModule.TRANSPORT_TYPE_KEY, NettySecuredTransport.class.getName())
|
||||
.put("plugins." + PluginsService.LOAD_PLUGIN_FROM_CLASSPATH, false)
|
||||
.put("node.mode", "network")
|
||||
.put("shield.transport.n2n.ip_filter.file", createFile(folder, "ip_filter.yml", CONFIG_IPFILTER_ALLOW_ALL))
|
||||
.put("shield.transport.ssl", ENABLE_TRANSPORT_SSL)
|
||||
.put("shield.ssl.keystore.path", store.getPath())
|
||||
.put("shield.ssl.keystore.password", password)
|
||||
|
|
Loading…
Reference in New Issue