This commit introduces audit event filtering policies for the logging audit.
Until now the only way to temper the gush of audit events was to specifically
pick some event types that were reported.
This superposes a way (named policies) to filter events using lucene regexp filters on 
the following event fields: users, realms, roles and indices. The policies are ignore
policies, ie when an event matches it is ignored (not reported).

Original commit: elastic/x-pack-elasticsearch@233f685121
This commit is contained in:
Albert Zaharovits 2018-01-11 11:07:46 +02:00 committed by GitHub
parent e74f90eba0
commit 3fc17ab918
3 changed files with 2065 additions and 255 deletions

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.security.audit.logfile;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.node.DiscoveryNode;
@ -26,6 +27,7 @@ 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.rest.RemoteHostHeader;
import org.elasticsearch.xpack.security.support.Automatons;
import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
import org.elasticsearch.xpack.security.user.SystemUser;
import org.elasticsearch.xpack.security.user.User;
@ -37,12 +39,16 @@ import java.net.SocketAddress;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.elasticsearch.common.Strings.collectionToCommaDelimitedString;
import static org.elasticsearch.common.Strings.arrayToCommaDelimitedString;
import static org.elasticsearch.xpack.security.SecurityField.setting;
import static org.elasticsearch.xpack.security.audit.AuditLevel.ACCESS_DENIED;
@ -58,7 +64,6 @@ import static org.elasticsearch.xpack.security.audit.AuditLevel.SYSTEM_ACCESS_GR
import static org.elasticsearch.xpack.security.audit.AuditLevel.TAMPERED_REQUEST;
import static org.elasticsearch.xpack.security.audit.AuditLevel.AUTHENTICATION_SUCCESS;
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;
public class LoggingAuditTrail extends AbstractComponent implements AuditTrail, ClusterStateListener {
@ -86,10 +91,28 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
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 static final String FILTER_POLICY_PREFIX = setting("audit.logfile.events.ignore_filters.");
// because of the default wildcard value (*) for the field filter, a policy with
// an unspecified filter field will match events that have any value for that
// particular field, as well as events with that particular field missing
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_PRINCIPALS =
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "users", (key) -> Setting.listSetting(key, Collections.singletonList("*"),
Function.identity(), Setting.Property.NodeScope, Setting.Property.Dynamic));
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_REALMS =
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "realms", (key) -> Setting.listSetting(key, Collections.singletonList("*"),
Function.identity(), Setting.Property.NodeScope, Setting.Property.Dynamic));
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_ROLES =
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "roles", (key) -> Setting.listSetting(key, Collections.singletonList("*"),
Function.identity(), Setting.Property.NodeScope, Setting.Property.Dynamic));
private static final Setting.AffixSetting<List<String>> FILTER_POLICY_IGNORE_INDICES =
Setting.affixKeySetting(FILTER_POLICY_PREFIX, "indices", (key) -> Setting.listSetting(key, Collections.singletonList("*"),
Function.identity(), Setting.Property.NodeScope, Setting.Property.Dynamic));
private final Logger logger;
private final EnumSet<AuditLevel> events;
private final boolean includeRequestBody;
// protected for testing
protected final Predicate<AuditEventMetaInfo> filterPolicyPredicate;
private final ThreadContext threadContext;
volatile LocalNodeInfo localNodeInfo;
@ -109,12 +132,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
this.includeRequestBody = INCLUDE_REQUEST_BODY.get(settings);
this.threadContext = threadContext;
this.localNodeInfo = new LocalNodeInfo(settings, null);
this.filterPolicyPredicate = new EventFilterPolicyRegistry(settings).ignorePredicate();
clusterService.addListener(this);
}
@Override
public void authenticationSuccess(String realm, User user, RestRequest request) {
if (events.contains(AUTHENTICATION_SUCCESS)) {
if (events.contains(AUTHENTICATION_SUCCESS) && filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.of(realm), Optional.empty(), Optional.empty())) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [authentication_success]\t{}, realm=[{}], uri=[{}], params=[{}], request_body=[{}]",
localNodeInfo.prefix, principal(user), realm, request.uri(), request.params(), restRequestContent(request));
@ -128,32 +153,44 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void authenticationSuccess(String realm, User user, String action, TransportMessage message) {
if (events.contains(AUTHENTICATION_SUCCESS)) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
logger.info("{}[transport] [authentication_success]\t{}, {}, realm=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user), realm, action,
message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.of(realm), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [authentication_success]\t{}, {}, realm=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user), realm, action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [authentication_success]\t{}, {}, realm=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user), realm, action,
message.getClass().getSimpleName());
}
}
}
}
@Override
public void anonymousAccessDenied(String action, TransportMessage message) {
if (events.contains(ANONYMOUS_ACCESS_DENIED)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), action, indices,
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.empty(), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
}
}
}
}
@Override
public void anonymousAccessDenied(RestRequest request) {
if (events.contains(ANONYMOUS_ACCESS_DENIED)) {
if (events.contains(ANONYMOUS_ACCESS_DENIED) && filterPolicyPredicate.test(AuditEventMetaInfo.EMPTY) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}], request_body=[{}]", localNodeInfo.prefix,
hostAttributes(request), request.uri(), restRequestContent(request));
@ -167,30 +204,30 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void authenticationFailed(AuthenticationToken token, String action, TransportMessage message) {
if (events.contains(AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action, indices,
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.of(token), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
message.getClass().getSimpleName());
}
}
}
}
@Override
public void authenticationFailed(RestRequest request) {
if (events.contains(AUTHENTICATION_FAILED)) {
if (events.contains(AUTHENTICATION_FAILED) && filterPolicyPredicate.test(AuditEventMetaInfo.EMPTY) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}], request_body=[{}]", localNodeInfo.prefix,
hostAttributes(request), request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request),
request.uri());
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request), request.uri());
}
}
}
@ -198,27 +235,31 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void authenticationFailed(String action, TransportMessage message) {
if (events.contains(AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, indices, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.empty(), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, arrayToCommaDelimitedString(indices.get()),
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
}
}
}
}
@Override
public void authenticationFailed(AuthenticationToken token, RestRequest request) {
if (events.contains(AUTHENTICATION_FAILED)) {
if (events.contains(AUTHENTICATION_FAILED)
&& filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.of(token), Optional.empty(), Optional.empty())) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}], request_body=[{}]", localNodeInfo.prefix,
hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", localNodeInfo.prefix,
hostAttributes(request), token.principal(), request.uri());
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", localNodeInfo.prefix, hostAttributes(request),
token.principal(), request.uri());
}
}
}
@ -226,30 +267,35 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void authenticationFailed(String realm, AuthenticationToken token, String action, TransportMessage message) {
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], indices=[{}], " +
"request=[{}]", localNodeInfo.prefix, realm, originAttributes(threadContext, message, localNodeInfo),
token.principal(), action, indices, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, realm, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.of(token), Optional.of(realm), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info(
"{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], indices=[{}], "
+ "request=[{}]",
localNodeInfo.prefix, realm, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, realm, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
message.getClass().getSimpleName());
}
}
}
}
@Override
public void authenticationFailed(String realm, AuthenticationToken token, RestRequest request) {
if (events.contains(REALM_AUTHENTICATION_FAILED)) {
if (events.contains(REALM_AUTHENTICATION_FAILED)
&& filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.of(token), Optional.of(realm), Optional.empty())) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}], request_body=[{}]",
localNodeInfo.prefix, realm, hostAttributes(request), token.principal(), request.uri(),
restRequestContent(request));
} else {
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}]", localNodeInfo.prefix,
realm, hostAttributes(request), token.principal(), request.uri());
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}]", localNodeInfo.prefix, realm,
hostAttributes(request), token.principal(), request.uri());
}
}
}
@ -257,19 +303,21 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void accessGranted(User user, String action, TransportMessage message, String[] roleNames) {
final boolean isSystem = SystemUser.is(user) || 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);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [access_granted]\t{}, {}, roles=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, indices, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_granted]\t{}, {}, roles=[{}], action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), principal(user), arrayToCommaDelimitedString(roleNames),
action, message.getClass().getSimpleName());
if ((isSystem && events.contains(SYSTEM_ACCESS_GRANTED)) || (isSystem == false && events.contains(ACCESS_GRANTED))) {
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.of(roleNames), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [access_granted]\t{}, {}, roles=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, arrayToCommaDelimitedString(indices.get()),
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_granted]\t{}, {}, roles=[{}], action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, message.getClass().getSimpleName());
}
}
}
}
@ -277,26 +325,30 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void accessDenied(User user, String action, TransportMessage message, String[] roleNames) {
if (events.contains(ACCESS_DENIED)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [access_denied]\t{}, {}, roles=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, indices, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_denied]\t{}, {}, roles=[{}], action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), principal(user), arrayToCommaDelimitedString(roleNames),
action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.of(roleNames), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [access_denied]\t{}, {}, roles=[{}], action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, arrayToCommaDelimitedString(indices.get()),
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [access_denied]\t{}, {}, roles=[{}], action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), principal(user),
arrayToCommaDelimitedString(roleNames), action, message.getClass().getSimpleName());
}
}
}
}
@Override
public void tamperedRequest(RestRequest request) {
if (events.contains(TAMPERED_REQUEST)) {
if (events.contains(TAMPERED_REQUEST) && filterPolicyPredicate.test(AuditEventMetaInfo.EMPTY) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}], request_body=[{}]", localNodeInfo.prefix,
hostAttributes(request), request.uri(), restRequestContent(request));
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}], request_body=[{}]", localNodeInfo.prefix, hostAttributes(request),
request.uri(), restRequestContent(request));
} else {
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request), request.uri());
}
@ -306,14 +358,17 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void tamperedRequest(String action, TransportMessage message) {
if (events.contains(TAMPERED_REQUEST)) {
String indices = indicesString(message);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, indices, message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate.test(new AuditEventMetaInfo(Optional.empty(), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, arrayToCommaDelimitedString(indices.get()),
message.getClass().getSimpleName());
} else {
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
}
}
}
}
@ -321,59 +376,95 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
@Override
public void tamperedRequest(User user, String action, TransportMessage request) {
if (events.contains(TAMPERED_REQUEST)) {
String indices = indicesString(request);
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices != null) {
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, request, localNodeInfo), principal(user), action, indices,
request.getClass().getSimpleName());
} else {
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, request, localNodeInfo), principal(user), action,
request.getClass().getSimpleName());
final Optional<String[]> indices = indices(request);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.empty(), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, request, localNodeInfo), principal(user), action,
arrayToCommaDelimitedString(indices.get()), request.getClass().getSimpleName());
} else {
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], request=[{}]", localNodeInfo.prefix,
originAttributes(threadContext, request, localNodeInfo), principal(user), action,
request.getClass().getSimpleName());
}
}
}
}
@Override
public void connectionGranted(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {
if (events.contains(CONNECTION_GRANTED)) {
logger.info("{}[ip_filter] [connection_granted]\torigin_address=[{}], transport_profile=[{}], rule=[{}]",
localNodeInfo.prefix, NetworkAddress.format(inetAddress), profile, rule);
if (events.contains(CONNECTION_GRANTED) && filterPolicyPredicate.test(AuditEventMetaInfo.EMPTY) == false) {
logger.info("{}[ip_filter] [connection_granted]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", localNodeInfo.prefix,
NetworkAddress.format(inetAddress), profile, rule);
}
}
@Override
public void connectionDenied(InetAddress inetAddress, String profile, SecurityIpFilterRule rule) {
if (events.contains(CONNECTION_DENIED)) {
logger.info("{}[ip_filter] [connection_denied]\torigin_address=[{}], transport_profile=[{}], rule=[{}]",
localNodeInfo.prefix, NetworkAddress.format(inetAddress), profile, rule);
if (events.contains(CONNECTION_DENIED) && filterPolicyPredicate.test(AuditEventMetaInfo.EMPTY) == false) {
logger.info("{}[ip_filter] [connection_denied]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", localNodeInfo.prefix,
NetworkAddress.format(inetAddress), profile, rule);
}
}
@Override
public void runAsGranted(User user, String action, TransportMessage message, String[] roleNames) {
if (events.contains(RUN_AS_GRANTED)) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
logger.info("{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), user.authenticatedUser().principal(),
user.principal(), arrayToCommaDelimitedString(roleNames), action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.of(roleNames), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info(
"{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}],"
+ " action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo),
user.authenticatedUser().principal(), user.principal(), arrayToCommaDelimitedString(roleNames), action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info(
"{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}],"
+ " action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo),
user.authenticatedUser().principal(), user.principal(), arrayToCommaDelimitedString(roleNames), action,
message.getClass().getSimpleName());
}
}
}
}
@Override
public void runAsDenied(User user, String action, TransportMessage message, String[] roleNames) {
if (events.contains(RUN_AS_DENIED)) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
logger.info("{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}], action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), user.authenticatedUser().principal(),
user.principal(), arrayToCommaDelimitedString(roleNames), action, message.getClass().getSimpleName());
final Optional<String[]> indices = indices(message);
if (filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.of(roleNames), indices)) == false) {
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
if (indices.isPresent()) {
logger.info(
"{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}],"
+ " action=[{}], indices=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo),
user.authenticatedUser().principal(), user.principal(), arrayToCommaDelimitedString(roleNames), action,
arrayToCommaDelimitedString(indices.get()), message.getClass().getSimpleName());
} else {
logger.info(
"{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], roles=[{}],"
+ " action=[{}], request=[{}]",
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo),
user.authenticatedUser().principal(), user.principal(), arrayToCommaDelimitedString(roleNames), action,
message.getClass().getSimpleName());
}
}
}
}
@Override
public void runAsDenied(User user, RestRequest request, String[] roleNames) {
if (events.contains(RUN_AS_DENIED)) {
if (events.contains(RUN_AS_DENIED) && filterPolicyPredicate
.test(new AuditEventMetaInfo(Optional.of(user), Optional.empty(), Optional.of(roleNames), Optional.empty())) == false) {
if (includeRequestBody) {
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], roles=[{}], uri=[{}], request_body=[{}]", localNodeInfo.prefix,
hostAttributes(request), user.principal(), arrayToCommaDelimitedString(roleNames), request.uri(),
@ -387,7 +478,7 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
private static String hostAttributes(RestRequest request) {
String formattedAddress;
SocketAddress socketAddress = request.getRemoteAddress();
final SocketAddress socketAddress = request.getRemoteAddress();
if (socketAddress instanceof InetSocketAddress) {
formattedAddress = NetworkAddress.format(((InetSocketAddress) socketAddress).getAddress());
} else {
@ -401,7 +492,7 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
}
private static Optional<String> restOriginTag(ThreadContext threadContext) {
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
final InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
if (restAddress == null) {
return Optional.empty();
}
@ -411,7 +502,7 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
}
private static Optional<String> transportOriginTag(TransportMessage message) {
TransportAddress address = message.remoteAddress();
final TransportAddress address = message.remoteAddress();
if (address == null) {
return Optional.empty();
}
@ -421,13 +512,15 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
.toString());
}
static String indicesString(TransportMessage message) {
Set<String> indices = indices(message);
return indices == null ? null : collectionToCommaDelimitedString(indices);
static Optional<String[]> indices(TransportMessage message) {
if (message instanceof IndicesRequest) {
return Optional.of(((IndicesRequest) message).indices());
}
return Optional.empty();
}
static String principal(User user) {
StringBuilder builder = new StringBuilder("principal=[");
final StringBuilder builder = new StringBuilder("principal=[");
builder.append(user.principal());
if (user.isRunAs()) {
builder.append("], run_by_principal=[").append(user.authenticatedUser().principal());
@ -442,6 +535,132 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
settings.add(INCLUDE_EVENT_SETTINGS);
settings.add(EXCLUDE_EVENT_SETTINGS);
settings.add(INCLUDE_REQUEST_BODY);
settings.add(FILTER_POLICY_IGNORE_PRINCIPALS);
settings.add(FILTER_POLICY_IGNORE_INDICES);
settings.add(FILTER_POLICY_IGNORE_ROLES);
settings.add(FILTER_POLICY_IGNORE_REALMS);
}
/**
* Builds the predicate for a single policy filter. The predicate matches events
* that will be ignored, aka filtered out, aka not logged. The event can be
* filtered by the following fields : `user`, `realm`, `role` and `index`.
* Predicates on each field are ANDed together to form the filter predicate of
* the policy.
*/
private static final class EventFilterPolicy {
final String name;
private final Predicate<String> ignorePrincipalsPredicate;
private final Predicate<String> ignoreRealmsPredicate;
private final Predicate<String> ignoreRolesPredicate;
private final Predicate<String> ignoreIndicesPredicate;
/**
* An empty filter list for a field will match events with that field missing.
* An event with an undefined field has the field value the empty string ("") or
* a singleton list of the empty string ([""]).
*/
EventFilterPolicy(String name, Settings settings) {
this.name = name;
ignorePrincipalsPredicate = Automatons.predicate(
emptyStringBuildsEmptyAutomaton(FILTER_POLICY_IGNORE_PRINCIPALS.getConcreteSettingForNamespace(name).get(settings)));
ignoreRealmsPredicate = Automatons.predicate(
emptyStringBuildsEmptyAutomaton(FILTER_POLICY_IGNORE_REALMS.getConcreteSettingForNamespace(name).get(settings)));
ignoreRolesPredicate = Automatons.predicate(
emptyStringBuildsEmptyAutomaton(FILTER_POLICY_IGNORE_ROLES.getConcreteSettingForNamespace(name).get(settings)));
ignoreIndicesPredicate = Automatons.predicate(
emptyStringBuildsEmptyAutomaton(FILTER_POLICY_IGNORE_INDICES.getConcreteSettingForNamespace(name).get(settings)));
}
/**
* It is a requirement that empty string filters match empty string fields. In
* this case we require automatons from empty string to match the empty string.
* `Automatons.predicate("").test("") == false`
* `Automatons.predicate("//").test("") == true`
*/
private List<String> emptyStringBuildsEmptyAutomaton(List<String> l) {
if (l.isEmpty()) {
return Collections.singletonList("//");
}
return l.stream().map(f -> f.isEmpty() ? "//" : f).collect(Collectors.toList());
}
/**
* ANDs the predicates of this filter policy. The `indices` and `roles` fields
* of an audit event are multi-valued and all values should match the filter
* predicate of the corresponding field.
*/
Predicate<AuditEventMetaInfo> ignorePredicate() {
return (eventInfo) -> {
return ignorePrincipalsPredicate.test(eventInfo.principal)
&& ignoreRealmsPredicate.test(eventInfo.realm)
&& eventInfo.roles.get().allMatch(ignoreRolesPredicate)
&& eventInfo.indices.get().allMatch(ignoreIndicesPredicate);
};
}
}
/**
* Builds the filter predicates for all the policies. Predicates of all policies
* are ORed together, so that an audit event matching any policy is ignored.
*/
private static final class EventFilterPolicyRegistry {
private final Map<String, Predicate<AuditEventMetaInfo>> policyMap;
EventFilterPolicyRegistry(Settings settings) {
final Map<String, Predicate<AuditEventMetaInfo>> map = new HashMap<>();
for (final String policyName : settings.getGroups(FILTER_POLICY_PREFIX, true).keySet()) {
map.put(policyName, new EventFilterPolicy(policyName, settings).ignorePredicate());
}
policyMap = Collections.unmodifiableMap(map);
}
Predicate<AuditEventMetaInfo> ignorePredicate() {
return policyMap.values().stream().reduce(x -> false, (x, y) -> x.or(y));
}
}
/**
* Abstraction for the fields of the audit event that are used for filtering. If
* an event has a missing field (one of `user`, `realm`, `roles` and `indices`)
* the value for the field will be the empty string or a singleton stream of the
* empty string.
*/
static final class AuditEventMetaInfo {
final String principal;
final String realm;
final Supplier<Stream<String>> roles;
final Supplier<Stream<String>> indices;
// empty is used for events can be filtered out only by the lack of a field
static final AuditEventMetaInfo EMPTY = new AuditEventMetaInfo(Optional.empty(), Optional.empty(), Optional.empty());
/**
* If a field is missing for an event, its value for filtering purposes is the
* empty string or a singleton stream of the empty string. This a allows a
* policy to filter by the missing value using the empty string, ie
* `ignore_filters.users: ["", "elastic"]` will filter events with a missing
* user field (such as `anonymous_access_denied`) as well as events from the
* "elastic" username.
*/
AuditEventMetaInfo(Optional<User> user, Optional<String> realm, Optional<String[]> roles, Optional<String[]> indices) {
this.principal = user.map(u -> u.principal()).orElse("");
this.realm = realm.orElse("");
// Supplier indirection and lazy generation of Streams serves 2 purposes:
// 1. streams might not get generated due to short circuiting logical
// conditions on the `principal` and `realm` fields
// 2. reusability of the AuditEventMetaInfo instance: in this case Streams have
// to be regenerated as they cannot be operated upon twice
this.roles = () -> roles.filter(r -> r.length != 0).map(Arrays::stream).orElse(Stream.of(""));
this.indices = () -> indices.filter(i -> i.length != 0).map(Arrays::stream).orElse(Stream.of(""));
}
AuditEventMetaInfo(Optional<AuthenticationToken> authenticationToken, Optional<String> realm, Optional<String[]> indices) {
this.principal = authenticationToken.map(u -> u.principal()).orElse("");
this.realm = realm.orElse("");
this.roles = () -> Stream.of("");
this.indices = () -> indices.filter(r -> r.length != 0).map(i -> Arrays.stream(i)).orElse(Stream.of(""));
}
}
@Override
@ -458,7 +677,7 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
}
}
protected static class LocalNodeInfo {
static class LocalNodeInfo {
private final DiscoveryNode localNode;
private final String prefix;
private final String localOriginTag;
@ -472,19 +691,19 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail,
static String resolvePrefix(Settings settings, @Nullable DiscoveryNode localNode) {
final StringBuilder builder = new StringBuilder();
if (HOST_ADDRESS_SETTING.get(settings)) {
String address = localNode != null ? localNode.getHostAddress() : null;
final String address = localNode != null ? localNode.getHostAddress() : null;
if (address != null) {
builder.append("[").append(address).append("] ");
}
}
if (HOST_NAME_SETTING.get(settings)) {
String hostName = localNode != null ? localNode.getHostName() : null;
final String hostName = localNode != null ? localNode.getHostName() : null;
if (hostName != null) {
builder.append("[").append(hostName).append("] ");
}
}
if (NODE_NAME_SETTING.get(settings)) {
String name = settings.get("name");
final String name = settings.get("name");
if (name != null) {
builder.append("[").append(name).append("] ");
}

View File

@ -27,7 +27,6 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.rest.FakeRestRequest;
import org.elasticsearch.test.rest.FakeRestRequest.Builder;
import org.elasticsearch.transport.TransportMessage;
import org.elasticsearch.xpack.security.audit.AuditUtil;
import org.elasticsearch.xpack.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.security.rest.RemoteHostHeader;
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
@ -53,7 +52,7 @@ import static org.mockito.Mockito.when;
public class LoggingAuditTrailTests extends ESTestCase {
private enum RestContent {
enum RestContent {
VALID() {
@Override
protected boolean hasContent() {
@ -62,12 +61,12 @@ public class LoggingAuditTrailTests extends ESTestCase {
@Override
protected BytesReference content() {
return new BytesArray("{ \"key\": \"value\"}");
return new BytesArray("{ \"key\": \"value\" }");
}
@Override
protected String expectedMessage() {
return "{ \"key\": \"value\"}";
return "{ \"key\": \"value\" }";
}
},
INVALID() {
@ -78,12 +77,12 @@ public class LoggingAuditTrailTests extends ESTestCase {
@Override
protected BytesReference content() {
return new BytesArray("{ \"key\": \"value\"");
return new BytesArray("{ \"key\": \"value\" ");
}
@Override
protected String expectedMessage() {
return "{ \"key\": \"value\"";
return "{ \"key\": \"value\" ";
}
},
EMPTY() {
@ -129,7 +128,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
clusterService = mock(ClusterService.class);
when(clusterService.localNode()).thenReturn(localNode);
Mockito.doAnswer((Answer) invocation -> {
LoggingAuditTrail arg0 = (LoggingAuditTrail) invocation.getArguments()[0];
final LoggingAuditTrail arg0 = (LoggingAuditTrail) invocation.getArguments()[0];
arg0.updateLocalNodeInfo(localNode);
return null;
}).when(clusterService).addListener(Mockito.isA(LoggingAuditTrail.class));
@ -138,10 +137,10 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAnonymousAccessDeniedTransport() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.anonymousAccessDenied("_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [anonymous_access_denied]\t" + origins +
@ -160,11 +159,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAnonymousAccessDeniedRest() throws Exception {
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.anonymousAccessDenied(request);
if (includeRequestBody) {
@ -184,10 +183,10 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailed() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.authenticationFailed(new MockToken(), "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
@ -207,10 +206,10 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailedNoToken() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.authenticationFailed("_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_failed]\t" + origins +
@ -229,11 +228,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailedRest() throws Exception {
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(new MockToken(), request);
if (includeRequestBody) {
@ -254,11 +253,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailedRestNoToken() throws Exception {
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed(request);
if (includeRequestBody) {
@ -278,9 +277,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailedRealm() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
assertEmptyLog(logger);
@ -288,7 +287,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
settings =
Settings.builder().put(settings).put("xpack.security.audit.logfile.events.include", "realm_authentication_failed").build();
auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [realm_authentication_failed]\trealm=[_realm], " + origins +
@ -301,11 +300,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationFailedRealmRest() throws Exception {
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationFailed("_realm", new MockToken(), request);
assertEmptyLog(logger);
@ -326,20 +325,20 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAccessGranted() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
boolean runAs = randomBoolean();
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String role = randomAlphaOfLengthBetween(1, 6);
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.accessGranted(user, "_action", message, new String[] { role });
String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
final String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
", roles=[" + role + "]";
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
@ -358,17 +357,17 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAccessGrantedInternalSystemAction() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String role = randomAlphaOfLengthBetween(1, 6);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.accessGranted(SystemUser.INSTANCE, "internal:_action", message, new String[] { role });
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);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.accessGranted(SystemUser.INSTANCE, "internal:_action", message, new String[] { role });
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
@ -382,20 +381,20 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAccessGrantedInternalSystemActionNonSystemUser() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
boolean runAs = randomBoolean();
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String role = randomAlphaOfLengthBetween(1, 6);
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.accessGranted(user, "internal:_action", message, new String[] { role });
String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
final String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
", roles=[" + role + "]";
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", " + userInfo +
@ -414,20 +413,20 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAccessDenied() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
boolean runAs = randomBoolean();
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
} else {
user = new User("_username", new String[]{"r1"});
}
String role = randomAlphaOfLengthBetween(1, 6);
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.accessDenied(user, "_action", message, new String[] { role });
String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
final String userInfo = (runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]") +
", roles=[" + role + "]";
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [access_denied]\t" + origins + ", " + userInfo +
@ -446,11 +445,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testTamperedRequestRest() throws Exception {
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200));
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.tamperedRequest(request);
if (includeRequestBody) {
@ -470,11 +469,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testTamperedRequest() throws Exception {
String action = "_action";
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final String action = "_action";
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.tamperedRequest(action, message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins +
@ -489,7 +488,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testTamperedRequestWithUser() throws Exception {
String action = "_action";
final String action = "_action";
final boolean runAs = randomBoolean();
User user;
if (runAs) {
@ -497,11 +496,11 @@ public class LoggingAuditTrailTests extends ESTestCase {
} else {
user = new User("_username", new String[]{"r1"});
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
auditTrail.tamperedRequest(user, action, message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [tampered_request]\t" + origins + ", " + userInfo +
@ -520,10 +519,10 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testConnectionDenied() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
InetAddress inetAddress = InetAddress.getLoopbackAddress();
SecurityIpFilterRule rule = new SecurityIpFilterRule(false, "_all");
final InetAddress inetAddress = InetAddress.getLoopbackAddress();
final 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]",
@ -538,10 +537,10 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testConnectionGranted() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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;
final InetAddress inetAddress = InetAddress.getLoopbackAddress();
final SecurityIpFilterRule rule = IPFilter.DEFAULT_PROFILE_ACCEPT_ALL;
auditTrail.connectionGranted(inetAddress, "default", rule);
assertEmptyLog(logger);
@ -555,15 +554,22 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testRunAsGranted() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
String role = randomAlphaOfLengthBetween(1, 6);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.runAsGranted(user, "_action", message, new String[] { role });
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_granted]\t" + origins +
", principal=[_username], run_as_principal=[running as], roles=[" + role + "], action=[_action], request=[MockMessage]");
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO,
prefix + "[transport] [run_as_granted]\t" + origins + ", principal=[_username], run_as_principal=[running as], roles=["
+ role + "], action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO,
prefix + "[transport] [run_as_granted]\t" + origins + ", principal=[_username], run_as_principal=[running as], roles=["
+ role + "], action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
@ -574,15 +580,22 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testRunAsDenied() throws Exception {
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
TransportMessage message = new MockMessage(threadContext);
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
String role = randomAlphaOfLengthBetween(1, 6);
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
final String role = randomAlphaOfLengthBetween(1, 6);
auditTrail.runAsDenied(user, "_action", message, new String[] { role });
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_denied]\t" + origins +
", principal=[_username], run_as_principal=[running as], roles=[" + role + "], action=[_action], request=[MockMessage]");
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO,
prefix + "[transport] [run_as_denied]\t" + origins + ", principal=[_username], run_as_principal=[running as], roles=["
+ role + "], action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO,
prefix + "[transport] [run_as_denied]\t" + origins + ", principal=[_username], run_as_principal=[running as], roles=["
+ role + "], action=[_action], request=[MockMessage]");
}
// test disabled
CapturingLogger.output(logger.getName(), Level.INFO).clear();
@ -593,17 +606,16 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testOriginAttributes() throws Exception {
MockMessage message = new MockMessage(threadContext);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
String text = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
final MockMessage message = new MockMessage(threadContext);
final LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
final String text = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
if (restAddress != null) {
assertThat(text, equalTo("origin_type=[rest], origin_address=[" +
NetworkAddress.format(restAddress.getAddress()) + "]"));
return;
}
TransportAddress address = message.remoteAddress();
final TransportAddress address = message.remoteAddress();
if (address == null) {
assertThat(text, equalTo("origin_type=[local_node], origin_address=[" + localNode.getHostAddress() + "]"));
return;
@ -614,26 +626,26 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
public void testAuthenticationSuccessRest() throws Exception {
Map<String, String> params = new HashMap<>();
final Map<String, String> params = new HashMap<>();
params.put("foo", "bar");
InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200), params);
String expectedMessage = tuple.v1().expectedMessage();
RestRequest request = tuple.v2();
boolean runAs = randomBoolean();
final InetAddress address = forge("_hostname", randomBoolean() ? "127.0.0.1" : "::1");
final Tuple<RestContent, RestRequest> tuple = prepareRestContent("_uri", new InetSocketAddress(address, 9200), params);
final String expectedMessage = tuple.v1().expectedMessage();
final RestRequest request = tuple.v2();
final boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
} else {
user = new User("_username", new String[] { "r1" });
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
String realm = "_realm";
final String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
final String realm = "_realm";
Settings settings = Settings.builder().put(this.settings)
.put("xpack.security.audit.logfile.events.include", "authentication_success")
.build();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
auditTrail.authenticationSuccess(realm, user, request);
if (includeRequestBody) {
@ -657,23 +669,23 @@ public class LoggingAuditTrailTests extends ESTestCase {
public void testAuthenticationSuccessTransport() throws Exception {
Settings settings = Settings.builder().put(this.settings)
.put("xpack.security.audit.logfile.events.include", "authentication_success").build();
Logger logger = CapturingLogger.newCapturingLogger(Level.INFO);
final 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(threadContext, message, auditTrail.localNodeInfo);
boolean runAs = randomBoolean();
final TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
final String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
final boolean runAs = randomBoolean();
User user;
if (runAs) {
user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
} else {
user = new User("_username", new String[] { "r1" });
}
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
String realm = "_realm";
final String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
final String realm = "_realm";
auditTrail.authenticationSuccess(realm, user, "_action", message);
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_success]\t" + origins + ", " + userInfo
+ ", realm=[_realm], action=[_action], request=[MockIndicesRequest]");
+ ", realm=[_realm], action=[_action], indices=[" + indices(message) + "], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.INFO, prefix + "[transport] [authentication_success]\t" + origins + ", " + userInfo
+ ", realm=[_realm], action=[_action], request=[MockMessage]");
@ -691,7 +703,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
private void assertMsg(Logger logger, Level level, String message) {
List<String> output = CapturingLogger.output(logger.getName(), level);
final List<String> output = CapturingLogger.output(logger.getName(), level);
assertThat(output.size(), is(1));
assertThat(output.get(0), equalTo(message));
}
@ -700,13 +712,13 @@ public class LoggingAuditTrailTests extends ESTestCase {
assertThat(CapturingLogger.isEmpty(logger.getName()), is(true));
}
private Tuple<RestContent, RestRequest> prepareRestContent(String uri, InetSocketAddress remoteAddress) {
protected Tuple<RestContent, RestRequest> prepareRestContent(String uri, InetSocketAddress remoteAddress) {
return prepareRestContent(uri, remoteAddress, Collections.emptyMap());
}
private Tuple<RestContent, RestRequest> prepareRestContent(String uri, InetSocketAddress remoteAddress, Map<String, String> params) {
RestContent content = randomFrom(RestContent.values());
FakeRestRequest.Builder builder = new Builder(NamedXContentRegistry.EMPTY);
final RestContent content = randomFrom(RestContent.values());
final FakeRestRequest.Builder builder = new Builder(NamedXContentRegistry.EMPTY);
if (content.hasContent()) {
builder.withContent(content.content(), XContentType.JSON);
}
@ -717,18 +729,18 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
/** creates address without any lookups. hostname can be null, for missing */
private static InetAddress forge(String hostname, String address) throws IOException {
byte bytes[] = InetAddress.getByName(address).getAddress();
protected static InetAddress forge(String hostname, String address) throws IOException {
final byte bytes[] = InetAddress.getByName(address).getAddress();
return InetAddress.getByAddress(hostname, bytes);
}
private static String indices(TransportMessage message) {
return Strings.collectionToCommaDelimitedString(AuditUtil.indices(message));
return Strings.arrayToCommaDelimitedString(((IndicesRequest) message).indices());
}
private static class MockMessage extends TransportMessage {
static class MockMessage extends TransportMessage {
private MockMessage(ThreadContext threadContext) throws IOException {
MockMessage(ThreadContext threadContext) throws IOException {
if (randomBoolean()) {
if (randomBoolean()) {
remoteAddress(buildNewFakeTransportAddress());
@ -742,9 +754,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
}
}
private static class MockIndicesRequest extends org.elasticsearch.action.MockIndicesRequest {
static class MockIndicesRequest extends org.elasticsearch.action.MockIndicesRequest {
private MockIndicesRequest(ThreadContext threadContext) throws IOException {
MockIndicesRequest(ThreadContext threadContext) throws IOException {
super(IndicesOptions.strictExpandOpenAndForbidClosed(), "idx1", "idx2");
if (randomBoolean()) {
remoteAddress(buildNewFakeTransportAddress());