Update the audit logfile list of system users (#55578)
Out of the box "access granted" audit events are not logged for system users. The list of system users was stale and included only the _system and _xpack users. This commit expands this list with _xpack_security and _async_search, effectively reducing the auditing noise by not logging the audit events of these system users out of the box. Closes #37924
This commit is contained in:
parent
c370b83bd7
commit
82ed0ab420
|
@ -210,6 +210,10 @@ public class User implements ToXContentObject {
|
|||
output.writeBoolean(false); // last user written, regardless of bwc, does not have an inner user
|
||||
}
|
||||
|
||||
public static boolean isInternal(User user) {
|
||||
return SystemUser.is(user) || XPackUser.is(user) || XPackSecurityUser.is(user) || AsyncSearchUser.is(user);
|
||||
}
|
||||
|
||||
/** Write just the given {@link User}, but not the inner {@link #authenticatedUser}. */
|
||||
private static void writeUser(User user, StreamOutput output) throws IOException {
|
||||
output.writeBoolean(false); // not a system user
|
||||
|
|
|
@ -35,9 +35,7 @@ import org.elasticsearch.transport.TransportRequest;
|
|||
import org.elasticsearch.xpack.core.security.authc.Authentication;
|
||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
|
||||
import org.elasticsearch.xpack.core.security.support.Automatons;
|
||||
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
||||
import org.elasticsearch.xpack.core.security.user.User;
|
||||
import org.elasticsearch.xpack.core.security.user.XPackUser;
|
||||
import org.elasticsearch.xpack.security.Security;
|
||||
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
||||
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||
|
@ -446,7 +444,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
|||
public void accessGranted(String requestId, Authentication authentication, String action, TransportRequest msg,
|
||||
AuthorizationInfo authorizationInfo) {
|
||||
final User user = authentication.getUser();
|
||||
final boolean isSystem = SystemUser.is(user) || XPackUser.is(user);
|
||||
final boolean isSystem = User.isInternal(user);
|
||||
if ((isSystem && events.contains(SYSTEM_ACCESS_GRANTED)) || ((isSystem == false) && events.contains(ACCESS_GRANTED))) {
|
||||
final Optional<String[]> indices = indices(msg);
|
||||
if (eventFilterPolicyRegistry.ignorePredicate().test(new AuditEventMetaInfo(Optional.of(user),
|
||||
|
@ -475,8 +473,7 @@ public class LoggingAuditTrail implements AuditTrail, ClusterStateListener {
|
|||
assert eventType == ACCESS_DENIED || eventType == AuditLevel.ACCESS_GRANTED || eventType == SYSTEM_ACCESS_GRANTED;
|
||||
final String[] indices = index == null ? null : new String[] { index };
|
||||
final User user = authentication.getUser();
|
||||
final boolean isSystem = SystemUser.is(user) || XPackUser.is(user);
|
||||
if (isSystem && eventType == ACCESS_GRANTED) {
|
||||
if (User.isInternal(user) && eventType == ACCESS_GRANTED) {
|
||||
eventType = SYSTEM_ACCESS_GRANTED;
|
||||
}
|
||||
if (events.contains(eventType)) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.apache.logging.log4j.Level;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.bulk.BulkItemRequest;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
|
@ -37,8 +38,12 @@ import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger;
|
|||
import org.elasticsearch.xpack.core.security.authc.Authentication;
|
||||
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
|
||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
|
||||
import org.elasticsearch.xpack.core.security.user.AsyncSearchUser;
|
||||
import org.elasticsearch.xpack.core.security.user.SystemUser;
|
||||
import org.elasticsearch.xpack.core.security.user.User;
|
||||
import org.elasticsearch.xpack.core.security.user.XPackSecurityUser;
|
||||
import org.elasticsearch.xpack.core.security.user.XPackUser;
|
||||
import org.elasticsearch.xpack.security.audit.AuditLevel;
|
||||
import org.elasticsearch.xpack.security.audit.AuditTrail;
|
||||
import org.elasticsearch.xpack.security.audit.AuditUtil;
|
||||
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationInfo;
|
||||
|
@ -571,11 +576,78 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
|||
assertEmptyLog(logger);
|
||||
}
|
||||
|
||||
public void testSystemAccessGranted() throws Exception {
|
||||
final TransportRequest request = randomBoolean() ? new MockRequest(threadContext) : new MockIndicesRequest(threadContext);
|
||||
final String[] expectedRoles = randomArray(0, 4, String[]::new, () -> randomBoolean() ? null : randomAlphaOfLengthBetween(1, 4));
|
||||
final AuthorizationInfo authorizationInfo = () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, expectedRoles);
|
||||
final User systemUser = randomFrom(SystemUser.INSTANCE, XPackUser.INSTANCE, XPackSecurityUser.INSTANCE, AsyncSearchUser.INSTANCE);
|
||||
final Authentication authentication = new Authentication(systemUser, new RealmRef("_reserved", "test", "foo"), null);
|
||||
final String requestId = randomRequestId();
|
||||
|
||||
auditTrail.accessGranted(requestId, authentication, "_action", request, authorizationInfo);
|
||||
// system user
|
||||
assertEmptyLog(logger);
|
||||
auditTrail.explicitIndexAccessEvent(requestId, randomFrom(AuditLevel.ACCESS_GRANTED, AuditLevel.SYSTEM_ACCESS_GRANTED),
|
||||
authentication, "_action", randomFrom(randomAlphaOfLengthBetween(1, 4), null),
|
||||
BulkItemRequest.class.getName(),
|
||||
request.remoteAddress(),
|
||||
authorizationInfo);
|
||||
// system user
|
||||
assertEmptyLog(logger);
|
||||
|
||||
// enable system user for access granted events
|
||||
settings = Settings.builder()
|
||||
.put(settings)
|
||||
.put("xpack.security.audit.logfile.events.include", "system_access_granted")
|
||||
.build();
|
||||
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
|
||||
|
||||
auditTrail.accessGranted(requestId, authentication, "_action", request, authorizationInfo);
|
||||
|
||||
MapBuilder<String, String> checkedFields = new MapBuilder<>(commonFields);
|
||||
MapBuilder<String, String[]> checkedArrayFields = new MapBuilder<>();
|
||||
checkedFields.put(LoggingAuditTrail.EVENT_TYPE_FIELD_NAME, LoggingAuditTrail.TRANSPORT_ORIGIN_FIELD_VALUE)
|
||||
.put(LoggingAuditTrail.EVENT_ACTION_FIELD_NAME, "access_granted")
|
||||
.put(LoggingAuditTrail.ACTION_FIELD_NAME, "_action")
|
||||
.put(LoggingAuditTrail.REQUEST_NAME_FIELD_NAME, request.getClass().getSimpleName())
|
||||
.put(LoggingAuditTrail.REQUEST_ID_FIELD_NAME, requestId);
|
||||
checkedArrayFields.put(PRINCIPAL_ROLES_FIELD_NAME, (String[]) authorizationInfo.asMap().get(PRINCIPAL_ROLES_FIELD_NAME));
|
||||
subject(authentication, checkedFields);
|
||||
restOrTransportOrigin(request, threadContext, checkedFields);
|
||||
indicesRequest(request, checkedFields, checkedArrayFields);
|
||||
opaqueId(threadContext, checkedFields);
|
||||
forwardedFor(threadContext, checkedFields);
|
||||
assertMsg(logger, checkedFields.immutableMap(), checkedArrayFields.immutableMap());
|
||||
clearLog();
|
||||
|
||||
String index = randomFrom(randomAlphaOfLengthBetween(1, 4), null);
|
||||
auditTrail.explicitIndexAccessEvent(requestId, randomFrom(AuditLevel.ACCESS_GRANTED, AuditLevel.SYSTEM_ACCESS_GRANTED),
|
||||
authentication, "_action", index, BulkItemRequest.class.getName(), request.remoteAddress(), authorizationInfo);
|
||||
|
||||
checkedFields = new MapBuilder<>(commonFields);
|
||||
checkedArrayFields = new MapBuilder<>();
|
||||
checkedFields.put(LoggingAuditTrail.EVENT_TYPE_FIELD_NAME, LoggingAuditTrail.TRANSPORT_ORIGIN_FIELD_VALUE)
|
||||
.put(LoggingAuditTrail.EVENT_ACTION_FIELD_NAME, "access_granted")
|
||||
.put(LoggingAuditTrail.ACTION_FIELD_NAME, "_action")
|
||||
.put(LoggingAuditTrail.REQUEST_NAME_FIELD_NAME, BulkItemRequest.class.getName())
|
||||
.put(LoggingAuditTrail.REQUEST_ID_FIELD_NAME, requestId);
|
||||
checkedArrayFields.put(PRINCIPAL_ROLES_FIELD_NAME, (String[]) authorizationInfo.asMap().get(PRINCIPAL_ROLES_FIELD_NAME));
|
||||
subject(authentication, checkedFields);
|
||||
restOrTransportOrigin(request, threadContext, checkedFields);
|
||||
opaqueId(threadContext, checkedFields);
|
||||
forwardedFor(threadContext, checkedFields);
|
||||
if (index != null) {
|
||||
checkedArrayFields.put(LoggingAuditTrail.INDICES_FIELD_NAME, new String[]{index});
|
||||
}
|
||||
assertMsg(logger, checkedFields.immutableMap(), checkedArrayFields.immutableMap());
|
||||
}
|
||||
|
||||
public void testAccessGrantedInternalSystemAction() throws Exception {
|
||||
final TransportRequest request = randomBoolean() ? new MockRequest(threadContext) : new MockIndicesRequest(threadContext);
|
||||
final String[] expectedRoles = randomArray(0, 4, String[]::new, () -> randomBoolean() ? null : randomAlphaOfLengthBetween(1, 4));
|
||||
final AuthorizationInfo authorizationInfo = () -> Collections.singletonMap(PRINCIPAL_ROLES_FIELD_NAME, expectedRoles);
|
||||
final Authentication authentication = new Authentication(SystemUser.INSTANCE, new RealmRef("_reserved", "test", "foo"), null);
|
||||
final User systemUser = randomFrom(SystemUser.INSTANCE, XPackUser.INSTANCE, XPackSecurityUser.INSTANCE, AsyncSearchUser.INSTANCE);
|
||||
final Authentication authentication = new Authentication(systemUser, new RealmRef("_reserved", "test", "foo"), null);
|
||||
final String requestId = randomRequestId();
|
||||
auditTrail.accessGranted(requestId, authentication, "internal:_action", request, authorizationInfo);
|
||||
assertEmptyLog(logger);
|
||||
|
@ -591,7 +663,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
|||
final MapBuilder<String, String[]> checkedArrayFields = new MapBuilder<>();
|
||||
checkedFields.put(LoggingAuditTrail.EVENT_TYPE_FIELD_NAME, LoggingAuditTrail.TRANSPORT_ORIGIN_FIELD_VALUE)
|
||||
.put(LoggingAuditTrail.EVENT_ACTION_FIELD_NAME, "access_granted")
|
||||
.put(LoggingAuditTrail.PRINCIPAL_FIELD_NAME, SystemUser.INSTANCE.principal())
|
||||
.put(LoggingAuditTrail.PRINCIPAL_FIELD_NAME, systemUser.principal())
|
||||
.put(LoggingAuditTrail.PRINCIPAL_REALM_FIELD_NAME, "_reserved")
|
||||
.put(LoggingAuditTrail.ACTION_FIELD_NAME, "internal:_action")
|
||||
.put(LoggingAuditTrail.REQUEST_NAME_FIELD_NAME, request.getClass().getSimpleName())
|
||||
|
|
Loading…
Reference in New Issue