Switch internal security index to ".security-7" (#39422)
This changes the name of the internal security index to ".security-7", but supports indices that were upgraded from earlier versions and use the ".security-6" name. In all cases, both ".security-6" and ".security-7" are considered to be restricted index names regardless of which name is actually in use on the cluster. Backport of: #39337
This commit is contained in:
parent
0c7310936b
commit
30687cbe7f
|
@ -303,7 +303,7 @@ public final class IndicesPermission {
|
||||||
private boolean check(String action, String index) {
|
private boolean check(String action, String index) {
|
||||||
assert index != null;
|
assert index != null;
|
||||||
return check(action) && indexNameMatcher.test(index)
|
return check(action) && indexNameMatcher.test(index)
|
||||||
&& (allowRestrictedIndices || (false == RestrictedIndicesNames.NAMES_SET.contains(index)));
|
&& (allowRestrictedIndices || (false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasQuery() {
|
boolean hasQuery() {
|
||||||
|
@ -338,13 +338,13 @@ public final class IndicesPermission {
|
||||||
final Predicate<String> predicate;
|
final Predicate<String> predicate;
|
||||||
if (restrictedIndices.isEmpty()) {
|
if (restrictedIndices.isEmpty()) {
|
||||||
predicate = indexMatcher(ordinaryIndices)
|
predicate = indexMatcher(ordinaryIndices)
|
||||||
.and(index -> false == RestrictedIndicesNames.NAMES_SET.contains(index));
|
.and(index -> false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index));
|
||||||
} else if (ordinaryIndices.isEmpty()) {
|
} else if (ordinaryIndices.isEmpty()) {
|
||||||
predicate = indexMatcher(restrictedIndices);
|
predicate = indexMatcher(restrictedIndices);
|
||||||
} else {
|
} else {
|
||||||
predicate = indexMatcher(restrictedIndices)
|
predicate = indexMatcher(restrictedIndices)
|
||||||
.or(indexMatcher(ordinaryIndices)
|
.or(indexMatcher(ordinaryIndices)
|
||||||
.and(index -> false == RestrictedIndicesNames.NAMES_SET.contains(index)));
|
.and(index -> false == RestrictedIndicesNames.RESTRICTED_NAMES.contains(index)));
|
||||||
}
|
}
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,18 +9,19 @@ package org.elasticsearch.xpack.core.security.index;
|
||||||
import org.apache.lucene.util.automaton.Automaton;
|
import org.apache.lucene.util.automaton.Automaton;
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
import org.elasticsearch.common.util.set.Sets;
|
||||||
import org.elasticsearch.xpack.core.security.support.Automatons;
|
import org.elasticsearch.xpack.core.security.support.Automatons;
|
||||||
import org.elasticsearch.xpack.core.upgrade.IndexUpgradeCheckVersion;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class RestrictedIndicesNames {
|
public final class RestrictedIndicesNames {
|
||||||
public static final String AUDIT_INDEX_NAME_PREFIX = ".security_audit_log";
|
public static final String INTERNAL_SECURITY_INDEX_6 = ".security-6";
|
||||||
public static final String INTERNAL_SECURITY_INDEX = ".security-" + IndexUpgradeCheckVersion.UPRADE_VERSION;
|
public static final String INTERNAL_SECURITY_INDEX_7 = ".security-7";
|
||||||
public static final String SECURITY_INDEX_NAME = ".security";
|
public static final String SECURITY_INDEX_NAME = ".security";
|
||||||
|
|
||||||
public static final Set<String> NAMES_SET = Collections.unmodifiableSet(Sets.newHashSet(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX));
|
public static final Set<String> RESTRICTED_NAMES = Collections.unmodifiableSet(
|
||||||
public static final Automaton NAMES_AUTOMATON = Automatons.patterns(NAMES_SET);
|
Sets.newHashSet(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX_6, INTERNAL_SECURITY_INDEX_7));
|
||||||
|
|
||||||
|
public static final Automaton NAMES_AUTOMATON = Automatons.patterns(RESTRICTED_NAMES);
|
||||||
|
|
||||||
private RestrictedIndicesNames() {
|
private RestrictedIndicesNames() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,12 +225,14 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
|
|
||||||
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
|
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
|
||||||
.test(randomAlphaOfLengthBetween(8, 24)), is(true));
|
.test(randomAlphaOfLengthBetween(8, 24)), is(true));
|
||||||
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
|
|
||||||
.test(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX), is(true));
|
|
||||||
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
|
|
||||||
.test(RestrictedIndicesNames.SECURITY_INDEX_NAME), is(true));
|
|
||||||
|
|
||||||
assertNoAccessAllowed(snapshotUserRole, RestrictedIndicesNames.NAMES_SET);
|
for (String index : RestrictedIndicesNames.RESTRICTED_NAMES) {
|
||||||
|
// This test might cease to be true if we ever have non-security restricted names
|
||||||
|
// but that depends on how users are supposed to perform snapshots of those new indices.
|
||||||
|
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNoAccessAllowed(snapshotUserRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIngestAdminRole() {
|
public void testIngestAdminRole() {
|
||||||
|
@ -258,7 +260,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(ingestAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(randomAlphaOfLengthBetween(8, 24)),
|
assertThat(ingestAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(randomAlphaOfLengthBetween(8, 24)),
|
||||||
is(false));
|
is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(ingestAdminRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(ingestAdminRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKibanaSystemRole() {
|
public void testKibanaSystemRole() {
|
||||||
|
@ -359,7 +361,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
||||||
assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(false));
|
assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(kibanaRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(kibanaRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKibanaUserRole() {
|
public void testKibanaUserRole() {
|
||||||
|
@ -396,7 +398,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"),
|
assertThat(kibanaUserRole.application().grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"),
|
||||||
"*"), is(false));
|
"*"), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(kibanaUserRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(kibanaUserRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMonitoringUserRole() {
|
public void testMonitoringUserRole() {
|
||||||
|
@ -440,7 +442,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(monitoringUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
assertThat(monitoringUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
||||||
assertThat(monitoringUserRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(true));
|
assertThat(monitoringUserRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(true));
|
||||||
|
|
||||||
assertNoAccessAllowed(monitoringUserRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(monitoringUserRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRemoteMonitoringAgentRole() {
|
public void testRemoteMonitoringAgentRole() {
|
||||||
|
@ -499,7 +501,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(metricbeatIndex), is(false));
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(metricbeatIndex), is(false));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME).test(metricbeatIndex), is(false));
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME).test(metricbeatIndex), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(remoteMonitoringAgentRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(remoteMonitoringAgentRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRemoteMonitoringCollectorRole() {
|
public void testRemoteMonitoringCollectorRole() {
|
||||||
|
@ -547,36 +549,41 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(false));
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetIndexAction.NAME).test(index), is(false));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// These tests might need to change if we add new non-security restricted indices that the monitoring user isn't supposed to see
|
||||||
|
// (but ideally, the monitoring user should see all indices).
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetSettingsAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetSettingsAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesShardStoresAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesShardStoresAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(UpgradeStatusAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(UpgradeStatusAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(RecoveryAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(RecoveryAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesStatsAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesStatsAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesSegmentsAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndicesSegmentsAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(true));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(true));
|
||||||
|
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(SearchAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(SearchAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(false));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(false));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(GetAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(false));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(false));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(DeleteAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(DeleteAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(false));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(false));
|
||||||
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndexAction.NAME)
|
assertThat(remoteMonitoringAgentRole.indices().allowedIndicesMatcher(IndexAction.NAME)
|
||||||
.test(randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME)), is(false));
|
.test(randomFrom(RestrictedIndicesNames.RESTRICTED_NAMES)), is(false));
|
||||||
|
|
||||||
assertMonitoringOnRestrictedIndices(remoteMonitoringAgentRole);
|
assertMonitoringOnRestrictedIndices(remoteMonitoringAgentRole);
|
||||||
|
|
||||||
assertNoAccessAllowed(remoteMonitoringAgentRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(remoteMonitoringAgentRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertMonitoringOnRestrictedIndices(Role role) {
|
private void assertMonitoringOnRestrictedIndices(Role role) {
|
||||||
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
final MetaData metaData = new MetaData.Builder()
|
final MetaData metaData = new MetaData.Builder()
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -588,9 +595,9 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
GetSettingsAction.NAME, IndicesShardStoresAction.NAME, UpgradeStatusAction.NAME, RecoveryAction.NAME);
|
GetSettingsAction.NAME, IndicesShardStoresAction.NAME, UpgradeStatusAction.NAME, RecoveryAction.NAME);
|
||||||
for (final String indexMonitoringActionName : indexMonitoringActionNamesList) {
|
for (final String indexMonitoringActionName : indexMonitoringActionNamesList) {
|
||||||
final Map<String, IndexAccessControl> authzMap = role.indices().authorize(indexMonitoringActionName,
|
final Map<String, IndexAccessControl> authzMap = role.indices().authorize(indexMonitoringActionName,
|
||||||
Sets.newHashSet(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME),
|
Sets.newHashSet(internalSecurityIndex, RestrictedIndicesNames.SECURITY_INDEX_NAME),
|
||||||
metaData.getAliasAndIndexLookup(), fieldPermissionsCache);
|
metaData.getAliasAndIndexLookup(), fieldPermissionsCache);
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX).isGranted(), is(true));
|
assertThat(authzMap.get(internalSecurityIndex).isGranted(), is(true));
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -632,7 +639,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(reportingUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false));
|
assertThat(reportingUserRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false));
|
||||||
assertThat(reportingUserRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(false));
|
assertThat(reportingUserRole.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(reportingUserRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(reportingUserRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKibanaDashboardOnlyUserRole() {
|
public void testKibanaDashboardOnlyUserRole() {
|
||||||
|
@ -666,7 +673,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(dashboardsOnlyUserRole.application().grants(
|
assertThat(dashboardsOnlyUserRole.application().grants(
|
||||||
new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"), is(false));
|
new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(dashboardsOnlyUserRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(dashboardsOnlyUserRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSuperuserRole() {
|
public void testSuperuserRole() {
|
||||||
|
@ -685,6 +692,8 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(superuserRole.cluster().check("internal:admin/foo", request), is(false));
|
assertThat(superuserRole.cluster().check("internal:admin/foo", request), is(false));
|
||||||
|
|
||||||
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
final MetaData metaData = new MetaData.Builder()
|
final MetaData metaData = new MetaData.Builder()
|
||||||
.put(new IndexMetaData.Builder("a1").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("a1").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder("a2").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("a2").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
|
@ -697,7 +706,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
.putAlias(new AliasMetaData.Builder("ab").build())
|
.putAlias(new AliasMetaData.Builder("ab").build())
|
||||||
.putAlias(new AliasMetaData.Builder("ba").build())
|
.putAlias(new AliasMetaData.Builder("ba").build())
|
||||||
.build(), true)
|
.build(), true)
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -725,7 +734,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
authzMap = superuserRole.indices().authorize(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME),
|
authzMap = superuserRole.indices().authorize(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME),
|
||||||
Sets.newHashSet(RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup, fieldPermissionsCache);
|
Sets.newHashSet(RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup, fieldPermissionsCache);
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX).isGranted(), is(true));
|
assertThat(authzMap.get(internalSecurityIndex).isGranted(), is(true));
|
||||||
assertTrue(superuserRole.indices().check(SearchAction.NAME));
|
assertTrue(superuserRole.indices().check(SearchAction.NAME));
|
||||||
assertFalse(superuserRole.indices().check("unknown"));
|
assertFalse(superuserRole.indices().check("unknown"));
|
||||||
|
|
||||||
|
@ -734,7 +743,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(superuserRole.indices().allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
|
assertThat(superuserRole.indices().allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
|
||||||
.test(RestrictedIndicesNames.SECURITY_INDEX_NAME), is(true));
|
.test(RestrictedIndicesNames.SECURITY_INDEX_NAME), is(true));
|
||||||
assertThat(superuserRole.indices().allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
|
assertThat(superuserRole.indices().allowedIndicesMatcher(randomFrom(IndexAction.NAME, DeleteIndexAction.NAME, SearchAction.NAME))
|
||||||
.test(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX), is(true));
|
.test(internalSecurityIndex), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLogstashSystemRole() {
|
public void testLogstashSystemRole() {
|
||||||
|
@ -760,7 +769,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(logstashSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
assertThat(logstashSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
||||||
is(false));
|
is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(logstashSystemRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(logstashSystemRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBeatsAdminRole() {
|
public void testBeatsAdminRole() {
|
||||||
|
@ -798,7 +807,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true));
|
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true));
|
||||||
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
|
||||||
|
|
||||||
assertNoAccessAllowed(beatsAdminRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(beatsAdminRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBeatsSystemRole() {
|
public void testBeatsSystemRole() {
|
||||||
|
@ -824,7 +833,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(logstashSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
assertThat(logstashSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
||||||
is(false));
|
is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(logstashSystemRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(logstashSystemRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAPMSystemRole() {
|
public void testAPMSystemRole() {
|
||||||
|
@ -850,7 +859,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(APMSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
assertThat(APMSystemRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
|
||||||
is(false));
|
is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(APMSystemRole, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(APMSystemRole, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAPMUserRole() {
|
public void testAPMUserRole() {
|
||||||
|
@ -938,7 +947,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertOnlyReadAllowed(role, AuditorField.NOTIFICATIONS_INDEX);
|
assertOnlyReadAllowed(role, AuditorField.NOTIFICATIONS_INDEX);
|
||||||
assertReadWriteDocsButNotDeleteIndexAllowed(role, AnnotationIndex.INDEX_NAME);
|
assertReadWriteDocsButNotDeleteIndexAllowed(role, AnnotationIndex.INDEX_NAME);
|
||||||
|
|
||||||
assertNoAccessAllowed(role, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMachineLearningUserRole() {
|
public void testMachineLearningUserRole() {
|
||||||
|
@ -1009,7 +1018,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertOnlyReadAllowed(role, AuditorField.NOTIFICATIONS_INDEX);
|
assertOnlyReadAllowed(role, AuditorField.NOTIFICATIONS_INDEX);
|
||||||
assertReadWriteDocsButNotDeleteIndexAllowed(role, AnnotationIndex.INDEX_NAME);
|
assertReadWriteDocsButNotDeleteIndexAllowed(role, AnnotationIndex.INDEX_NAME);
|
||||||
|
|
||||||
assertNoAccessAllowed(role, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWatcherAdminRole() {
|
public void testWatcherAdminRole() {
|
||||||
|
@ -1038,7 +1047,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertOnlyReadAllowed(role, index);
|
assertOnlyReadAllowed(role, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNoAccessAllowed(role, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWatcherUserRole() {
|
public void testWatcherUserRole() {
|
||||||
|
@ -1068,7 +1077,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertOnlyReadAllowed(role, index);
|
assertOnlyReadAllowed(role, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNoAccessAllowed(role, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertReadWriteDocsButNotDeleteIndexAllowed(Role role, String index) {
|
private void assertReadWriteDocsButNotDeleteIndexAllowed(Role role, String index) {
|
||||||
|
@ -1092,7 +1101,7 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
||||||
assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false));
|
assertThat(role.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(false));
|
||||||
assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(false));
|
assertThat(role.indices().allowedIndicesMatcher(BulkAction.NAME).test(index), is(false));
|
||||||
|
|
||||||
assertNoAccessAllowed(role, RestrictedIndicesNames.NAMES_SET);
|
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNoAccessAllowed(Role role, Collection<String> indices) {
|
private void assertNoAccessAllowed(Role role, Collection<String> indices) {
|
||||||
|
|
|
@ -40,12 +40,10 @@ import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.core.template.TemplateUtils;
|
import org.elasticsearch.xpack.core.template.TemplateUtils;
|
||||||
import org.elasticsearch.xpack.core.upgrade.IndexUpgradeCheckVersion;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -67,7 +65,7 @@ import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
|
||||||
*/
|
*/
|
||||||
public class SecurityIndexManager implements ClusterStateListener {
|
public class SecurityIndexManager implements ClusterStateListener {
|
||||||
|
|
||||||
public static final String INTERNAL_SECURITY_INDEX = ".security-" + IndexUpgradeCheckVersion.UPRADE_VERSION;
|
public static final String INTERNAL_SECURITY_INDEX = RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7;
|
||||||
public static final int INTERNAL_INDEX_FORMAT = 6;
|
public static final int INTERNAL_INDEX_FORMAT = 6;
|
||||||
public static final String SECURITY_VERSION_STRING = "security-version";
|
public static final String SECURITY_VERSION_STRING = "security-version";
|
||||||
public static final String TEMPLATE_VERSION_PATTERN = Pattern.quote("${security.template.version}");
|
public static final String TEMPLATE_VERSION_PATTERN = Pattern.quote("${security.template.version}");
|
||||||
|
@ -83,7 +81,7 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
private volatile State indexState;
|
private volatile State indexState;
|
||||||
|
|
||||||
public SecurityIndexManager(Client client, String indexName, ClusterService clusterService) {
|
public SecurityIndexManager(Client client, String indexName, ClusterService clusterService) {
|
||||||
this(client, indexName, new State(false, false, false, false, null, null));
|
this(client, indexName, new State(false, false, false, false, null, null, null));
|
||||||
clusterService.addListener(this);
|
clusterService.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +95,6 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
return new SecurityIndexManager(null, indexName, indexState);
|
return new SecurityIndexManager(null, indexName, indexState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> indexNames() {
|
|
||||||
return Collections.unmodifiableList(Arrays.asList(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkMappingVersion(Predicate<Version> requiredVersion) {
|
public boolean checkMappingVersion(Predicate<Version> requiredVersion) {
|
||||||
// pull value into local variable for consistent view
|
// pull value into local variable for consistent view
|
||||||
final State currentIndexState = this.indexState;
|
final State currentIndexState = this.indexState;
|
||||||
|
@ -167,7 +161,9 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
final Version mappingVersion = oldestIndexMappingVersion(event.state());
|
final Version mappingVersion = oldestIndexMappingVersion(event.state());
|
||||||
final ClusterHealthStatus indexStatus = indexMetaData == null ? null :
|
final ClusterHealthStatus indexStatus = indexMetaData == null ? null :
|
||||||
new ClusterIndexHealth(indexMetaData, event.state().getRoutingTable().index(indexMetaData.getIndex())).getStatus();
|
new ClusterIndexHealth(indexMetaData, event.state().getRoutingTable().index(indexMetaData.getIndex())).getStatus();
|
||||||
final State newState = new State(indexExists, isIndexUpToDate, indexAvailable, mappingIsUpToDate, mappingVersion, indexStatus);
|
final String concreteIndexName = indexMetaData == null ? INTERNAL_SECURITY_INDEX : indexMetaData.getIndex().getName();
|
||||||
|
final State newState = new State(indexExists, isIndexUpToDate, indexAvailable, mappingIsUpToDate, mappingVersion, concreteIndexName,
|
||||||
|
indexStatus);
|
||||||
this.indexState = newState;
|
this.indexState = newState;
|
||||||
|
|
||||||
if (newState.equals(previousState) == false) {
|
if (newState.equals(previousState) == false) {
|
||||||
|
@ -306,6 +302,7 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
"Security index is not on the current version. Security features relying on the index will not be available until " +
|
"Security index is not on the current version. Security features relying on the index will not be available until " +
|
||||||
"the upgrade API is run on the security index"));
|
"the upgrade API is run on the security index"));
|
||||||
} else if (indexState.indexExists == false) {
|
} else if (indexState.indexExists == false) {
|
||||||
|
LOGGER.info("security index does not exist. Creating [{}] with alias [{}]", INTERNAL_SECURITY_INDEX, SECURITY_INDEX_NAME);
|
||||||
Tuple<String, Settings> mappingAndSettings = loadMappingAndSettingsSourceFromTemplate();
|
Tuple<String, Settings> mappingAndSettings = loadMappingAndSettingsSourceFromTemplate();
|
||||||
CreateIndexRequest request = new CreateIndexRequest(INTERNAL_SECURITY_INDEX)
|
CreateIndexRequest request = new CreateIndexRequest(INTERNAL_SECURITY_INDEX)
|
||||||
.alias(new Alias(SECURITY_INDEX_NAME))
|
.alias(new Alias(SECURITY_INDEX_NAME))
|
||||||
|
@ -336,7 +333,9 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
}
|
}
|
||||||
}, client.admin().indices()::create);
|
}, client.admin().indices()::create);
|
||||||
} else if (indexState.mappingUpToDate == false) {
|
} else if (indexState.mappingUpToDate == false) {
|
||||||
PutMappingRequest request = new PutMappingRequest(INTERNAL_SECURITY_INDEX)
|
LOGGER.info(
|
||||||
|
"security index [{}] (alias [{}]) is not up to date. Updating mapping", indexState.concreteIndexName, SECURITY_INDEX_NAME);
|
||||||
|
PutMappingRequest request = new PutMappingRequest(indexState.concreteIndexName)
|
||||||
.source(loadMappingAndSettingsSourceFromTemplate().v1(), XContentType.JSON)
|
.source(loadMappingAndSettingsSourceFromTemplate().v1(), XContentType.JSON)
|
||||||
.type("doc");
|
.type("doc");
|
||||||
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, request,
|
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, request,
|
||||||
|
@ -383,15 +382,17 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
public final boolean indexAvailable;
|
public final boolean indexAvailable;
|
||||||
public final boolean mappingUpToDate;
|
public final boolean mappingUpToDate;
|
||||||
public final Version mappingVersion;
|
public final Version mappingVersion;
|
||||||
|
public final String concreteIndexName;
|
||||||
public final ClusterHealthStatus indexStatus;
|
public final ClusterHealthStatus indexStatus;
|
||||||
|
|
||||||
public State(boolean indexExists, boolean isIndexUpToDate, boolean indexAvailable,
|
public State(boolean indexExists, boolean isIndexUpToDate, boolean indexAvailable,
|
||||||
boolean mappingUpToDate, Version mappingVersion, ClusterHealthStatus indexStatus) {
|
boolean mappingUpToDate, Version mappingVersion, String concreteIndexName, ClusterHealthStatus indexStatus) {
|
||||||
this.indexExists = indexExists;
|
this.indexExists = indexExists;
|
||||||
this.isIndexUpToDate = isIndexUpToDate;
|
this.isIndexUpToDate = isIndexUpToDate;
|
||||||
this.indexAvailable = indexAvailable;
|
this.indexAvailable = indexAvailable;
|
||||||
this.mappingUpToDate = mappingUpToDate;
|
this.mappingUpToDate = mappingUpToDate;
|
||||||
this.mappingVersion = mappingVersion;
|
this.mappingVersion = mappingVersion;
|
||||||
|
this.concreteIndexName = concreteIndexName;
|
||||||
this.indexStatus = indexStatus;
|
this.indexStatus = indexStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,12 +406,14 @@ public class SecurityIndexManager implements ClusterStateListener {
|
||||||
indexAvailable == state.indexAvailable &&
|
indexAvailable == state.indexAvailable &&
|
||||||
mappingUpToDate == state.mappingUpToDate &&
|
mappingUpToDate == state.mappingUpToDate &&
|
||||||
Objects.equals(mappingVersion, state.mappingVersion) &&
|
Objects.equals(mappingVersion, state.mappingVersion) &&
|
||||||
|
Objects.equals(concreteIndexName, state.concreteIndexName) &&
|
||||||
indexStatus == state.indexStatus;
|
indexStatus == state.indexStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(indexExists, isIndexUpToDate, indexAvailable, mappingUpToDate, mappingVersion, indexStatus);
|
return Objects.hash(indexExists, isIndexUpToDate, indexAvailable, mappingUpToDate, mappingVersion, concreteIndexName,
|
||||||
|
indexStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ import org.elasticsearch.xpack.core.security.authc.Realm.Factory;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
|
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.EmptyAuthorizationInfo;
|
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.EmptyAuthorizationInfo;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
|
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
|
||||||
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
||||||
import org.elasticsearch.xpack.core.security.user.User;
|
import org.elasticsearch.xpack.core.security.user.User;
|
||||||
|
@ -146,9 +147,14 @@ public class AuthenticationServiceTests extends ESTestCase {
|
||||||
private Client client;
|
private Client client;
|
||||||
private InetSocketAddress remoteAddress;
|
private InetSocketAddress remoteAddress;
|
||||||
|
|
||||||
|
private String concreteSecurityIndexName;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@SuppressForbidden(reason = "Allow accessing localhost")
|
@SuppressForbidden(reason = "Allow accessing localhost")
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
|
concreteSecurityIndexName = randomFrom(
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6, RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
|
|
||||||
token = mock(AuthenticationToken.class);
|
token = mock(AuthenticationToken.class);
|
||||||
when(token.principal()).thenReturn(randomAlphaOfLength(5));
|
when(token.principal()).thenReturn(randomAlphaOfLength(5));
|
||||||
message = new InternalMessage();
|
message = new InternalMessage();
|
||||||
|
@ -1386,6 +1392,6 @@ public class AuthenticationServiceTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
||||||
return new SecurityIndexManager.State(true, true, true, true, null, indexStatus);
|
return new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, indexStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.elasticsearch.env.TestEnvironment;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
|
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -21,8 +22,11 @@ import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class NativeRealmTests extends ESTestCase {
|
public class NativeRealmTests extends ESTestCase {
|
||||||
|
|
||||||
|
private final String concreteSecurityIndexName = randomFrom(
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6, RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
|
|
||||||
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
||||||
return new SecurityIndexManager.State(true, true, true, true, null, indexStatus);
|
return new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, indexStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCacheClearOnIndexHealthChange() {
|
public void testCacheClearOnIndexHealthChange() {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRoleMapping;
|
import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRoleMapping;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression;
|
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression.FieldValue;
|
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression.FieldValue;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.core.security.user.User;
|
import org.elasticsearch.xpack.core.security.user.User;
|
||||||
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
|
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
|
||||||
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
|
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
|
||||||
|
@ -46,6 +47,8 @@ import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
public class NativeRoleMappingStoreTests extends ESTestCase {
|
public class NativeRoleMappingStoreTests extends ESTestCase {
|
||||||
|
private final String concreteSecurityIndexName = randomFrom(
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6, RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
|
|
||||||
public void testResolveRoles() throws Exception {
|
public void testResolveRoles() throws Exception {
|
||||||
// Does match DN
|
// Does match DN
|
||||||
|
@ -124,7 +127,7 @@ public class NativeRoleMappingStoreTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
||||||
return new SecurityIndexManager.State(true, true, true, true, null, indexStatus);
|
return new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, indexStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCacheClearOnIndexHealthChange() {
|
public void testCacheClearOnIndexHealthChange() {
|
||||||
|
@ -169,13 +172,13 @@ public class NativeRoleMappingStoreTests extends ESTestCase {
|
||||||
final NativeRoleMappingStore store = buildRoleMappingStoreForInvalidationTesting(numInvalidation);
|
final NativeRoleMappingStore store = buildRoleMappingStoreForInvalidationTesting(numInvalidation);
|
||||||
|
|
||||||
store.onSecurityIndexStateChange(
|
store.onSecurityIndexStateChange(
|
||||||
new SecurityIndexManager.State(true, false, true, true, null, null),
|
new SecurityIndexManager.State(true, false, true, true, null, concreteSecurityIndexName, null),
|
||||||
new SecurityIndexManager.State(true, true, true, true, null, null));
|
new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, null));
|
||||||
assertEquals(1, numInvalidation.get());
|
assertEquals(1, numInvalidation.get());
|
||||||
|
|
||||||
store.onSecurityIndexStateChange(
|
store.onSecurityIndexStateChange(
|
||||||
new SecurityIndexManager.State(true, true, true, true, null, null),
|
new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, null),
|
||||||
new SecurityIndexManager.State(true, false, true, true, null, null));
|
new SecurityIndexManager.State(true, false, true, true, null, concreteSecurityIndexName, null));
|
||||||
assertEquals(2, numInvalidation.get());
|
assertEquals(2, numInvalidation.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
RoleDescriptor bRole = new RoleDescriptor("b", null,
|
RoleDescriptor bRole = new RoleDescriptor("b", null,
|
||||||
new IndicesPrivileges[] { IndicesPrivileges.builder().indices("b").privileges("READ").build() }, null);
|
new IndicesPrivileges[] { IndicesPrivileges.builder().indices("b").privileges("READ").build() }, null);
|
||||||
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
MetaData metaData = MetaData.builder()
|
MetaData metaData = MetaData.builder()
|
||||||
.put(new IndexMetaData.Builder("a1").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("a1").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder("a2").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("a2").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
|
@ -59,7 +61,7 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
.putAlias(new AliasMetaData.Builder("ab").build())
|
.putAlias(new AliasMetaData.Builder("ab").build())
|
||||||
.putAlias(new AliasMetaData.Builder("ba").build())
|
.putAlias(new AliasMetaData.Builder("ba").build())
|
||||||
.build(), true)
|
.build(), true)
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -75,7 +77,7 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
assertThat(list, containsInAnyOrder("a1", "a2", "aaaaaa", "b", "ab"));
|
assertThat(list, containsInAnyOrder("a1", "a2", "aaaaaa", "b", "ab"));
|
||||||
assertFalse(list.contains("bbbbb"));
|
assertFalse(list.contains("bbbbb"));
|
||||||
assertFalse(list.contains("ba"));
|
assertFalse(list.contains("ba"));
|
||||||
assertThat(list, not(contains(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)));
|
assertThat(list, not(contains(internalSecurityIndex)));
|
||||||
assertThat(list, not(contains(RestrictedIndicesNames.SECURITY_INDEX_NAME)));
|
assertThat(list, not(contains(RestrictedIndicesNames.SECURITY_INDEX_NAME)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +101,13 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
.cluster(ClusterPrivilege.ALL)
|
.cluster(ClusterPrivilege.ALL)
|
||||||
.build();
|
.build();
|
||||||
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
MetaData metaData = MetaData.builder()
|
MetaData metaData = MetaData.builder()
|
||||||
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(
|
||||||
|
internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -113,7 +118,7 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
List<String> authorizedIndices =
|
List<String> authorizedIndices =
|
||||||
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
||||||
assertThat(authorizedIndices, containsInAnyOrder("an-index", "another-index"));
|
assertThat(authorizedIndices, containsInAnyOrder("an-index", "another-index"));
|
||||||
assertThat(authorizedIndices, not(contains(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)));
|
assertThat(authorizedIndices, not(contains(internalSecurityIndex)));
|
||||||
assertThat(authorizedIndices, not(contains(RestrictedIndicesNames.SECURITY_INDEX_NAME)));
|
assertThat(authorizedIndices, not(contains(RestrictedIndicesNames.SECURITY_INDEX_NAME)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +128,12 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
.cluster(ClusterPrivilege.ALL)
|
.cluster(ClusterPrivilege.ALL)
|
||||||
.build();
|
.build();
|
||||||
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
MetaData metaData = MetaData.builder()
|
MetaData metaData = MetaData.builder()
|
||||||
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -137,11 +144,11 @@ public class AuthorizedIndicesTests extends ESTestCase {
|
||||||
List<String> authorizedIndices =
|
List<String> authorizedIndices =
|
||||||
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
||||||
assertThat(authorizedIndices, containsInAnyOrder(
|
assertThat(authorizedIndices, containsInAnyOrder(
|
||||||
"an-index", "another-index", SecurityIndexManager.SECURITY_INDEX_NAME, SecurityIndexManager.INTERNAL_SECURITY_INDEX));
|
"an-index", "another-index", SecurityIndexManager.SECURITY_INDEX_NAME, internalSecurityIndex));
|
||||||
|
|
||||||
List<String> authorizedIndicesSuperUser =
|
List<String> authorizedIndicesSuperUser =
|
||||||
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
RBACEngine.resolveAuthorizedIndicesFromRole(role, SearchAction.NAME, metaData.getAliasAndIndexLookup());
|
||||||
assertThat(authorizedIndicesSuperUser, containsInAnyOrder(
|
assertThat(authorizedIndicesSuperUser, containsInAnyOrder(
|
||||||
"an-index", "another-index", SecurityIndexManager.SECURITY_INDEX_NAME, SecurityIndexManager.INTERNAL_SECURITY_INDEX));
|
"an-index", "another-index", SecurityIndexManager.SECURITY_INDEX_NAME, internalSecurityIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.INTERNAL_SECURITY_INDEX;
|
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7;
|
||||||
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.SECURITY_INDEX_NAME;
|
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.SECURITY_INDEX_NAME;
|
||||||
|
|
||||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||||
|
@ -56,7 +56,7 @@ public class SnapshotUserRoleIntegTests extends NativeRealmIntegTestCase {
|
||||||
final String snapshotUserToken = basicAuthHeaderValue(user, new SecureString(password));
|
final String snapshotUserToken = basicAuthHeaderValue(user, new SecureString(password));
|
||||||
client = client().filterWithHeader(Collections.singletonMap("Authorization", snapshotUserToken));
|
client = client().filterWithHeader(Collections.singletonMap("Authorization", snapshotUserToken));
|
||||||
securityClient().preparePutUser(user, password, Hasher.BCRYPT, "snapshot_user").get();
|
securityClient().preparePutUser(user, password, Hasher.BCRYPT, "snapshot_user").get();
|
||||||
ensureGreen(INTERNAL_SECURITY_INDEX);
|
ensureGreen(INTERNAL_SECURITY_INDEX_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSnapshotUserRoleCanSnapshotAndSeeAllIndices() {
|
public void testSnapshotUserRoleCanSnapshotAndSeeAllIndices() {
|
||||||
|
@ -67,17 +67,17 @@ public class SnapshotUserRoleIntegTests extends NativeRealmIntegTestCase {
|
||||||
assertThat(getRepositoriesResponse.repositories().get(0).name(), is("repo"));
|
assertThat(getRepositoriesResponse.repositories().get(0).name(), is("repo"));
|
||||||
// view all indices, including restricted ones
|
// view all indices, including restricted ones
|
||||||
final GetIndexResponse getIndexResponse = client.admin().indices().prepareGetIndex().setIndices(randomFrom("_all", "*")).get();
|
final GetIndexResponse getIndexResponse = client.admin().indices().prepareGetIndex().setIndices(randomFrom("_all", "*")).get();
|
||||||
assertThat(Arrays.asList(getIndexResponse.indices()), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
|
assertThat(Arrays.asList(getIndexResponse.indices()), containsInAnyOrder(INTERNAL_SECURITY_INDEX_7, ordinaryIndex));
|
||||||
// create snapshot that includes restricted indices
|
// create snapshot that includes restricted indices
|
||||||
final CreateSnapshotResponse snapshotResponse = client.admin().cluster().prepareCreateSnapshot("repo", "snap")
|
final CreateSnapshotResponse snapshotResponse = client.admin().cluster().prepareCreateSnapshot("repo", "snap")
|
||||||
.setIndices(randomFrom("_all", "*")).setWaitForCompletion(true).get();
|
.setIndices(randomFrom("_all", "*")).setWaitForCompletion(true).get();
|
||||||
assertThat(snapshotResponse.getSnapshotInfo().state(), is(SnapshotState.SUCCESS));
|
assertThat(snapshotResponse.getSnapshotInfo().state(), is(SnapshotState.SUCCESS));
|
||||||
assertThat(snapshotResponse.getSnapshotInfo().indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
|
assertThat(snapshotResponse.getSnapshotInfo().indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX_7, ordinaryIndex));
|
||||||
// view snapshots for repo
|
// view snapshots for repo
|
||||||
final GetSnapshotsResponse getSnapshotResponse = client.admin().cluster().prepareGetSnapshots("repo").get();
|
final GetSnapshotsResponse getSnapshotResponse = client.admin().cluster().prepareGetSnapshots("repo").get();
|
||||||
assertThat(getSnapshotResponse.getSnapshots().size(), is(1));
|
assertThat(getSnapshotResponse.getSnapshots().size(), is(1));
|
||||||
assertThat(getSnapshotResponse.getSnapshots().get(0).snapshotId().getName(), is("snap"));
|
assertThat(getSnapshotResponse.getSnapshots().get(0).snapshotId().getName(), is("snap"));
|
||||||
assertThat(getSnapshotResponse.getSnapshots().get(0).indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
|
assertThat(getSnapshotResponse.getSnapshots().get(0).indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX_7, ordinaryIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSnapshotUserRoleIsReserved() {
|
public void testSnapshotUserRoleIsReserved() {
|
||||||
|
@ -112,7 +112,7 @@ public class SnapshotUserRoleIntegTests extends NativeRealmIntegTestCase {
|
||||||
() -> client.admin().cluster().prepareDeleteSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(),
|
() -> client.admin().cluster().prepareDeleteSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(),
|
||||||
"cluster:admin/snapshot/delete", "snapshot_user");
|
"cluster:admin/snapshot/delete", "snapshot_user");
|
||||||
// try destructive/revealing actions on all indices
|
// try destructive/revealing actions on all indices
|
||||||
for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_INDEX, SECURITY_INDEX_NAME, ordinaryIndex)) {
|
for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_INDEX_7, SECURITY_INDEX_NAME, ordinaryIndex)) {
|
||||||
assertThrowsAuthorizationException(() -> client.prepareSearch(indexToTest).get(), "indices:data/read/search", "snapshot_user");
|
assertThrowsAuthorizationException(() -> client.prepareSearch(indexToTest).get(), "indices:data/read/search", "snapshot_user");
|
||||||
assertThrowsAuthorizationException(() -> client.prepareGet(indexToTest, "doc", "1").get(), "indices:data/read/get",
|
assertThrowsAuthorizationException(() -> client.prepareGet(indexToTest, "doc", "1").get(), "indices:data/read/get",
|
||||||
"snapshot_user");
|
"snapshot_user");
|
||||||
|
|
|
@ -293,8 +293,10 @@ public class IndicesPermissionTests extends ESTestCase {
|
||||||
|
|
||||||
public void testSecurityIndicesPermissions() {
|
public void testSecurityIndicesPermissions() {
|
||||||
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build();
|
||||||
|
final String internalSecurityIndex = randomFrom(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6,
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
final MetaData metaData = new MetaData.Builder()
|
final MetaData metaData = new MetaData.Builder()
|
||||||
.put(new IndexMetaData.Builder(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX)
|
.put(new IndexMetaData.Builder(internalSecurityIndex)
|
||||||
.settings(indexSettings)
|
.settings(indexSettings)
|
||||||
.numberOfShards(1)
|
.numberOfShards(1)
|
||||||
.numberOfReplicas(0)
|
.numberOfReplicas(0)
|
||||||
|
@ -307,17 +309,17 @@ public class IndicesPermissionTests extends ESTestCase {
|
||||||
// allow_restricted_indices: false
|
// allow_restricted_indices: false
|
||||||
IndicesPermission.Group group = new IndicesPermission.Group(IndexPrivilege.ALL, new FieldPermissions(), null, false, "*");
|
IndicesPermission.Group group = new IndicesPermission.Group(IndexPrivilege.ALL, new FieldPermissions(), null, false, "*");
|
||||||
Map<String, IndicesAccessControl.IndexAccessControl> authzMap = new IndicesPermission(group).authorize(SearchAction.NAME,
|
Map<String, IndicesAccessControl.IndexAccessControl> authzMap = new IndicesPermission(group).authorize(SearchAction.NAME,
|
||||||
Sets.newHashSet(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup,
|
Sets.newHashSet(internalSecurityIndex, RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup,
|
||||||
fieldPermissionsCache);
|
fieldPermissionsCache);
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX).isGranted(), is(false));
|
assertThat(authzMap.get(internalSecurityIndex).isGranted(), is(false));
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(false));
|
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(false));
|
||||||
|
|
||||||
// allow_restricted_indices: true
|
// allow_restricted_indices: true
|
||||||
group = new IndicesPermission.Group(IndexPrivilege.ALL, new FieldPermissions(), null, true, "*");
|
group = new IndicesPermission.Group(IndexPrivilege.ALL, new FieldPermissions(), null, true, "*");
|
||||||
authzMap = new IndicesPermission(group).authorize(SearchAction.NAME,
|
authzMap = new IndicesPermission(group).authorize(SearchAction.NAME,
|
||||||
Sets.newHashSet(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX, RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup,
|
Sets.newHashSet(internalSecurityIndex, RestrictedIndicesNames.SECURITY_INDEX_NAME), lookup,
|
||||||
fieldPermissionsCache);
|
fieldPermissionsCache);
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX).isGranted(), is(true));
|
assertThat(authzMap.get(internalSecurityIndex).isGranted(), is(true));
|
||||||
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
assertThat(authzMap.get(RestrictedIndicesNames.SECURITY_INDEX_NAME).isGranted(), is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterP
|
||||||
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
|
||||||
import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore;
|
import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore;
|
||||||
import org.elasticsearch.xpack.core.security.authz.store.RoleRetrievalResult;
|
import org.elasticsearch.xpack.core.security.authz.store.RoleRetrievalResult;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
|
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
|
||||||
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
||||||
import org.elasticsearch.xpack.core.security.user.User;
|
import org.elasticsearch.xpack.core.security.user.User;
|
||||||
|
@ -94,6 +95,8 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private final FieldPermissionsCache cache = new FieldPermissionsCache(Settings.EMPTY);
|
private final FieldPermissionsCache cache = new FieldPermissionsCache(Settings.EMPTY);
|
||||||
|
private final String concreteSecurityIndexName = randomFrom(
|
||||||
|
RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_6, RestrictedIndicesNames.INTERNAL_SECURITY_INDEX_7);
|
||||||
|
|
||||||
public void testRolesWhenDlsFlsUnlicensed() throws IOException {
|
public void testRolesWhenDlsFlsUnlicensed() throws IOException {
|
||||||
XPackLicenseState licenseState = mock(XPackLicenseState.class);
|
XPackLicenseState licenseState = mock(XPackLicenseState.class);
|
||||||
|
@ -695,7 +698,7 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
private SecurityIndexManager.State dummyState(ClusterHealthStatus indexStatus) {
|
||||||
return new SecurityIndexManager.State(true, true, true, true, null, indexStatus);
|
return new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, indexStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCacheClearOnIndexHealthChange() {
|
public void testCacheClearOnIndexHealthChange() {
|
||||||
|
@ -770,13 +773,13 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
||||||
};
|
};
|
||||||
|
|
||||||
compositeRolesStore.onSecurityIndexStateChange(
|
compositeRolesStore.onSecurityIndexStateChange(
|
||||||
new SecurityIndexManager.State(true, false, true, true, null, null),
|
new SecurityIndexManager.State(true, false, true, true, null, concreteSecurityIndexName, null),
|
||||||
new SecurityIndexManager.State(true, true, true, true, null, null));
|
new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, null));
|
||||||
assertEquals(1, numInvalidation.get());
|
assertEquals(1, numInvalidation.get());
|
||||||
|
|
||||||
compositeRolesStore.onSecurityIndexStateChange(
|
compositeRolesStore.onSecurityIndexStateChange(
|
||||||
new SecurityIndexManager.State(true, true, true, true, null, null),
|
new SecurityIndexManager.State(true, true, true, true, null, concreteSecurityIndexName, null),
|
||||||
new SecurityIndexManager.State(true, false, true, true, null, null));
|
new SecurityIndexManager.State(true, false, true, true, null, concreteSecurityIndexName, null));
|
||||||
assertEquals(2, numInvalidation.get());
|
assertEquals(2, numInvalidation.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.elasticsearch.action.search.SearchAction;
|
||||||
import org.elasticsearch.action.update.UpdateAction;
|
import org.elasticsearch.action.update.UpdateAction;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.core.security.index.IndexAuditTrailField;
|
import org.elasticsearch.xpack.core.security.index.IndexAuditTrailField;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.elasticsearch.xpack.core.security.user.XPackUser;
|
import org.elasticsearch.xpack.core.security.user.XPackUser;
|
||||||
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
|
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
|
||||||
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
|
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
|
||||||
|
@ -28,11 +29,14 @@ public class XPackUserTests extends ESTestCase {
|
||||||
assertThat(predicate.test(index), Matchers.is(true));
|
assertThat(predicate.test(index), Matchers.is(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testXPackUserCannotAccessSecurityIndex() {
|
public void testXPackUserCannotAccessRestrictedIndices() {
|
||||||
final String action = randomFrom(GetAction.NAME, SearchAction.NAME, IndexAction.NAME);
|
final String action = randomFrom(GetAction.NAME, SearchAction.NAME, IndexAction.NAME);
|
||||||
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
|
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
|
||||||
assertThat(predicate.test(SecurityIndexManager.SECURITY_INDEX_NAME), Matchers.is(false));
|
assertThat(predicate.test(SecurityIndexManager.SECURITY_INDEX_NAME), Matchers.is(false));
|
||||||
assertThat(predicate.test(SecurityIndexManager.INTERNAL_SECURITY_INDEX), Matchers.is(false));
|
assertThat(predicate.test(SecurityIndexManager.INTERNAL_SECURITY_INDEX), Matchers.is(false));
|
||||||
|
for (String index : RestrictedIndicesNames.RESTRICTED_NAMES) {
|
||||||
|
assertThat(predicate.test(index), Matchers.is(false));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testXPackUserCanReadAuditTrail() {
|
public void testXPackUserCanReadAuditTrail() {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
|
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -640,8 +641,7 @@ public abstract class SqlSecurityTestCase extends ESRestTestCase {
|
||||||
* SQL drops them from the interface. So we might have access to them, but we
|
* SQL drops them from the interface. So we might have access to them, but we
|
||||||
* don't show them.
|
* don't show them.
|
||||||
*/
|
*/
|
||||||
indices.remove(".security");
|
indices.removeAll(RestrictedIndicesNames.RESTRICTED_NAMES);
|
||||||
indices.remove(".security-6");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use a sorted list for indices for consistent error reporting
|
// Use a sorted list for indices for consistent error reporting
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
setup:
|
||||||
|
- skip:
|
||||||
|
features: headers
|
||||||
|
|
||||||
|
- do:
|
||||||
|
cluster.health:
|
||||||
|
wait_for_status: yellow
|
||||||
|
|
||||||
|
- do:
|
||||||
|
security.put_role:
|
||||||
|
name: "all_access"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"cluster": [ "all" ],
|
||||||
|
"indices": [
|
||||||
|
{ "names": ["*"], "privileges": ["all"] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
security.put_user:
|
||||||
|
username: "test_user"
|
||||||
|
body: >
|
||||||
|
{
|
||||||
|
"password" : "x-pack-test-password",
|
||||||
|
"roles" : [ "all_access" ],
|
||||||
|
"full_name" : "user with all possible privileges (but not superuser)"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
teardown:
|
||||||
|
- do:
|
||||||
|
security.delete_user:
|
||||||
|
username: "test_user"
|
||||||
|
ignore: 404
|
||||||
|
|
||||||
|
- do:
|
||||||
|
security.delete_role:
|
||||||
|
name: "all_access"
|
||||||
|
ignore: 404
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test get security index metadata":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
catch: forbidden
|
||||||
|
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
|
||||||
|
indices.get:
|
||||||
|
index: ".security-7"
|
||||||
|
|
||||||
|
- do:
|
||||||
|
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
|
||||||
|
indices.get:
|
||||||
|
index: ".security*7"
|
||||||
|
- length: { $body: 0 }
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test get security document":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
catch: forbidden
|
||||||
|
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
|
||||||
|
get:
|
||||||
|
index: ".security-7"
|
||||||
|
type: "doc"
|
||||||
|
id: "user-test_user"
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test search security index":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
catch: forbidden
|
||||||
|
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
|
||||||
|
search:
|
||||||
|
rest_total_hits_as_int: true
|
||||||
|
index: ".security-7"
|
||||||
|
|
||||||
|
- do:
|
||||||
|
headers: { Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" } # test_user
|
||||||
|
search:
|
||||||
|
rest_total_hits_as_int: true
|
||||||
|
index: ".security*7"
|
||||||
|
- match: { hits.total: 0 }
|
||||||
|
|
Loading…
Reference in New Issue