mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-29 01:44:36 -04:00
To avoid ambiguity (as cluster and index policies may have the same
name) changing implementation to have to separate policies for `index_privileges` and `cluster_privileges`. If both are set for the same policy, throw the IllegalArgumentException.
This commit is contained in:
parent
a7585b783f
commit
cb5bc09c7e
4 changed files with 144 additions and 52 deletions
|
@ -149,13 +149,26 @@ A list of authentication realm names or wildcards. The specified policy will
|
||||||
not print audit events for users in these realms.
|
not print audit events for users in these realms.
|
||||||
// end::xpack-sa-lf-events-ignore-realms-tag[]
|
// end::xpack-sa-lf-events-ignore-realms-tag[]
|
||||||
|
|
||||||
[[xpack-sa-lf-events-ignore-privileges]]
|
[[xpack-sa-lf-events-ignore-index-privileges]]
|
||||||
// tag::xpack-sa-lf-events-ignore-privileges-tag[]
|
// tag::xpack-sa-lf-events-ignore-index-privileges-tag[]
|
||||||
`xpack.security.audit.logfile.events.ignore_filters.<policy_name>.privileges`::
|
`xpack.security.audit.logfile.events.ignore_filters.<policy_name>.index_privileges`::
|
||||||
(<<dynamic-cluster-setting,Dynamic>>)
|
(<<dynamic-cluster-setting,Dynamic>>)
|
||||||
A list of privileges. The specified policy will not print audit events for actions
|
A list of index privileges. The specified policy will not print audit events for actions
|
||||||
requiring any of these privileges.
|
requiring any of these privileges.
|
||||||
// end::xpack-sa-lf-events-ignore-privileges-tag[]
|
// end::xpack-sa-lf-events-ignore-index-privileges-tag[]
|
||||||
|
|
||||||
|
[[xpack-sa-lf-events-ignore-cluster-privileges]]
|
||||||
|
// tag::xpack-sa-lf-events-ignore-cluster-privileges-tag[]
|
||||||
|
`xpack.security.audit.logfile.events.ignore_filters.<policy_name>.cluster_privileges`::
|
||||||
|
(<<dynamic-cluster-setting,Dynamic>>)
|
||||||
|
A list of cluster privileges. The specified policy will not print audit events for actions
|
||||||
|
requiring any of these privileges.
|
||||||
|
// end::xpack-sa-lf-events-ignore-cluster-privileges-tag[]
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
Either `cluster_privileges` or `index_privileges` ignore filter can be specified
|
||||||
|
for the same policy.
|
||||||
|
If you need to filter out both index and cluster actions, you can create two different policies.
|
||||||
|
|
||||||
[[xpack-sa-lf-events-ignore-roles]]
|
[[xpack-sa-lf-events-ignore-roles]]
|
||||||
// tag::xpack-sa-lf-events-ignore-roles-tag[]
|
// tag::xpack-sa-lf-events-ignore-roles-tag[]
|
||||||
|
|
|
@ -79,7 +79,6 @@ import org.elasticsearch.xpack.security.Security;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
||||||
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||||
import org.elasticsearch.xpack.security.authc.ApiKeyService;
|
import org.elasticsearch.xpack.security.authc.ApiKeyService;
|
||||||
import org.elasticsearch.xpack.security.authz.AuthorizationService;
|
|
||||||
import org.elasticsearch.xpack.security.rest.RemoteHostHeader;
|
import org.elasticsearch.xpack.security.rest.RemoteHostHeader;
|
||||||
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
||||||
import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
|
import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
|
||||||
|
@ -94,6 +93,7 @@ import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -221,8 +221,12 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "indices",
|
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "indices",
|
||||||
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
|
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
|
||||||
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
|
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
|
||||||
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_PRIVILEGES =
|
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_INDEX_PRIVILEGES =
|
||||||
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "privileges",
|
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "index_privileges",
|
||||||
|
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
|
||||||
|
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
|
||||||
|
protected static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES =
|
||||||
|
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "cluster_privileges",
|
||||||
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
|
(key) -> Setting.listSetting(key, Collections.singletonList("*"), Function.identity(),
|
||||||
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
|
value -> EventFilterPolicy.parsePredicate(value), Property.NodeScope, Property.Dynamic));
|
||||||
|
|
||||||
|
@ -284,10 +288,16 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
final EventFilterPolicy newPolicy = policy.orElse(new EventFilterPolicy(policyName, settings)).changeIndicesFilter(filtersList);
|
final EventFilterPolicy newPolicy = policy.orElse(new EventFilterPolicy(policyName, settings)).changeIndicesFilter(filtersList);
|
||||||
this.eventFilterPolicyRegistry.set(policyName, newPolicy);
|
this.eventFilterPolicyRegistry.set(policyName, newPolicy);
|
||||||
}, (policyName, filtersList) -> EventFilterPolicy.parsePredicate(filtersList));
|
}, (policyName, filtersList) -> EventFilterPolicy.parsePredicate(filtersList));
|
||||||
clusterService.getClusterSettings().addAffixUpdateConsumer(FILTER_POLICY_IGNORE_PRIVILEGES, (policyName, filtersList) -> {
|
clusterService.getClusterSettings().addAffixUpdateConsumer(FILTER_POLICY_IGNORE_INDEX_PRIVILEGES, (policyName, filtersList) -> {
|
||||||
final Optional<EventFilterPolicy> policy = eventFilterPolicyRegistry.get(policyName);
|
final Optional<EventFilterPolicy> policy = eventFilterPolicyRegistry.get(policyName);
|
||||||
final EventFilterPolicy newPolicy = policy.orElse(new EventFilterPolicy(policyName, settings)).
|
final EventFilterPolicy newPolicy = policy.orElse(new EventFilterPolicy(policyName, settings)).
|
||||||
changePrivilegesFilter(filtersList);
|
changeIndexPrivilegesFilter(filtersList);
|
||||||
|
this.eventFilterPolicyRegistry.set(policyName, newPolicy);
|
||||||
|
}, (policyName, filtersList) -> EventFilterPolicy.parsePredicate(filtersList));
|
||||||
|
clusterService.getClusterSettings().addAffixUpdateConsumer(FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES, (policyName, filtersList) -> {
|
||||||
|
final Optional<EventFilterPolicy> policy = eventFilterPolicyRegistry.get(policyName);
|
||||||
|
final EventFilterPolicy newPolicy = policy.orElse(new EventFilterPolicy(policyName, settings)).
|
||||||
|
changeClusterPrivilegesFilter(filtersList);
|
||||||
this.eventFilterPolicyRegistry.set(policyName, newPolicy);
|
this.eventFilterPolicyRegistry.set(policyName, newPolicy);
|
||||||
}, (policyName, filtersList) -> EventFilterPolicy.parsePredicate(filtersList));
|
}, (policyName, filtersList) -> EventFilterPolicy.parsePredicate(filtersList));
|
||||||
// this log filter ensures that audit events are not filtered out because of the log level
|
// this log filter ensures that audit events are not filtered out because of the log level
|
||||||
|
@ -1345,13 +1355,15 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
settings.add(FILTER_POLICY_IGNORE_INDICES);
|
settings.add(FILTER_POLICY_IGNORE_INDICES);
|
||||||
settings.add(FILTER_POLICY_IGNORE_ROLES);
|
settings.add(FILTER_POLICY_IGNORE_ROLES);
|
||||||
settings.add(FILTER_POLICY_IGNORE_REALMS);
|
settings.add(FILTER_POLICY_IGNORE_REALMS);
|
||||||
settings.add(FILTER_POLICY_IGNORE_PRIVILEGES);
|
settings.add(FILTER_POLICY_IGNORE_INDEX_PRIVILEGES);
|
||||||
|
settings.add(FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the predicate for a single policy filter. The predicate matches events
|
* Builds the predicate for a single policy filter. The predicate matches events
|
||||||
* that will be ignored, aka filtered out, aka not logged. The event can be
|
* that will be ignored, aka filtered out, aka not logged. The event can be
|
||||||
* filtered by the following fields : `user`, `realm`, `role` and `index`.
|
* filtered by the following fields : `user`, `realm`, `role`, `index`, and
|
||||||
|
* (`index_privilege` or `cluster_privilege`).
|
||||||
* Predicates on each field are ANDed together to form the filter predicate of
|
* Predicates on each field are ANDed together to form the filter predicate of
|
||||||
* the policy.
|
* the policy.
|
||||||
*/
|
*/
|
||||||
|
@ -1361,14 +1373,25 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
private final Predicate<String> ignoreRealmsPredicate;
|
private final Predicate<String> ignoreRealmsPredicate;
|
||||||
private final Predicate<String> ignoreRolesPredicate;
|
private final Predicate<String> ignoreRolesPredicate;
|
||||||
private final Predicate<String> ignoreIndicesPredicate;
|
private final Predicate<String> ignoreIndicesPredicate;
|
||||||
private final Predicate<String> ignorePrivilegesPredicate;
|
private final Predicate<String> ignoreIndexPrivilegesPredicate;
|
||||||
|
private final Predicate<String> ignoreClusterPrivilegesPredicate;
|
||||||
|
|
||||||
EventFilterPolicy(String name, Settings settings) {
|
EventFilterPolicy(String name, Settings settings) {
|
||||||
this(name, parsePredicate(FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace(name).get(settings)),
|
this(name, parsePredicate(FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace(name).get(settings)),
|
||||||
parsePredicate(FILTER_POLICY_IGNORE_REALMS.getConcreteSettingForNamespace(name).get(settings)),
|
parsePredicate(FILTER_POLICY_IGNORE_REALMS.getConcreteSettingForNamespace(name).get(settings)),
|
||||||
parsePredicate(FILTER_POLICY_IGNORE_ROLES.getConcreteSettingForNamespace(name).get(settings)),
|
parsePredicate(FILTER_POLICY_IGNORE_ROLES.getConcreteSettingForNamespace(name).get(settings)),
|
||||||
parsePredicate(FILTER_POLICY_IGNORE_INDICES.getConcreteSettingForNamespace(name).get(settings)),
|
parsePredicate(FILTER_POLICY_IGNORE_INDICES.getConcreteSettingForNamespace(name).get(settings)),
|
||||||
parsePredicate(FILTER_POLICY_IGNORE_PRIVILEGES.getConcreteSettingForNamespace(name).get(settings)));
|
parsePredicate(FILTER_POLICY_IGNORE_INDEX_PRIVILEGES.getConcreteSettingForNamespace(name).get(settings)),
|
||||||
|
parsePredicate(FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES.getConcreteSettingForNamespace(name).get(settings)));
|
||||||
|
|
||||||
|
if (FILTER_POLICY_IGNORE_INDEX_PRIVILEGES.getConcreteSettingForNamespace(name).exists(settings) &&
|
||||||
|
FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES.getConcreteSettingForNamespace(name).exists(settings)) {
|
||||||
|
final String message = String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Both Index and Cluster privilege ignore filters are set for policy [%s]. " +
|
||||||
|
"Please update your configuration settings and remove one of these filters to avoid ambiguity.", this.name);
|
||||||
|
throw new IllegalArgumentException(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1378,39 +1401,45 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
*/
|
*/
|
||||||
EventFilterPolicy(String name, Predicate<String> ignorePrincipalsPredicate, Predicate<String> ignoreRealmsPredicate,
|
EventFilterPolicy(String name, Predicate<String> ignorePrincipalsPredicate, Predicate<String> ignoreRealmsPredicate,
|
||||||
Predicate<String> ignoreRolesPredicate, Predicate<String> ignoreIndicesPredicate,
|
Predicate<String> ignoreRolesPredicate, Predicate<String> ignoreIndicesPredicate,
|
||||||
Predicate<String> ignoreActionsPredicate) {
|
Predicate<String> ignoreIndexPrivilegesPredicate, Predicate<String> ignoreClusterPrivilegesPredicate) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
// "null" values are "unexpected" and should not match any ignore policy
|
// "null" values are "unexpected" and should not match any ignore policy
|
||||||
this.ignorePrincipalsPredicate = ignorePrincipalsPredicate;
|
this.ignorePrincipalsPredicate = ignorePrincipalsPredicate;
|
||||||
this.ignoreRealmsPredicate = ignoreRealmsPredicate;
|
this.ignoreRealmsPredicate = ignoreRealmsPredicate;
|
||||||
this.ignoreRolesPredicate = ignoreRolesPredicate;
|
this.ignoreRolesPredicate = ignoreRolesPredicate;
|
||||||
this.ignoreIndicesPredicate = ignoreIndicesPredicate;
|
this.ignoreIndicesPredicate = ignoreIndicesPredicate;
|
||||||
this.ignorePrivilegesPredicate = ignoreActionsPredicate;
|
this.ignoreIndexPrivilegesPredicate = ignoreIndexPrivilegesPredicate;
|
||||||
|
this.ignoreClusterPrivilegesPredicate = ignoreClusterPrivilegesPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventFilterPolicy changePrincipalsFilter(List<String> filtersList) {
|
private EventFilterPolicy changePrincipalsFilter(List<String> filtersList) {
|
||||||
return new EventFilterPolicy(name, parsePredicate(filtersList), ignoreRealmsPredicate, ignoreRolesPredicate,
|
return new EventFilterPolicy(name, parsePredicate(filtersList), ignoreRealmsPredicate, ignoreRolesPredicate,
|
||||||
ignoreIndicesPredicate, ignorePrivilegesPredicate);
|
ignoreIndicesPredicate, ignoreIndexPrivilegesPredicate, ignoreClusterPrivilegesPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventFilterPolicy changeRealmsFilter(List<String> filtersList) {
|
private EventFilterPolicy changeRealmsFilter(List<String> filtersList) {
|
||||||
return new EventFilterPolicy(name, ignorePrincipalsPredicate, parsePredicate(filtersList), ignoreRolesPredicate,
|
return new EventFilterPolicy(name, ignorePrincipalsPredicate, parsePredicate(filtersList), ignoreRolesPredicate,
|
||||||
ignoreIndicesPredicate, ignorePrivilegesPredicate);
|
ignoreIndicesPredicate, ignoreIndexPrivilegesPredicate, ignoreClusterPrivilegesPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventFilterPolicy changeRolesFilter(List<String> filtersList) {
|
private EventFilterPolicy changeRolesFilter(List<String> filtersList) {
|
||||||
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, parsePredicate(filtersList),
|
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, parsePredicate(filtersList),
|
||||||
ignoreIndicesPredicate, ignorePrivilegesPredicate);
|
ignoreIndicesPredicate, ignoreIndexPrivilegesPredicate, ignoreClusterPrivilegesPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventFilterPolicy changeIndicesFilter(List<String> filtersList) {
|
private EventFilterPolicy changeIndicesFilter(List<String> filtersList) {
|
||||||
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, ignoreRolesPredicate,
|
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, ignoreRolesPredicate,
|
||||||
parsePredicate(filtersList), ignorePrivilegesPredicate);
|
parsePredicate(filtersList), ignoreIndexPrivilegesPredicate, ignoreClusterPrivilegesPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventFilterPolicy changePrivilegesFilter(List<String> filtersList) {
|
private EventFilterPolicy changeIndexPrivilegesFilter(List<String> filtersList) {
|
||||||
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, ignoreRolesPredicate,
|
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, ignoreRolesPredicate,
|
||||||
ignoreIndicesPredicate, parsePredicate(filtersList));
|
ignoreIndicesPredicate, parsePredicate(filtersList), ignoreClusterPrivilegesPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventFilterPolicy changeClusterPrivilegesFilter(List<String> filtersList) {
|
||||||
|
return new EventFilterPolicy(name, ignorePrincipalsPredicate, ignoreRealmsPredicate, ignoreRolesPredicate,
|
||||||
|
ignoreIndicesPredicate, ignoreIndexPrivilegesPredicate, parsePredicate(filtersList));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Predicate<String> parsePredicate(List<String> l) {
|
static Predicate<String> parsePredicate(List<String> l) {
|
||||||
|
@ -1430,14 +1459,16 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
return l.stream().map(f -> f.isEmpty() ? "//" : f).collect(Collectors.toList());
|
return l.stream().map(f -> f.isEmpty() ? "//" : f).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean ignorePrivilegesPredicateTest(String action) {
|
private boolean ignoreIndexPrivilegesPredicateTest(String action) {
|
||||||
Collection<String> privileges = null;
|
if (ignoreIndexPrivilegesPredicate.test(action)) return true;
|
||||||
if (AuthorizationService.isIndexAction(action)) {
|
Collection<String> privileges = IndexPrivilege.findPrivilegesThatGrant(action);
|
||||||
privileges = IndexPrivilege.findPrivilegesThatGrant(action);
|
return privileges != null && privileges.stream().anyMatch((s) -> ignoreIndexPrivilegesPredicate.test(s));
|
||||||
} else if (ClusterPrivilegeResolver.isClusterAction(action)) {
|
|
||||||
privileges = ClusterPrivilegeResolver.findPrivilegesThatGrant(action, null, null);
|
|
||||||
}
|
}
|
||||||
return privileges != null ? privileges.stream().anyMatch((s) -> ignorePrivilegesPredicate.test(s)) : false;
|
|
||||||
|
private boolean ignoreClusterPrivilegesPredicateTest(String action) {
|
||||||
|
if (ignoreClusterPrivilegesPredicate.test(action)) return true;
|
||||||
|
Collection<String> privileges = ClusterPrivilegeResolver.findPrivilegesThatGrant(action, null, null);
|
||||||
|
return privileges != null && privileges.stream().anyMatch((s) -> ignoreClusterPrivilegesPredicate.test(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1448,8 +1479,8 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
Predicate<AuditEventMetaInfo> ignorePredicate() {
|
Predicate<AuditEventMetaInfo> ignorePredicate() {
|
||||||
return eventInfo -> eventInfo.principal != null && ignorePrincipalsPredicate.test(eventInfo.principal)
|
return eventInfo -> eventInfo.principal != null && ignorePrincipalsPredicate.test(eventInfo.principal)
|
||||||
&& eventInfo.realm != null && ignoreRealmsPredicate.test(eventInfo.realm)
|
&& eventInfo.realm != null && ignoreRealmsPredicate.test(eventInfo.realm)
|
||||||
&& eventInfo.action != null && (ignorePrivilegesPredicate.test(eventInfo.action) ||
|
&& eventInfo.action != null && (ignoreIndexPrivilegesPredicateTest(eventInfo.action) &&
|
||||||
ignorePrivilegesPredicateTest(eventInfo.action))
|
ignoreClusterPrivilegesPredicateTest(eventInfo.action))
|
||||||
&& eventInfo.roles.get().allMatch(role -> role != null && ignoreRolesPredicate.test(role))
|
&& eventInfo.roles.get().allMatch(role -> role != null && ignoreRolesPredicate.test(role))
|
||||||
&& eventInfo.indices.get().allMatch(index -> index != null && ignoreIndicesPredicate.test(index));
|
&& eventInfo.indices.get().allMatch(index -> index != null && ignoreIndicesPredicate.test(index));
|
||||||
}
|
}
|
||||||
|
@ -1457,8 +1488,8 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[users]:" + ignorePrincipalsPredicate.toString() + "&[realms]:" + ignoreRealmsPredicate.toString() + "&[roles]:"
|
return "[users]:" + ignorePrincipalsPredicate.toString() + "&[realms]:" + ignoreRealmsPredicate.toString() + "&[roles]:"
|
||||||
+ ignoreRolesPredicate.toString() + "&[indices]:" + ignoreIndicesPredicate.toString() + "&[actions]:"
|
+ ignoreRolesPredicate.toString() + "&[indices]:" + ignoreIndicesPredicate.toString() + "&[index privileges]:"
|
||||||
+ ignorePrivilegesPredicate.toString();
|
+ ignoreIndexPrivilegesPredicate.toString() + "&[cluster privileges]:" + ignoreClusterPrivilegesPredicate.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail.PRINCIPAL_ROLES_FIELD_NAME;
|
import static org.elasticsearch.xpack.security.audit.logfile.LoggingAuditTrail.PRINCIPAL_ROLES_FIELD_NAME;
|
||||||
import static org.elasticsearch.xpack.security.authc.ApiKeyServiceTests.Utils.createApiKeyAuthentication;
|
import static org.elasticsearch.xpack.security.authc.ApiKeyServiceTests.Utils.createApiKeyAuthentication;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.hasToString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
@ -125,10 +127,17 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
final List<String> filteredIndices = randomNonEmptyListOfFilteredNames();
|
final List<String> filteredIndices = randomNonEmptyListOfFilteredNames();
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.indicesPolicy.indices", filteredIndices);
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.indicesPolicy.indices", filteredIndices);
|
||||||
// filter by privileges
|
// filter by privileges
|
||||||
final List<String> filteredActions = randomNonEmptyListOfFilteredActions();
|
final boolean clusterActionsFilter = randomBoolean();
|
||||||
|
final List<String> filteredActions = clusterActionsFilter? randomNonEmptyListOfFilteredClusterActions() :
|
||||||
|
randomNonEmptyListOfFilteredIndexActions();
|
||||||
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.privilegesPolicy.privileges",
|
if (clusterActionsFilter) {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.privilegesPolicy.cluster_privileges",
|
||||||
randomBoolean() ? filteredPrivileges : filteredActions);
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
} else {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.privilegesPolicy.index_privileges",
|
||||||
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
}
|
||||||
|
|
||||||
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
||||||
|
|
||||||
|
@ -216,10 +225,17 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
final List<String> filteredIndices = randomNonEmptyListOfFilteredNames();
|
final List<String> filteredIndices = randomNonEmptyListOfFilteredNames();
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.indices", filteredIndices);
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.indices", filteredIndices);
|
||||||
// filter by privileges
|
// filter by privileges
|
||||||
final List<String> filteredActions = randomNonEmptyListOfFilteredActions();
|
final boolean clusterActionsFilter = randomBoolean();
|
||||||
|
final List<String> filteredActions = clusterActionsFilter? randomNonEmptyListOfFilteredClusterActions() :
|
||||||
|
randomNonEmptyListOfFilteredIndexActions();
|
||||||
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.privileges",
|
if (clusterActionsFilter) {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.cluster_privileges",
|
||||||
randomBoolean() ? filteredPrivileges : filteredActions);
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
} else {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.index_privileges",
|
||||||
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
}
|
||||||
|
|
||||||
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
||||||
|
|
||||||
|
@ -342,10 +358,17 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.indices", filteredIndices);
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.indices", filteredIndices);
|
||||||
filteredIndices.remove("");
|
filteredIndices.remove("");
|
||||||
// filter by privileges
|
// filter by privileges
|
||||||
final List<String> filteredActions = randomNonEmptyListOfFilteredActions();
|
final boolean clusterActionsFilter = randomBoolean();
|
||||||
|
final List<String> filteredActions = clusterActionsFilter? randomNonEmptyListOfFilteredClusterActions() :
|
||||||
|
randomNonEmptyListOfFilteredIndexActions();
|
||||||
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
final List<String> filteredPrivileges = randomNonEmptyListOfFilteredPrivileges(filteredActions);
|
||||||
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.privileges",
|
if (clusterActionsFilter) {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.cluster_privileges",
|
||||||
randomBoolean() ? filteredPrivileges : filteredActions);
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
} else {
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.completeFilterPolicy.index_privileges",
|
||||||
|
randomBoolean() ? filteredPrivileges : filteredActions);
|
||||||
|
}
|
||||||
|
|
||||||
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext);
|
||||||
|
|
||||||
|
@ -1885,6 +1908,21 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
threadContext.stashContext();
|
threadContext.stashContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBothClusterAndIndexFiltersExist() throws Exception {
|
||||||
|
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO, null);
|
||||||
|
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
|
// create complete filter policy
|
||||||
|
final Settings.Builder settingsBuilder = Settings.builder().put(settings);
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.privilegesPolicy.cluster_privileges",
|
||||||
|
"monitor");
|
||||||
|
settingsBuilder.putList("xpack.security.audit.logfile.events.ignore_filters.privilegesPolicy.index_privileges",
|
||||||
|
"read");
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||||
|
() -> new LoggingAuditTrail(settingsBuilder.build(), clusterService, logger, threadContext));
|
||||||
|
assertThat(e, hasToString(containsString("Both Index and Cluster privilege ignore filters are set for policy " +
|
||||||
|
"[privilegesPolicy]. Please update your configuration settings and remove one of these filters to avoid ambiguity.")));
|
||||||
|
}
|
||||||
|
|
||||||
private <T> List<T> randomListFromLengthBetween(List<T> l, int min, int max) {
|
private <T> List<T> randomListFromLengthBetween(List<T> l, int min, int max) {
|
||||||
assert (min >= 0) && (min <= max) && (max <= l.size());
|
assert (min >= 0) && (min <= max) && (max <= l.size());
|
||||||
final int len = randomIntBetween(min, max);
|
final int len = randomIntBetween(min, max);
|
||||||
|
@ -1919,7 +1957,7 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> randomNonEmptyListOfFilteredActions() {
|
private List<String> randomNonEmptyListOfFilteredIndexActions() {
|
||||||
final List<String> filtered = new ArrayList<>(4);
|
final List<String> filtered = new ArrayList<>(4);
|
||||||
final String[] actionPatterns = {
|
final String[] actionPatterns = {
|
||||||
"internal:transport/proxy/indices:*",
|
"internal:transport/proxy/indices:*",
|
||||||
|
@ -1940,11 +1978,24 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
"indices:admin/flush*",
|
"indices:admin/flush*",
|
||||||
"indices:admin/synced_flush",
|
"indices:admin/synced_flush",
|
||||||
"indices:admin/forcemerge*",
|
"indices:admin/forcemerge*",
|
||||||
|
"indices:admin/index_template/*",
|
||||||
|
"indices:admin/data_stream/*",
|
||||||
|
"indices:admin/template/*",};
|
||||||
|
Random random = random();
|
||||||
|
for (int i = 0; i < randomIntBetween(1, 4); i++) {
|
||||||
|
Object name = actionPatterns[random.nextInt(actionPatterns.length)];
|
||||||
|
filtered.add((String)name);
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> randomNonEmptyListOfFilteredClusterActions() {
|
||||||
|
final List<String> filtered = new ArrayList<>(4);
|
||||||
|
final String[] actionPatterns = {
|
||||||
"cluster:admin/xpack/security/*",
|
"cluster:admin/xpack/security/*",
|
||||||
"cluster:admin/xpack/security/saml/*",
|
"cluster:admin/xpack/security/saml/*",
|
||||||
"cluster:admin/xpack/security/oidc/*",
|
"cluster:admin/xpack/security/oidc/*",
|
||||||
"cluster:admin/xpack/security/token/*",
|
"cluster:admin/xpack/security/token/*",
|
||||||
"cluster:admin/xpack/security/api_key/*",
|
|
||||||
"cluster:monitor/*",
|
"cluster:monitor/*",
|
||||||
"cluster:monitor/xpack/ml/*",
|
"cluster:monitor/xpack/ml/*",
|
||||||
"cluster:monitor/text_structure/*",
|
"cluster:monitor/text_structure/*",
|
||||||
|
@ -1952,8 +2003,6 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
"cluster:monitor/xpack/watcher/*",
|
"cluster:monitor/xpack/watcher/*",
|
||||||
"cluster:monitor/xpack/rollup/*",
|
"cluster:monitor/xpack/rollup/*",
|
||||||
"cluster:*",
|
"cluster:*",
|
||||||
"indices:admin/index_template/*",
|
|
||||||
"indices:admin/data_stream/*",
|
|
||||||
"cluster:admin/xpack/ml/*",
|
"cluster:admin/xpack/ml/*",
|
||||||
"cluster:admin/data_frame/*",
|
"cluster:admin/data_frame/*",
|
||||||
"cluster:monitor/data_frame/*",
|
"cluster:monitor/data_frame/*",
|
||||||
|
@ -1962,7 +2011,6 @@ public class LoggingAuditTrailFilterTests extends ESTestCase {
|
||||||
"cluster:admin/xpack/watcher/*",
|
"cluster:admin/xpack/watcher/*",
|
||||||
"cluster:monitor/nodes/liveness",
|
"cluster:monitor/nodes/liveness",
|
||||||
"cluster:monitor/state",
|
"cluster:monitor/state",
|
||||||
"indices:admin/template/*",
|
|
||||||
"cluster:admin/component_template/*",
|
"cluster:admin/component_template/*",
|
||||||
"cluster:admin/ingest/pipeline/*",
|
"cluster:admin/ingest/pipeline/*",
|
||||||
"cluster:admin/xpack/rollup/*",
|
"cluster:admin/xpack/rollup/*",
|
||||||
|
|
|
@ -272,8 +272,8 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||||
LoggingAuditTrail.INCLUDE_EVENT_SETTINGS, LoggingAuditTrail.EXCLUDE_EVENT_SETTINGS,
|
LoggingAuditTrail.INCLUDE_EVENT_SETTINGS, LoggingAuditTrail.EXCLUDE_EVENT_SETTINGS,
|
||||||
LoggingAuditTrail.INCLUDE_REQUEST_BODY, LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS,
|
LoggingAuditTrail.INCLUDE_REQUEST_BODY, LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS,
|
||||||
LoggingAuditTrail.FILTER_POLICY_IGNORE_REALMS, LoggingAuditTrail.FILTER_POLICY_IGNORE_ROLES,
|
LoggingAuditTrail.FILTER_POLICY_IGNORE_REALMS, LoggingAuditTrail.FILTER_POLICY_IGNORE_ROLES,
|
||||||
LoggingAuditTrail.FILTER_POLICY_IGNORE_INDICES, LoggingAuditTrail.FILTER_POLICY_IGNORE_PRIVILEGES,
|
LoggingAuditTrail.FILTER_POLICY_IGNORE_INDICES, LoggingAuditTrail.FILTER_POLICY_IGNORE_INDEX_PRIVILEGES,
|
||||||
Loggers.LOG_LEVEL_SETTING));
|
LoggingAuditTrail.FILTER_POLICY_IGNORE_CLUSTER_PRIVILEGES, Loggers.LOG_LEVEL_SETTING));
|
||||||
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
|
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
|
||||||
commonFields = new LoggingAuditTrail.EntryCommonFields(settings, localNode).commonFields;
|
commonFields = new LoggingAuditTrail.EntryCommonFields(settings, localNode).commonFields;
|
||||||
threadContext = new ThreadContext(Settings.EMPTY);
|
threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
|
@ -345,11 +345,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||||
|
|
||||||
Settings settings5 = Settings.builder()
|
Settings settings5 = Settings.builder()
|
||||||
.putList(prefix + "ignore_filters.filter2.users", Arrays.asList("tom", "cruise"))
|
.putList(prefix + "ignore_filters.filter2.users", Arrays.asList("tom", "cruise"))
|
||||||
.putList(prefix + "ignore_filters.filter2.privileges", Arrays.asList("read", "/foo")).build();
|
.putList(prefix + "ignore_filters.filter2.index_privileges", Arrays.asList("read", "/foo")).build();
|
||||||
assertThat(LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace("filter2").get(settings5),
|
assertThat(LoggingAuditTrail.FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace("filter2").get(settings5),
|
||||||
containsInAnyOrder("tom", "cruise"));
|
containsInAnyOrder("tom", "cruise"));
|
||||||
e = expectThrows(IllegalArgumentException.class,
|
e = expectThrows(IllegalArgumentException.class,
|
||||||
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_PRIVILEGES.getConcreteSettingForNamespace("filter2").get(settings5));
|
() -> LoggingAuditTrail.FILTER_POLICY_IGNORE_INDEX_PRIVILEGES.getConcreteSettingForNamespace("filter2").get(settings5));
|
||||||
assertThat(e, hasToString(containsString("invalid pattern [/foo]")));
|
assertThat(e, hasToString(containsString("invalid pattern [/foo]")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue