security: make control of logfile audit output consistent with index output

This change moves the logfile audit output from determining what to log based on the
logger level to a enum based configuration that is used by the index output.

A few notable changes were made:

* We alway log all the information we have except for the request body
* The request body is no longer logged by default for REST events; the user needs to
explicitly opt in as there could be sensitive data in the body
* Added a `realm_authentication_failed` event that separates overall authentication
failure from that of an individual realm

Original commit: elastic/x-pack-elasticsearch@343a2bcdd9
This commit is contained in:
jaymode 2016-09-02 13:37:30 -04:00
parent 89ce4ebb08
commit 7965608add
10 changed files with 663 additions and 794 deletions

View File

@ -3,7 +3,7 @@ appender.audit_rolling.name = audit_rolling
appender.audit_rolling.fileName = ${sys:es.logs}_access.log
appender.audit_rolling.layout.type = PatternLayout
appender.audit_rolling.layout.pattern = [%d{ISO8601}] %m%n
appender.audit_rolling.filePattern = ${sys:es.logs}-%d{yyyy-MM-dd}.log
appender.audit_rolling.filePattern = ${sys:es.logs}_access-%d{yyyy-MM-dd}.log
appender.audit_rolling.policies.type = Policies
appender.audit_rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.audit_rolling.policies.time.interval = 1

View File

@ -3,17 +3,18 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.audit.index;
package org.elasticsearch.xpack.security.audit;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
public enum IndexAuditLevel {
public enum AuditLevel {
ANONYMOUS_ACCESS_DENIED,
AUTHENTICATION_FAILED,
REALM_AUTHENTICATION_FAILED,
ACCESS_GRANTED,
ACCESS_DENIED,
TAMPERED_REQUEST,
@ -23,13 +24,13 @@ public enum IndexAuditLevel {
RUN_AS_GRANTED,
RUN_AS_DENIED;
static EnumSet<IndexAuditLevel> parse(List<String> levels) {
EnumSet<IndexAuditLevel> enumSet = EnumSet.noneOf(IndexAuditLevel.class);
static EnumSet<AuditLevel> parse(List<String> levels) {
EnumSet<AuditLevel> enumSet = EnumSet.noneOf(AuditLevel.class);
for (String level : levels) {
String lowerCaseLevel = level.trim().toLowerCase(Locale.ROOT);
switch (lowerCaseLevel) {
case "_all":
enumSet.addAll(Arrays.asList(IndexAuditLevel.values()));
enumSet.addAll(Arrays.asList(AuditLevel.values()));
break;
case "anonymous_access_denied":
enumSet.add(ANONYMOUS_ACCESS_DENIED);
@ -37,6 +38,9 @@ public enum IndexAuditLevel {
case "authentication_failed":
enumSet.add(AUTHENTICATION_FAILED);
break;
case "realm_authentication_failed":
enumSet.add(REALM_AUTHENTICATION_FAILED);
break;
case "access_granted":
enumSet.add(ACCESS_GRANTED);
break;
@ -68,9 +72,9 @@ public enum IndexAuditLevel {
return enumSet;
}
public static EnumSet<IndexAuditLevel> parse(List<String> includeLevels, List<String> excludeLevels) {
EnumSet<IndexAuditLevel> included = parse(includeLevels);
EnumSet<IndexAuditLevel> excluded = parse(excludeLevels);
public static EnumSet<AuditLevel> parse(List<String> includeLevels, List<String> excludeLevels) {
EnumSet<AuditLevel> included = parse(includeLevels);
EnumSet<AuditLevel> excluded = parse(excludeLevels);
included.removeAll(excluded);
return included;
}

View File

@ -51,6 +51,7 @@ import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportMessage;
import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.xpack.security.InternalClient;
import org.elasticsearch.xpack.security.audit.AuditLevel;
import org.elasticsearch.xpack.security.audit.AuditTrail;
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.security.authz.privilege.SystemPrivilege;
@ -85,19 +86,20 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import static org.elasticsearch.xpack.security.Security.setting;
import static org.elasticsearch.xpack.security.audit.AuditLevel.REALM_AUTHENTICATION_FAILED;
import static org.elasticsearch.xpack.security.audit.AuditUtil.indices;
import static org.elasticsearch.xpack.security.audit.AuditUtil.restRequestContent;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.ANONYMOUS_ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.AUTHENTICATION_FAILED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.CONNECTION_DENIED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.CONNECTION_GRANTED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.RUN_AS_DENIED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.RUN_AS_GRANTED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.SYSTEM_ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.TAMPERED_REQUEST;
import static org.elasticsearch.xpack.security.audit.index.IndexAuditLevel.parse;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ANONYMOUS_ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.AUTHENTICATION_FAILED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.CONNECTION_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.CONNECTION_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.RUN_AS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.RUN_AS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.SYSTEM_ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.TAMPERED_REQUEST;
import static org.elasticsearch.xpack.security.audit.AuditLevel.parse;
import static org.elasticsearch.xpack.security.audit.index.IndexNameResolver.resolve;
/**
@ -105,27 +107,30 @@ import static org.elasticsearch.xpack.security.audit.index.IndexNameResolver.res
*/
public class IndexAuditTrail extends AbstractComponent implements AuditTrail, ClusterStateListener {
public static final int DEFAULT_BULK_SIZE = 1000;
public static final int MAX_BULK_SIZE = 10000;
public static final int DEFAULT_MAX_QUEUE_SIZE = 1000;
public static final TimeValue DEFAULT_FLUSH_INTERVAL = TimeValue.timeValueSeconds(1);
public static final IndexNameResolver.Rollover DEFAULT_ROLLOVER = IndexNameResolver.Rollover.DAILY;
public static final String NAME = "index";
public static final String INDEX_NAME_PREFIX = ".security_audit_log";
public static final String DOC_TYPE = "event";
public static final Setting<IndexNameResolver.Rollover> ROLLOVER_SETTING =
public static final String INDEX_TEMPLATE_NAME = "security_audit_log";
private static final int DEFAULT_BULK_SIZE = 1000;
private static final int MAX_BULK_SIZE = 10000;
private static final int DEFAULT_MAX_QUEUE_SIZE = 1000;
private static final TimeValue DEFAULT_FLUSH_INTERVAL = TimeValue.timeValueSeconds(1);
private static final IndexNameResolver.Rollover DEFAULT_ROLLOVER = IndexNameResolver.Rollover.DAILY;
private static final Setting<IndexNameResolver.Rollover> ROLLOVER_SETTING =
new Setting<>(setting("audit.index.rollover"), (s) -> DEFAULT_ROLLOVER.name(),
s -> IndexNameResolver.Rollover.valueOf(s.toUpperCase(Locale.ENGLISH)), Property.NodeScope);
public static final Setting<Integer> QUEUE_SIZE_SETTING =
private static final Setting<Integer> QUEUE_SIZE_SETTING =
Setting.intSetting(setting("audit.index.queue_max_size"), DEFAULT_MAX_QUEUE_SIZE, 1, Property.NodeScope);
public static final String INDEX_TEMPLATE_NAME = "security_audit_log";
public static final String DEFAULT_CLIENT_NAME = "security-audit-client";
private static final String DEFAULT_CLIENT_NAME = "security-audit-client";
static final List<String> DEFAULT_EVENT_INCLUDES = Arrays.asList(
private static final List<String> DEFAULT_EVENT_INCLUDES = Arrays.asList(
ACCESS_DENIED.toString(),
ACCESS_GRANTED.toString(),
ANONYMOUS_ACCESS_DENIED.toString(),
AUTHENTICATION_FAILED.toString(),
REALM_AUTHENTICATION_FAILED.toString(),
CONNECTION_DENIED.toString(),
CONNECTION_GRANTED.toString(),
TAMPERED_REQUEST.toString(),
@ -134,23 +139,24 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
);
private static final String FORBIDDEN_INDEX_SETTING = "index.mapper.dynamic";
public static final Setting<Settings> INDEX_SETTINGS =
private static final Setting<Settings> INDEX_SETTINGS =
Setting.groupSetting(setting("audit.index.settings.index."), Property.NodeScope);
public static final Setting<List<String>> INCLUDE_EVENT_SETTINGS =
private static final Setting<List<String>> INCLUDE_EVENT_SETTINGS =
Setting.listSetting(setting("audit.index.events.include"), DEFAULT_EVENT_INCLUDES, Function.identity(),
Property.NodeScope);
public static final Setting<List<String>> EXCLUDE_EVENT_SETTINGS =
private static final Setting<List<String>> EXCLUDE_EVENT_SETTINGS =
Setting.listSetting(setting("audit.index.events.exclude"), Collections.emptyList(),
Function.identity(), Property.NodeScope);
public static final Setting<Settings> REMOTE_CLIENT_SETTINGS =
private static final Setting<Boolean> INCLUDE_REQUEST_BODY =
Setting.boolSetting(setting("audit.index.events.emit_request_body"), false, Property.NodeScope);
private static final Setting<Settings> REMOTE_CLIENT_SETTINGS =
Setting.groupSetting(setting("audit.index.client."), Property.NodeScope);
public static final Setting<Integer> BULK_SIZE_SETTING =
private static final Setting<Integer> BULK_SIZE_SETTING =
Setting.intSetting(setting("audit.index.bulk_size"), DEFAULT_BULK_SIZE, 1, MAX_BULK_SIZE, Property.NodeScope);
public static final Setting<TimeValue> FLUSH_TIMEOUT_SETTING =
private static final Setting<TimeValue> FLUSH_TIMEOUT_SETTING =
Setting.timeSetting(setting("audit.index.flush_interval"), DEFAULT_FLUSH_INTERVAL,
TimeValue.timeValueMillis(1L), Property.NodeScope);
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
private final String nodeName;
private final Client client;
@ -160,12 +166,13 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
private final Lock putMappingLock = new ReentrantLock();
private final ClusterService clusterService;
private final boolean indexToRemoteCluster;
private final EnumSet<AuditLevel> events;
private final IndexNameResolver.Rollover rollover;
private final boolean includeRequestBody;
private BulkProcessor bulkProcessor;
private IndexNameResolver.Rollover rollover;
private String nodeHostName;
private String nodeHostAddress;
private EnumSet<IndexAuditLevel> events;
@Override
public String name() {
@ -180,25 +187,10 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
this.queueConsumer = new QueueConsumer(EsExecutors.threadName(settings, "audit-queue-consumer"));
int maxQueueSize = QUEUE_SIZE_SETTING.get(settings);
this.eventQueue = createQueue(maxQueueSize);
// we have to initialize this here since we use rollover in determining if we can start...
rollover = ROLLOVER_SETTING.get(settings);
// we have to initialize the events here since we can receive events before starting...
List<String> includedEvents = INCLUDE_EVENT_SETTINGS.get(settings);
List<String> excludedEvents = EXCLUDE_EVENT_SETTINGS.get(settings);
try {
events = parse(includedEvents, excludedEvents);
} catch (IllegalArgumentException e) {
logger.warn(
(Supplier<?>) () -> new ParameterizedMessage(
"invalid event type specified, using default for audit index output. include events [{}], exclude events [{}]",
includedEvents,
excludedEvents),
e);
events = parse(DEFAULT_EVENT_INCLUDES, Collections.emptyList());
}
this.rollover = ROLLOVER_SETTING.get(settings);
this.events = parse(INCLUDE_EVENT_SETTINGS.get(settings), EXCLUDE_EVENT_SETTINGS.get(settings));
this.indexToRemoteCluster = REMOTE_CLIENT_SETTINGS.get(settings).names().size() > 0;
this.includeRequestBody = INCLUDE_REQUEST_BODY.get(settings);
if (indexToRemoteCluster == false) {
// in the absence of client settings for remote indexing, fall back to the client that was passed in.
@ -391,7 +383,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
@Override
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportMessage message) {
if (events.contains(AUTHENTICATION_FAILED)) {
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
if (XPackUser.is(token.principal()) == false) {
try {
enqueue(message("authentication_failed", action, token, realm, indices(message), message), "authentication_failed");
@ -404,7 +396,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
@Override
public void authenticationFailed(String realm, AuthenticationToken token, RestRequest request) {
if (events.contains(AUTHENTICATION_FAILED)) {
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
if (XPackUser.is(token.principal()) == false) {
try {
enqueue(message("authentication_failed", null, token, realm, null, request), "authentication_failed");
@ -610,7 +602,9 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
if (indices != null) {
msg.builder.array(Field.INDICES, indices.toArray(Strings.EMPTY_ARRAY));
}
msg.builder.field(Field.REQUEST_BODY, restRequestContent(request));
if (includeRequestBody) {
msg.builder.field(Field.REQUEST_BODY, restRequestContent(request));
}
msg.builder.field(Field.ORIGIN_TYPE, "rest");
SocketAddress address = request.getRemoteAddress();
if (address instanceof InetSocketAddress) {
@ -630,7 +624,9 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
common("rest", type, msg.builder);
msg.builder.field(Field.PRINCIPAL, user.principal());
msg.builder.field(Field.REQUEST_BODY, restRequestContent(request));
if (includeRequestBody) {
msg.builder.field(Field.REQUEST_BODY, restRequestContent(request));
}
msg.builder.field(Field.ORIGIN_TYPE, "rest");
SocketAddress address = request.getRemoteAddress();
if (address instanceof InetSocketAddress) {
@ -905,6 +901,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
settings.add(FLUSH_TIMEOUT_SETTING);
settings.add(QUEUE_SIZE_SETTING);
settings.add(REMOTE_CLIENT_SETTINGS);
settings.add(INCLUDE_REQUEST_BODY);
}
private class QueueConsumer extends Thread {

View File

@ -20,6 +20,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportMessage;
import org.elasticsearch.xpack.security.audit.AuditLevel;
import org.elasticsearch.xpack.security.audit.AuditTrail;
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.security.authz.privilege.SystemPrivilege;
@ -32,11 +33,27 @@ import org.elasticsearch.xpack.security.user.XPackUser;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import static org.elasticsearch.common.Strings.collectionToCommaDelimitedString;
import static org.elasticsearch.xpack.security.Security.setting;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ANONYMOUS_ACCESS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.AUTHENTICATION_FAILED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.REALM_AUTHENTICATION_FAILED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.CONNECTION_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.CONNECTION_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.RUN_AS_DENIED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.RUN_AS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.SYSTEM_ACCESS_GRANTED;
import static org.elasticsearch.xpack.security.audit.AuditLevel.TAMPERED_REQUEST;
import static org.elasticsearch.xpack.security.audit.AuditLevel.parse;
import static org.elasticsearch.xpack.security.audit.AuditUtil.indices;
import static org.elasticsearch.xpack.security.audit.AuditUtil.restRequestContent;
@ -52,10 +69,28 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
Setting.boolSetting(setting("audit.logfile.prefix.emit_node_host_name"), false, Property.NodeScope);
public static final Setting<Boolean> NODE_NAME_SETTING =
Setting.boolSetting(setting("audit.logfile.prefix.emit_node_name"), true, Property.NodeScope);
private static final List<String> DEFAULT_EVENT_INCLUDES = Arrays.asList(
ACCESS_DENIED.toString(),
ACCESS_GRANTED.toString(),
ANONYMOUS_ACCESS_DENIED.toString(),
AUTHENTICATION_FAILED.toString(),
CONNECTION_DENIED.toString(),
TAMPERED_REQUEST.toString(),
RUN_AS_DENIED.toString(),
RUN_AS_GRANTED.toString()
);
private static final Setting<List<String>> INCLUDE_EVENT_SETTINGS =
Setting.listSetting(setting("audit.logfile.events.include"), DEFAULT_EVENT_INCLUDES, Function.identity(), Property.NodeScope);
private static final Setting<List<String>> EXCLUDE_EVENT_SETTINGS =
Setting.listSetting(setting("audit.logfile.events.exclude"), Collections.emptyList(), Function.identity(), Property.NodeScope);
private static final Setting<Boolean> INCLUDE_REQUEST_BODY =
Setting.boolSetting(setting("audit.logfile.events.emit_request_body"), false, Property.NodeScope);
private final Logger logger;
private final ClusterService clusterService;
private final ThreadContext threadContext;
private final EnumSet<AuditLevel> events;
private final boolean includeRequestBody;
private String prefix;
@ -73,6 +108,8 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
this.logger = logger;
this.clusterService = clusterService;
this.threadContext = threadContext;
this.events = parse(INCLUDE_EVENT_SETTINGS.get(settings), EXCLUDE_EVENT_SETTINGS.get(settings));
this.includeRequestBody = INCLUDE_REQUEST_BODY.get(settings);
}
private String getPrefix() {
@ -84,300 +121,240 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
@Override
public void anonymousAccessDenied(String action, TransportMessage message) {
String indices = indicesString(message);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [anonymous_access_denied]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
if (events.contains(ANONYMOUS_ACCESS_DENIED)) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
message.getClass().getSimpleName());
} else {
logger.warn("{}[transport] [anonymous_access_denied]\t{}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [anonymous_access_denied]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
} else {
logger.warn("{}[transport] [anonymous_access_denied]\t{}, action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action);
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
}
}
}
@Override
public void anonymousAccessDenied(RestRequest request) {
if (logger.isDebugEnabled()) {
logger.debug("{}[rest] [anonymous_access_denied]\t{}, uri=[{}], request_body=[{}]", getPrefix(),
hostAttributes(request), request.uri(), restRequestContent(request));
} else {
logger.warn("{}[rest] [anonymous_access_denied]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
if (events.contains(ANONYMOUS_ACCESS_DENIED)) {
if (includeRequestBody) {
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}], request_body=[{}]", getPrefix(),
hostAttributes(request), request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
}
}
}
@Override
public void authenticationFailed(AuthenticationToken token, String action, TransportMessage message) {
String indices = indicesString(message);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]",
if (events.contains(AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]",
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), token.principal(),
action, indices, message.getClass().getSimpleName());
action, indices, message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), token.principal(), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), token.principal(), action,
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), token.principal(), action,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), token.principal(), action);
}
}
}
@Override
public void authenticationFailed(RestRequest request) {
if (logger.isDebugEnabled()) {
logger.debug("{}[rest] [authentication_failed]\t{}, uri=[{}], request_body=[{}]", getPrefix(), hostAttributes(request),
request.uri(), restRequestContent(request));
} else {
logger.error("{}[rest] [authentication_failed]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
if (events.contains(AUTHENTICATION_FAILED)) {
if (includeRequestBody) {
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}], request_body=[{}]", getPrefix(), hostAttributes(request),
request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
}
}
}
@Override
public void authenticationFailed(String action, TransportMessage message) {
String indices = indicesString(message);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [authentication_failed]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
if (events.contains(AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [authentication_failed]\t{}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [authentication_failed]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [authentication_failed]\t{}, action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action);
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
}
}
}
@Override
public void authenticationFailed(AuthenticationToken token, RestRequest request) {
if (logger.isDebugEnabled()) {
logger.debug("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
} else {
logger.error("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", getPrefix(), hostAttributes(request),
token.principal(), request.uri());
if (events.contains(AUTHENTICATION_FAILED)) {
if (includeRequestBody) {
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", getPrefix(), hostAttributes(request),
token.principal(), request.uri());
}
}
}
@Override
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportMessage message) {
if (logger.isTraceEnabled()) {
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
if (indices != null) {
logger.trace("{}[transport] [authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], indices=[{}], " +
"request=[{}]", getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext),
token.principal(), action, indices, message.getClass().getSimpleName());
logger.info("{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], indices=[{}], " +
"request=[{}]", getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext),
token.principal(), action, indices, message.getClass().getSimpleName());
} else {
logger.trace("{}[transport] [authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], request=[{}]",
getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext), token.principal(),
action, message.getClass().getSimpleName());
logger.info("{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], request=[{}]",
getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext), token.principal(),
action, message.getClass().getSimpleName());
}
}
}
@Override
public void authenticationFailed(String realm, AuthenticationToken token, RestRequest request) {
if (logger.isTraceEnabled()) {
logger.trace("{}[rest] [authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
realm, hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
if (includeRequestBody) {
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}], request_body=[{}]",
getPrefix(), realm, hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}]", getPrefix(),
realm, hostAttributes(request), token.principal(), request.uri());
}
}
}
@Override
public void accessGranted(User user, String action, TransportMessage message) {
String indices = indicesString(message);
// special treatment for internal system actions - only log on trace
if ((SystemUser.is(user) && SystemPrivilege.INSTANCE.predicate().test(action)) || XPackUser.is(user)) {
if (logger.isTraceEnabled()) {
if (indices != null) {
logger.trace("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
final boolean isSystem = (SystemUser.is(user) && SystemPrivilege.INSTANCE.predicate().test(action)) || XPackUser.is(user);
final boolean logSystemAccessGranted = isSystem && events.contains(SYSTEM_ACCESS_GRANTED);
final boolean shouldLog = logSystemAccessGranted || (isSystem == false && events.contains(ACCESS_GRANTED));
if (shouldLog) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
message.getClass().getSimpleName());
} else {
logger.trace("{}[transport] [access_granted]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
message.getClass().getSimpleName());
}
}
return;
}
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [access_granted]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action);
}
}
}
@Override
public void accessDenied(User user, String action, TransportMessage message) {
String indices = indicesString(message);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [access_denied]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
if (events.contains(ACCESS_DENIED)) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [access_denied]\t{}, {}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [access_denied]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [access_denied]\t{}, {}, action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action);
}
}
}
@Override
public void tamperedRequest(RestRequest request) {
if (logger.isDebugEnabled()) {
logger.debug("{}[rest] [tampered_request]\t{}, uri=[{}], request_body=[{}]", getPrefix(), hostAttributes(request),
request.uri(), restRequestContent(request));
} else {
logger.error("{}[rest] [tampered_request]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
if (events.contains(TAMPERED_REQUEST)) {
if (includeRequestBody) {
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}], request_body=[{}]", getPrefix(), hostAttributes(request),
request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
}
}
}
@Override
public void tamperedRequest(String action, TransportMessage message) {
String indices = indicesString(message);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [tampered_request]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
if (events.contains(TAMPERED_REQUEST)) {
String indices = indicesString(message);
if (indices != null) {
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [tampered_request]\t{}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [tampered_request]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action,
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], request=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action,
message.getClass().getSimpleName());
} else {
logger.error("{}[transport] [tampered_request]\t{}, action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), action);
}
}
}
@Override
public void tamperedRequest(User user, String action, TransportMessage request) {
String indices = indicesString(request);
if (indices != null) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [tampered_request]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action, indices,
if (events.contains(TAMPERED_REQUEST)) {
String indices = indicesString(request);
if (indices != null) {
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action, indices,
request.getClass().getSimpleName());
} else {
logger.error("{}[transport] [tampered_request]\t{}, {}, action=[{}], indices=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action, indices);
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [tampered_request]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action,
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action,
request.getClass().getSimpleName());
} else {
logger.error("{}[transport] [tampered_request]\t{}, {}, action=[{}]", getPrefix(),
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action);
}
}
}
@Override
public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {
if (logger.isTraceEnabled()) {
logger.trace("{}[ip_filter] [connection_granted]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", getPrefix(),
if (events.contains(CONNECTION_GRANTED)) {
logger.info("{}[ip_filter] [connection_granted]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", getPrefix(),
NetworkAddress.format(inetAddress), profile, rule);
}
}
@Override
public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {
logger.error("{}[ip_filter] [connection_denied]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", getPrefix(),
NetworkAddress.format(inetAddress), profile, rule);
if (events.contains(CONNECTION_DENIED)) {
logger.info("{}[ip_filter] [connection_denied]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", getPrefix(),
NetworkAddress.format(inetAddress), profile, rule);
}
}
@Override
public void runAsGranted(User user, String action, TransportMessage message) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
if (events.contains(RUN_AS_GRANTED)) {
logger.info("{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), user.principal(),
user.runAs().principal(), action, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), user.principal(),
user.runAs().principal(), action);
}
}
@Override
public void runAsDenied(User user, String action, TransportMessage message) {
if (logger.isDebugEnabled()) {
logger.debug("{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
if (events.contains(RUN_AS_DENIED)) {
logger.info("{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), user.principal(),
user.runAs().principal(), action, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], action=[{}]", getPrefix(),
originAttributes(message, clusterService.localNode(), threadContext), user.principal(),
user.runAs().principal(), action);
}
}
@Override
public void runAsDenied(User user, RestRequest request) {
if (logger.isDebugEnabled()) {
logger.debug("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
if (events.contains(RUN_AS_DENIED)) {
if (includeRequestBody) {
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
hostAttributes(request), user.principal(), request.uri(), restRequestContent(request));
} else {
logger.info("{}[transport] [run_as_denied]\t{}, principal=[{}], uri=[{}]", getPrefix(),
hostAttributes(request), user.principal(), request.uri());
} else {
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}]", getPrefix(),
hostAttributes(request), user.principal(), request.uri());
}
}
}
@ -465,5 +442,8 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
settings.add(HOST_ADDRESS_SETTING);
settings.add(HOST_NAME_SETTING);
settings.add(NODE_NAME_SETTING);
settings.add(INCLUDE_EVENT_SETTINGS);
settings.add(EXCLUDE_EVENT_SETTINGS);
settings.add(INCLUDE_REQUEST_BODY);
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.audit;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.security.audit.AuditLevel;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Locale;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
public class AuditLevelTests extends ESTestCase {
public void testAllIndexAuditLevel() {
EnumSet<AuditLevel> enumSet = AuditLevel.parse(Collections.singletonList("_all"));
AuditLevel[] levels = AuditLevel.values();
assertThat(enumSet.size(), is(levels.length));
for (AuditLevel level : levels) {
assertThat(enumSet.contains(level), is(true));
}
}
public void testExcludeHasPreference() {
EnumSet<AuditLevel> enumSet = AuditLevel.parse(Collections.singletonList("_all"), Collections.singletonList("_all"));
assertThat(enumSet.size(), is(0));
}
public void testExcludeHasPreferenceSingle() {
String excluded = randomFrom(AuditLevel.values()).toString().toLowerCase(Locale.ROOT);
EnumSet<AuditLevel> enumSet = AuditLevel.parse(Collections.singletonList("_all"), Collections.singletonList(excluded));
EnumSet<AuditLevel> expected = EnumSet.allOf(AuditLevel.class);
expected.remove(AuditLevel.valueOf(excluded.toUpperCase(Locale.ROOT)));
assertThat(enumSet, equalTo(expected));
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.audit.index;
import org.elasticsearch.test.ESTestCase;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Locale;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
public class IndexAuditLevelTests extends ESTestCase {
public void testAllIndexAuditLevel() {
EnumSet<IndexAuditLevel> enumSet = IndexAuditLevel.parse(Collections.singletonList("_all"));
IndexAuditLevel[] levels = IndexAuditLevel.values();
assertThat(enumSet.size(), is(levels.length));
for (IndexAuditLevel level : levels) {
assertThat(enumSet.contains(level), is(true));
}
}
public void testExcludeHasPreference() {
EnumSet<IndexAuditLevel> enumSet = IndexAuditLevel.parse(Collections.singletonList("_all"), Collections.singletonList("_all"));
assertThat(enumSet.size(), is(0));
}
public void testExcludeHasPreferenceSingle() {
String excluded = randomFrom(IndexAuditLevel.values()).toString().toLowerCase(Locale.ROOT);
EnumSet<IndexAuditLevel> enumSet = IndexAuditLevel.parse(Collections.singletonList("_all"), Collections.singletonList(excluded));
EnumSet<IndexAuditLevel> expected = EnumSet.allOf(IndexAuditLevel.class);
expected.remove(IndexAuditLevel.valueOf(excluded.toUpperCase(Locale.ROOT)));
assertThat(enumSet, equalTo(expected));
}
}

View File

@ -113,11 +113,6 @@ public class IndexAuditTrailMutedTests extends ESTestCase {
TransportMessage message = mock(TransportMessage.class);
AuthenticationToken token = mock(AuthenticationToken.class);
// with realm
auditTrail.authenticationFailed(randomAsciiOfLengthBetween(2, 10), token, "_action", message);
assertThat(messageEnqueued.get(), is(false));
assertThat(clientCalled.get(), is(false));
// without realm
auditTrail.authenticationFailed(token, "_action", message);
assertThat(messageEnqueued.get(), is(false));
@ -136,11 +131,6 @@ public class IndexAuditTrailMutedTests extends ESTestCase {
RestRequest restRequest = mock(RestRequest.class);
AuthenticationToken token = mock(AuthenticationToken.class);
// with realm
auditTrail.authenticationFailed(randomAsciiOfLengthBetween(2, 10), token, restRequest);
assertThat(messageEnqueued.get(), is(false));
assertThat(clientCalled.get(), is(false));
// without the realm
auditTrail.authenticationFailed(token, restRequest);
assertThat(messageEnqueued.get(), is(false));
@ -150,7 +140,32 @@ public class IndexAuditTrailMutedTests extends ESTestCase {
auditTrail.authenticationFailed(restRequest);
assertThat(messageEnqueued.get(), is(false));
assertThat(clientCalled.get(), is(false));
verifyZeroInteractions(token, restRequest);
}
public void testAuthenticationFailedRealmMutedTransport() {
createAuditTrail(new String[] { "realm_authentication_failed" });
TransportMessage message = mock(TransportMessage.class);
AuthenticationToken token = mock(AuthenticationToken.class);
// with realm
auditTrail.authenticationFailed(randomAsciiOfLengthBetween(2, 10), token, "_action", message);
assertThat(messageEnqueued.get(), is(false));
assertThat(clientCalled.get(), is(false));
verifyZeroInteractions(token, message);
}
public void testAuthenticationFailedRealmMutedRest() {
createAuditTrail(new String[]{"realm_authentication_failed"});
RestRequest restRequest = mock(RestRequest.class);
AuthenticationToken token = mock(AuthenticationToken.class);
// with realm
auditTrail.authenticationFailed(randomAsciiOfLengthBetween(2, 10), token, restRequest);
assertThat(messageEnqueued.get(), is(false));
assertThat(clientCalled.get(), is(false));
verifyZeroInteractions(token, restRequest);
}

View File

@ -96,6 +96,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
private int numShards;
private int numReplicas;
private ThreadPool threadPool;
private boolean includeRequestBody;
@BeforeClass
public static void configureBeforeClass() {
@ -241,6 +242,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
Settings.Builder builder = Settings.builder();
builder.put(levelSettings(includes, excludes));
builder.put(commonSettings(rollover));
builder.put("xpack.security.audit.index.events.emit_request_body", includeRequestBody);
return builder.build();
}
@ -256,6 +258,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
rollover = randomFrom(HOURLY, DAILY, WEEKLY, MONTHLY);
numReplicas = numberOfReplicas();
numShards = numberOfShards();
includeRequestBody = randomBoolean();
Settings.Builder builder = Settings.builder();
if (remoteIndexing) {
builder.put(remoteSettings);
@ -314,7 +317,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertThat(NetworkAddress.format(InetAddress.getLoopbackAddress()), equalTo(sourceMap.get("origin_address")));
assertThat("_uri", equalTo(sourceMap.get("uri")));
assertThat(sourceMap.get("origin_type"), is("rest"));
assertThat(sourceMap.get("request_body"), notNullValue());
assertRequestBody(sourceMap);
}
public void testAuthenticationFailedTransport() throws Exception {
@ -373,7 +376,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertThat("127.0.0.1", equalTo(sourceMap.get("origin_address")));
assertThat("_uri", equalTo(sourceMap.get("uri")));
assertThat(sourceMap.get("origin_type"), is("rest"));
assertThat(sourceMap.get("request_body"), notNullValue());
assertRequestBody(sourceMap);
}
public void testAuthenticationFailedRestNoToken() throws Exception {
@ -388,7 +391,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertThat("127.0.0.1", equalTo(sourceMap.get("origin_address")));
assertThat("_uri", equalTo(sourceMap.get("uri")));
assertThat(sourceMap.get("origin_type"), is("rest"));
assertThat(sourceMap.get("request_body"), notNullValue());
assertRequestBody(sourceMap);
}
public void testAuthenticationFailedTransportRealm() throws Exception {
@ -429,7 +432,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertThat("_uri", equalTo(sourceMap.get("uri")));
assertEquals("_realm", sourceMap.get("realm"));
assertThat(sourceMap.get("origin_type"), is("rest"));
assertThat(sourceMap.get("request_body"), notNullValue());
assertRequestBody(sourceMap);
}
public void testAccessGranted() throws Exception {
@ -520,7 +523,7 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertThat("127.0.0.1", equalTo(sourceMap.get("origin_address")));
assertThat("_uri", equalTo(sourceMap.get("uri")));
assertThat(sourceMap.get("origin_type"), is("rest"));
assertThat(sourceMap.get("request_body"), notNullValue());
assertRequestBody(sourceMap);
}
public void testTamperedRequest() throws Exception {
@ -638,6 +641,13 @@ public class IndexAuditTrailTests extends SecurityIntegTestCase {
assertEquals(type, sourceMap.get("event_type"));
}
private void assertRequestBody(Map<String, Object> sourceMap) {
if (includeRequestBody) {
assertThat(sourceMap.get("request_body"), notNullValue());
} else {
assertThat(sourceMap.get("request_body"), nullValue());
}
}
private static class LocalHostMockMessage extends TransportMessage {
LocalHostMockMessage() {
remoteAddress(new LocalTransportAddress("local_host"));

View File

@ -14,7 +14,6 @@ import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.filter.RegexFilter;
import org.apache.logging.log4j.core.impl.MutableLogEvent;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.logging.TestLoggers;

View File

@ -105,53 +105,45 @@ public class LoggingAuditTrailTests extends ESTestCase {
private DiscoveryNode localNode;
private ClusterService clusterService;
private ThreadContext threadContext;
private boolean includeRequestBody;
@Before
public void init() throws Exception {
includeRequestBody = randomBoolean();
settings = Settings.builder()
.put("xpack.security.audit.logfile.prefix.emit_node_host_address", randomBoolean())
.put("xpack.security.audit.logfile.prefix.emit_node_host_name", randomBoolean())
.put("xpack.security.audit.logfile.prefix.emit_node_name", randomBoolean())
.put("xpack.security.audit.logfile.events.emit_request_body", includeRequestBody)
.build();
localNode = mock(DiscoveryNode.class);
when(localNode.getHostAddress()).thenReturn(LocalTransportAddress.buildUnique().toString());
clusterService = mock(ClusterService.class);
when(clusterService.localNode()).thenReturn(localNode);
prefix = LoggingAuditTrail.resolvePrefix(settings, localNode);
threadContext = new ThreadContext(Settings.EMPTY);
}
public void testAnonymousAccessDeniedTransport() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, clusterService.localNode(), threadContext);
auditTrail.anonymousAccessDenied("_action", message);
switch (level.toString()) {
case "ERROR":
assertEmptyLog(logger);
break;
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.WARN, prefix + "[transport] [anonymous_access_denied]\t" + origins +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.WARN, prefix + "[transport] [anonymous_access_denied]\t" + origins + ", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [anonymous_access_denied]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [anonymous_access_denied]\t" + origins +
", action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, clusterService.localNode(), threadContext);
auditTrail.anonymousAccessDenied("_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [anonymous_access_denied]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [anonymous_access_denied]\t" + origins +
", action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "anonymous_access_denied").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.anonymousAccessDenied("_action", message);
assertEmptyLog(logger);
}
public void testAnonymousAccessDeniedRest() throws Exception {
@ -160,359 +152,283 @@ public class LoggingAuditTrailTests extends ESTestCase {
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.anonymousAccessDenied(request);
switch (level.toString()) {
case "ERROR":
assertEmptyLog(logger);
break;
case "WARN":
case "INFO":
assertMsg(logger, Level.WARN, prefix + "[rest] [anonymous_access_denied]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[rest] [anonymous_access_denied]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.anonymousAccessDenied(request);
if (includeRequestBody) {
assertMsg(logger, Level.INFO, prefix + "[rest] [anonymous_access_denied]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[rest] [anonymous_access_denied]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "anonymous_access_denied").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.anonymousAccessDenied(request);
assertEmptyLog(logger);
}
public void testAuthenticationFailed() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
auditTrail.authenticationFailed(new MockToken(), "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action], indices=[" + indices(message) +
"], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
auditTrail.authenticationFailed(new MockToken(), "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action], indices=[" + indices(message) +
"], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
", principal=[_principal], action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(new MockToken(), "_action", message);
assertEmptyLog(logger);
}
public void testAuthenticationFailedNoToken() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
auditTrail.authenticationFailed("_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
auditTrail.authenticationFailed("_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
", action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_action", message);
assertEmptyLog(logger);
}
public void testAuthenticationFailedRest() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(new MockToken(), request);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
assertMsg(logger, Level.ERROR, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri], request_body=[" +
expectedMessage + "]");
}
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(new MockToken(), request);
if (includeRequestBody) {
assertMsg(logger, Level.INFO, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri], request_body=[" +
expectedMessage + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(new MockToken(), request);
assertEmptyLog(logger);
}
public void testAuthenticationFailedRestNoToken() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(request);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
assertMsg(logger, Level.ERROR, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
}
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(request);
if (includeRequestBody) {
assertMsg(logger, Level.INFO, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[rest] [authentication_failed]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(request);
assertEmptyLog(logger);
}
public void testAuthenticationFailedRealm() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
case "DEBUG":
assertEmptyLog(logger);
break;
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.TRACE, prefix + "[transport] [authentication_failed]\trealm=[_realm], " + origins +
", principal=[_principal], action=[_action], indices=[" + indices(message) + "], " +
"request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.TRACE, prefix + "[transport] [authentication_failed]\trealm=[_realm], " + origins +
", principal=[_principal], action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
assertEmptyLog(logger);
// test enabled
settings =
Settings.builder().put(settings).put("xpack.security.audit.logfile.events.include", "realm_authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [realm_authentication_failed]\trealm=[_realm], " + origins +
", principal=[_principal], action=[_action], indices=[" + indices(message) + "], " +
"request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [realm_authentication_failed]\trealm=[_realm], " + origins +
", principal=[_principal], action=[_action], request=[MockMessage]");
}
}
public void testAuthenticationFailedRealmRest() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), request);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
case "DEBUG":
assertEmptyLog(logger);
break;
case "TRACE":
assertMsg(logger, Level.TRACE, prefix + "[rest] [authentication_failed]\trealm=[_realm], origin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri], request_body=[" +
expectedMessage + "]");
}
RestRequest request = mock(RestRequest.class);
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), request);
assertEmptyLog(logger);
// test enabled
settings =
Settings.builder().put(settings).put("xpack.security.audit.logfile.events.include", "realm_authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), request);
if (includeRequestBody) {
assertMsg(logger, Level.INFO, prefix + "[rest] [realm_authentication_failed]\trealm=[_realm], origin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri], request_body=[" +
expectedMessage + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[rest] [realm_authentication_failed]\trealm=[_realm], origin_address=[" +
NetworkAddress.format(address) + "], principal=[_principal], uri=[_uri]");
}
}
public void testAccessGranted() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessGranted(user, "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
assertEmptyLog(logger);
break;
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessGranted(user, "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "access_granted").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.accessGranted(user, "_action", message);
assertEmptyLog(logger);
}
public void testAccessGrantedInternalSystemAction() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
auditTrail.accessGranted(SystemUser.INSTANCE, "internal:_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
case "DEBUG":
assertEmptyLog(logger);
break;
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
SystemUser.INSTANCE.principal()
+ "], action=[internal:_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
SystemUser.INSTANCE.principal() + "], action=[internal:_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
auditTrail.accessGranted(SystemUser.INSTANCE, "internal:_action", message);
assertEmptyLog(logger);
// test enabled
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(SystemUser.INSTANCE, "internal:_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
SystemUser.INSTANCE.principal()
+ "], action=[internal:_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
SystemUser.INSTANCE.principal() + "], action=[internal:_action], request=[MockMessage]");
}
}
public void testAccessGrantedInternalSystemActionNonSystemUser() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessGranted(user, "internal:_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
assertEmptyLog(logger);
break;
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessGranted(user, "internal:_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
", action=[internal:_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "access_granted").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.accessGranted(user, "internal:_action", message);
assertEmptyLog(logger);
}
public void testAccessDenied() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessDenied(user, "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.ERROR, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.ERROR, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("_username", new String[]{"r1"},
new User("running as", new String[] {"r2"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
auditTrail.accessDenied(user, "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "access_denied").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.accessDenied(user, "_action", message);
assertEmptyLog(logger);
}
public void testTamperedRequestRest() throws Exception {
@ -521,58 +437,42 @@ public class LoggingAuditTrailTests extends ESTestCase {
when(request.getRemoteAddress()).thenReturn(new InetSocketAddress(address, 9200));
when(request.uri()).thenReturn("_uri");
String expectedMessage = prepareRestContent(request);
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(request);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
assertMsg(logger, Level.ERROR, prefix + "[rest] [tampered_request]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[rest] [tampered_request]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(request);
if (includeRequestBody) {
assertMsg(logger, Level.INFO, prefix + "[rest] [tampered_request]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri], request_body=[" + expectedMessage + "]");
} else {
assertMsg(logger, Level.INFO, prefix + "[rest] [tampered_request]\torigin_address=[" +
NetworkAddress.format(address) + "], uri=[_uri]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "tampered_request").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(request);
assertEmptyLog(logger);
}
public void testTamperedRequest() throws Exception {
String action = "_action";
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(action, message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.ERROR, prefix + "[transport] [tampered_request]\t" + origins +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.ERROR, prefix + "[transport] [tampered_request]\t" + origins + ", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [tampered_request]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [tampered_request]\t" + origins +
", action=[_action], request=[MockMessage]");
}
}
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(action, message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins +
", action=[_action], request=[MockMessage]");
}
// test disabled
}
public void testTamperedRequestWithUser() throws Exception {
@ -585,137 +485,100 @@ public class LoggingAuditTrailTests extends ESTestCase {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(user, action, message);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.ERROR, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "]");
} else {
assertMsg(logger, Level.ERROR, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action]");
}
break;
case "DEBUG":
case "TRACE":
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.DEBUG, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
}
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(user, action, message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
", action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "tampered_request").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(user, action, message);
assertEmptyLog(logger);
}
public void testConnectionDenied() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
InetAddress inetAddress = InetAddress.getLoopbackAddress();
SecurityIpFilterRule rule = new SecurityIpFilterRule(false, "_all");
auditTrail.connectionDenied(inetAddress, "default", rule);
switch (level.toString()) {
case "ERROR":
assertMsg(logger, Level.ERROR, String.format(Locale.ROOT, prefix +
"[ip_filter] [connection_denied]\torigin_address=[%s], transport_profile=[%s], rule=[deny %s]",
NetworkAddress.format(inetAddress), "default", "_all"));
break;
case "WARN":
case "INFO":
case "DEBUG":
case "TRACE":
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
InetAddress inetAddress = InetAddress.getLoopbackAddress();
SecurityIpFilterRule rule = new SecurityIpFilterRule(false, "_all");
auditTrail.connectionDenied(inetAddress, "default", rule);
assertMsg(logger, Level.INFO, String.format(Locale.ROOT, prefix +
"[ip_filter] [connection_denied]\torigin_address=[%s], transport_profile=[%s], rule=[deny %s]",
NetworkAddress.format(inetAddress), "default", "_all"));
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "connection_denied").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.connectionDenied(inetAddress, "default", rule);
assertEmptyLog(logger);
}
public void testConnectionGranted() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
InetAddress inetAddress = InetAddress.getLoopbackAddress();
SecurityIpFilterRule rule = IPFilter.DEFAULT_PROFILE_ACCEPT_ALL;
auditTrail.connectionGranted(inetAddress, "default", rule);
switch (level.toString()) {
case "ERROR":
case "WARN":
case "INFO":
case "DEBUG":
assertEmptyLog(logger);
break;
case "TRACE":
assertMsg(logger, Level.TRACE, String.format(Locale.ROOT, prefix + "[ip_filter] " +
"[connection_granted]\torigin_address=[%s], transport_profile=[default], rule=[allow default:accept_all]",
NetworkAddress.format(inetAddress)));
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
InetAddress inetAddress = InetAddress.getLoopbackAddress();
SecurityIpFilterRule rule = IPFilter.DEFAULT_PROFILE_ACCEPT_ALL;
auditTrail.connectionGranted(inetAddress, "default", rule);
assertEmptyLog(logger);
// test enabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.include", "connection_granted").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.connectionGranted(inetAddress, "default", rule);
assertMsg(logger, Level.INFO, String.format(Locale.ROOT, prefix + "[ip_filter] [connection_granted]\torigin_address=[%s], " +
"transport_profile=[default], rule=[allow default:accept_all]", NetworkAddress.format(inetAddress)));
}
public void testRunAsGranted() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
User user = new User("_username", new String[]{"r1"}, new User("running as", new String[] {"r2"}));
auditTrail.runAsGranted(user, "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
assertEmptyLog(logger);
break;
case "INFO":
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_granted]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[transport] [run_as_granted]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
User user = new User("_username", new String[]{"r1"}, new User("running as", new String[] {"r2"}));
auditTrail.runAsGranted(user, "_action", message);
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_granted]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action], request=[MockMessage]");
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "run_as_granted").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.runAsGranted(user, "_action", message);
assertEmptyLog(logger);
}
public void testRunAsDenied() throws Exception {
for (Level level : Level.values()) {
threadContext = new ThreadContext(Settings.EMPTY);
Logger logger = CapturingLogger.newCapturingLogger(level);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
User user = new User("_username", new String[]{"r1"}, new User("running as", new String[] {"r2"}));
auditTrail.runAsDenied(user, "_action", message);
switch (level.toString()) {
case "ERROR":
case "WARN":
assertEmptyLog(logger);
break;
case "INFO":
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_denied]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action]");
break;
case "DEBUG":
case "TRACE":
assertMsg(logger, Level.DEBUG, prefix + "[transport] [run_as_denied]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action], request=[MockMessage]");
}
}
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, localNode, threadContext);
User user = new User("_username", new String[]{"r1"}, new User("running as", new String[] {"r2"}));
auditTrail.runAsDenied(user, "_action", message);
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_denied]\t" + origins +
", principal=[_username], run_as_principal=[running as], action=[_action], request=[MockMessage]");
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
settings = Settings.builder().put(settings).put("xpack.security.audit.logfile.events.exclude", "run_as_denied").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.runAsDenied(user, "_action", message);
assertEmptyLog(logger);
}
public void testOriginAttributes() throws Exception {
threadContext = new ThreadContext(Settings.EMPTY);
MockMessage message = new MockMessage(threadContext);
String text = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);