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:
Tim Vernum 2019-02-27 12:49:44 +11:00 committed by GitHub
parent 0c7310936b
commit 30687cbe7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 221 additions and 94 deletions

View File

@ -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;
} }

View File

@ -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() {
} }

View File

@ -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) {

View File

@ -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);
} }
} }
} }

View File

@ -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);
} }
} }

View File

@ -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() {

View File

@ -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());
} }

View File

@ -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));
} }
} }

View File

@ -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");

View File

@ -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));
} }

View File

@ -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());
} }

View File

@ -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() {

View File

@ -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

View File

@ -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 }