mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-26 06:46:10 +00:00
LoggingAuditTrail emit events before local address available (elastic/x-pack-elasticsearch#3061)
Register LoggingAuditTrail as a ClusterStateListener. Avoid querying for the localNode while on the ClusterStateApplier thread, which tripps assertion. This can happen when logging audit events that originate from the system. relates elastic/x-pack-elasticsearch#3057 Original commit: elastic/x-pack-elasticsearch@66bc59682d
This commit is contained in:
parent
756d878983
commit
a5fe074b5c
@ -6,8 +6,11 @@
|
||||
package org.elasticsearch.xpack.security.audit.logfile;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||
import org.elasticsearch.cluster.ClusterStateListener;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.network.NetworkAddress;
|
||||
@ -36,6 +39,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
@ -57,7 +61,7 @@ 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 {
|
||||
public class LoggingAuditTrail extends AbstractComponent implements AuditTrail, ClusterStateListener {
|
||||
|
||||
public static final String NAME = "logfile";
|
||||
public static final Setting<Boolean> HOST_ADDRESS_SETTING =
|
||||
@ -84,12 +88,10 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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;
|
||||
private final ThreadContext threadContext;
|
||||
volatile LocalNodeInfo localNodeInfo;
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
@ -103,28 +105,22 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
LoggingAuditTrail(Settings settings, ClusterService clusterService, Logger logger, ThreadContext threadContext) {
|
||||
super(settings);
|
||||
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() {
|
||||
if (prefix == null) {
|
||||
prefix = resolvePrefix(settings, clusterService.localNode());
|
||||
}
|
||||
return prefix;
|
||||
this.threadContext = threadContext;
|
||||
this.localNodeInfo = new LocalNodeInfo(settings, null);
|
||||
clusterService.addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticationSuccess(String realm, User user, RestRequest request) {
|
||||
if (events.contains(AUTHENTICATION_SUCCESS)) {
|
||||
if (includeRequestBody) {
|
||||
logger.info("{}[rest] [authentication_success]\t{}, realm=[{}], uri=[{}], params=[{}], request_body=[{}]", getPrefix(),
|
||||
principal(user), realm, request.uri(), request.params(), restRequestContent(request));
|
||||
logger.info("{}[rest] [authentication_success]\t{}, realm=[{}], uri=[{}], params=[{}], request_body=[{}]",
|
||||
localNodeInfo.prefix, principal(user), realm, request.uri(), request.params(), restRequestContent(request));
|
||||
} else {
|
||||
logger.info("{}[rest] [authentication_success]\t{}, realm=[{}], uri=[{}], params=[{}]", getPrefix(), principal(user), realm,
|
||||
request.uri(), request.params());
|
||||
logger.info("{}[rest] [authentication_success]\t{}, realm=[{}], uri=[{}], params=[{}]", localNodeInfo.prefix,
|
||||
principal(user), realm, request.uri(), request.params());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,8 +128,9 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
@Override
|
||||
public void authenticationSuccess(String realm, User user, String action, TransportMessage message) {
|
||||
if (events.contains(AUTHENTICATION_SUCCESS)) {
|
||||
logger.info("{}[transport] [authentication_success]\t{}, {}, realm=[{}], action=[{}], request=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), principal(user), realm, action,
|
||||
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());
|
||||
}
|
||||
}
|
||||
@ -142,13 +139,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
|
||||
logger.info("{}[transport] [anonymous_access_denied]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,10 +155,11 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void anonymousAccessDenied(RestRequest request) {
|
||||
if (events.contains(ANONYMOUS_ACCESS_DENIED)) {
|
||||
if (includeRequestBody) {
|
||||
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}], request_body=[{}]", getPrefix(),
|
||||
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}], request_body=[{}]", localNodeInfo.prefix,
|
||||
hostAttributes(request), request.uri(), restRequestContent(request));
|
||||
} else {
|
||||
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}]", getPrefix(), hostAttributes(request), request.uri());
|
||||
logger.info("{}[rest] [anonymous_access_denied]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request),
|
||||
request.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,13 +168,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]",
|
||||
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), token.principal(),
|
||||
action, indices, message.getClass().getSimpleName());
|
||||
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action, indices,
|
||||
message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.info("{}[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=[{}]",
|
||||
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
|
||||
message.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@ -186,10 +186,11 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void authenticationFailed(RestRequest request) {
|
||||
if (events.contains(AUTHENTICATION_FAILED)) {
|
||||
if (includeRequestBody) {
|
||||
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}], request_body=[{}]", getPrefix(), hostAttributes(request),
|
||||
request.uri(), restRequestContent(request));
|
||||
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=[{}]", getPrefix(), hostAttributes(request), request.uri());
|
||||
logger.info("{}[rest] [authentication_failed]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request),
|
||||
request.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,13 +199,13 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
|
||||
message.getClass().getSimpleName());
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action, message.getClass().getSimpleName());
|
||||
logger.info("{}[transport] [authentication_failed]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,11 +214,11 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void authenticationFailed(AuthenticationToken token, RestRequest request) {
|
||||
if (events.contains(AUTHENTICATION_FAILED)) {
|
||||
if (includeRequestBody) {
|
||||
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}], request_body=[{}]", getPrefix(),
|
||||
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=[{}]", getPrefix(), hostAttributes(request),
|
||||
token.principal(), request.uri());
|
||||
logger.info("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", localNodeInfo.prefix,
|
||||
hostAttributes(request), token.principal(), request.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,14 +227,15 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]", getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext),
|
||||
"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=[{}]",
|
||||
getPrefix(), realm, originAttributes(message, clusterService.localNode(), threadContext), token.principal(),
|
||||
action, message.getClass().getSimpleName());
|
||||
localNodeInfo.prefix, realm, originAttributes(threadContext, message, localNodeInfo), token.principal(), action,
|
||||
message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,9 +245,10 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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));
|
||||
localNodeInfo.prefix, realm, hostAttributes(request), token.principal(), request.uri(),
|
||||
restRequestContent(request));
|
||||
} else {
|
||||
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}]", getPrefix(),
|
||||
logger.info("{}[rest] [realm_authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}]", localNodeInfo.prefix,
|
||||
realm, hostAttributes(request), token.principal(), request.uri());
|
||||
}
|
||||
}
|
||||
@ -258,13 +261,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
|
||||
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), principal(user), action, indices,
|
||||
message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
|
||||
logger.info("{}[transport] [access_granted]\t{}, {}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), principal(user), action,
|
||||
message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
@ -274,13 +278,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void accessDenied(User user, String action, TransportMessage message) {
|
||||
if (events.contains(ACCESS_DENIED)) {
|
||||
String indices = indicesString(message);
|
||||
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
|
||||
if (indices != null) {
|
||||
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], indices=[{}], request=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action, indices,
|
||||
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], indices=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), principal(user), action, indices,
|
||||
message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], request=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), principal(user), action,
|
||||
logger.info("{}[transport] [access_denied]\t{}, {}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), principal(user), action,
|
||||
message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
@ -290,10 +295,10 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void tamperedRequest(RestRequest request) {
|
||||
if (events.contains(TAMPERED_REQUEST)) {
|
||||
if (includeRequestBody) {
|
||||
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}], request_body=[{}]", getPrefix(), 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=[{}]", getPrefix(), hostAttributes(request), request.uri());
|
||||
logger.info("{}[rest] [tampered_request]\t{}, uri=[{}]", localNodeInfo.prefix, hostAttributes(request), request.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,14 +307,13 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action, indices,
|
||||
message.getClass().getSimpleName());
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(message, clusterService.localNode(), threadContext), action,
|
||||
message.getClass().getSimpleName());
|
||||
logger.info("{}[transport] [tampered_request]\t{}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, message, localNodeInfo), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -318,13 +322,14 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action, indices,
|
||||
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=[{}]", getPrefix(),
|
||||
originAttributes(request, clusterService.localNode(), threadContext), principal(user), action,
|
||||
logger.info("{}[transport] [tampered_request]\t{}, {}, action=[{}], request=[{}]", localNodeInfo.prefix,
|
||||
originAttributes(threadContext, request, localNodeInfo), principal(user), action,
|
||||
request.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
@ -333,24 +338,25 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
@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=[{}]", getPrefix(),
|
||||
NetworkAddress.format(inetAddress), profile, rule);
|
||||
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=[{}]", getPrefix(),
|
||||
NetworkAddress.format(inetAddress), profile, rule);
|
||||
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) {
|
||||
if (events.contains(RUN_AS_GRANTED)) {
|
||||
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
|
||||
logger.info("{}[transport] [run_as_granted]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
|
||||
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), user.authenticatedUser().principal(),
|
||||
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), user.authenticatedUser().principal(),
|
||||
user.principal(), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
@ -358,8 +364,9 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
@Override
|
||||
public void runAsDenied(User user, String action, TransportMessage message) {
|
||||
if (events.contains(RUN_AS_DENIED)) {
|
||||
final LocalNodeInfo localNodeInfo = this.localNodeInfo;
|
||||
logger.info("{}[transport] [run_as_denied]\t{}, principal=[{}], run_as_principal=[{}], action=[{}], request=[{}]",
|
||||
getPrefix(), originAttributes(message, clusterService.localNode(), threadContext), user.authenticatedUser().principal(),
|
||||
localNodeInfo.prefix, originAttributes(threadContext, message, localNodeInfo), user.authenticatedUser().principal(),
|
||||
user.principal(), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
@ -368,11 +375,11 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
public void runAsDenied(User user, RestRequest request) {
|
||||
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));
|
||||
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}], request_body=[{}]", localNodeInfo.prefix,
|
||||
hostAttributes(request), user.principal(), request.uri(), restRequestContent(request));
|
||||
} else {
|
||||
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}]", getPrefix(),
|
||||
hostAttributes(request), user.principal(), request.uri());
|
||||
logger.info("{}[rest] [run_as_denied]\t{}, principal=[{}], uri=[{}]", localNodeInfo.prefix, hostAttributes(request),
|
||||
user.principal(), request.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -388,56 +395,29 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
return "origin_address=[" + formattedAddress + "]";
|
||||
}
|
||||
|
||||
static String originAttributes(TransportMessage message, DiscoveryNode localNode, ThreadContext threadContext) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// first checking if the message originated in a rest call
|
||||
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
|
||||
if (restAddress != null) {
|
||||
builder.append("origin_type=[rest], origin_address=[").
|
||||
append(NetworkAddress.format(restAddress.getAddress())).
|
||||
append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
// we'll see if was originated in a remote node
|
||||
TransportAddress address = message.remoteAddress();
|
||||
if (address != null) {
|
||||
builder.append("origin_type=[transport], ");
|
||||
builder.append("origin_address=[").
|
||||
append(NetworkAddress.format(address.address().getAddress())).
|
||||
append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
// the call was originated locally on this node
|
||||
return builder.append("origin_type=[local_node], origin_address=[")
|
||||
.append(localNode.getHostAddress())
|
||||
.append("]")
|
||||
.toString();
|
||||
protected static String originAttributes(ThreadContext threadContext, TransportMessage message, LocalNodeInfo localNodeInfo) {
|
||||
return restOriginTag(threadContext).orElse(transportOriginTag(message).orElse(localNodeInfo.localOriginTag));
|
||||
}
|
||||
|
||||
static String resolvePrefix(Settings settings, DiscoveryNode localNode) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (HOST_ADDRESS_SETTING.get(settings)) {
|
||||
String address = localNode.getHostAddress();
|
||||
if (address != null) {
|
||||
builder.append("[").append(address).append("] ");
|
||||
}
|
||||
private static Optional<String> restOriginTag(ThreadContext threadContext) {
|
||||
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
|
||||
if (restAddress == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (HOST_NAME_SETTING.get(settings)) {
|
||||
String hostName = localNode.getHostName();
|
||||
if (hostName != null) {
|
||||
builder.append("[").append(hostName).append("] ");
|
||||
}
|
||||
return Optional.of(new StringBuilder("origin_type=[rest], origin_address=[").append(NetworkAddress.format(restAddress.getAddress()))
|
||||
.append("]")
|
||||
.toString());
|
||||
}
|
||||
|
||||
private static Optional<String> transportOriginTag(TransportMessage message) {
|
||||
TransportAddress address = message.remoteAddress();
|
||||
if (address == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (NODE_NAME_SETTING.get(settings)) {
|
||||
String name = settings.get("name");
|
||||
if (name != null) {
|
||||
builder.append("[").append(name).append("] ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
return Optional.of(
|
||||
new StringBuilder("origin_type=[transport], origin_address=[").append(NetworkAddress.format(address.address().getAddress()))
|
||||
.append("]")
|
||||
.toString());
|
||||
}
|
||||
|
||||
static String indicesString(TransportMessage message) {
|
||||
@ -462,4 +442,62 @@ public class LoggingAuditTrail extends AbstractComponent implements AuditTrail {
|
||||
settings.add(EXCLUDE_EVENT_SETTINGS);
|
||||
settings.add(INCLUDE_REQUEST_BODY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clusterChanged(ClusterChangedEvent event) {
|
||||
updateLocalNodeInfo(event.state().getNodes().getLocalNode());
|
||||
}
|
||||
|
||||
void updateLocalNodeInfo(DiscoveryNode newLocalNode) {
|
||||
// check if local node changed
|
||||
final DiscoveryNode localNode = localNodeInfo.localNode;
|
||||
if (localNode == null || localNode.equals(newLocalNode) == false) {
|
||||
// no need to synchronize, called only from the cluster state applier thread
|
||||
localNodeInfo = new LocalNodeInfo(settings, newLocalNode);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class LocalNodeInfo {
|
||||
private final DiscoveryNode localNode;
|
||||
private final String prefix;
|
||||
private final String localOriginTag;
|
||||
|
||||
LocalNodeInfo(Settings settings, @Nullable DiscoveryNode newLocalNode) {
|
||||
this.localNode = newLocalNode;
|
||||
this.prefix = resolvePrefix(settings, newLocalNode);
|
||||
this.localOriginTag = localOriginTag(newLocalNode);
|
||||
}
|
||||
|
||||
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;
|
||||
if (address != null) {
|
||||
builder.append("[").append(address).append("] ");
|
||||
}
|
||||
}
|
||||
if (HOST_NAME_SETTING.get(settings)) {
|
||||
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");
|
||||
if (name != null) {
|
||||
builder.append("[").append(name).append("] ");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String localOriginTag(@Nullable DiscoveryNode localNode) {
|
||||
if (localNode == null) {
|
||||
return "origin_type=[local_node]";
|
||||
}
|
||||
return new StringBuilder("origin_type=[local_node], origin_address=[").append(localNode.getHostAddress())
|
||||
.append("]")
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.mock.orig.Mockito;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.rest.FakeRestRequest;
|
||||
@ -34,6 +35,7 @@ import org.elasticsearch.xpack.security.transport.filter.SecurityIpFilterRule;
|
||||
import org.elasticsearch.xpack.security.user.SystemUser;
|
||||
import org.elasticsearch.xpack.security.user.User;
|
||||
import org.junit.Before;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
@ -126,7 +128,12 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
when(localNode.getHostAddress()).thenReturn(buildNewFakeTransportAddress().toString());
|
||||
clusterService = mock(ClusterService.class);
|
||||
when(clusterService.localNode()).thenReturn(localNode);
|
||||
prefix = LoggingAuditTrail.resolvePrefix(settings, localNode);
|
||||
Mockito.doAnswer((Answer) invocation -> {
|
||||
LoggingAuditTrail arg0 = (LoggingAuditTrail) invocation.getArguments()[0];
|
||||
arg0.updateLocalNodeInfo(localNode);
|
||||
return null;
|
||||
}).when(clusterService).addListener(Mockito.isA(LoggingAuditTrail.class));
|
||||
prefix = LoggingAuditTrail.LocalNodeInfo.resolvePrefix(settings, localNode);
|
||||
threadContext = new ThreadContext(Settings.EMPTY);
|
||||
}
|
||||
|
||||
@ -134,7 +141,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
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 +
|
||||
@ -180,7 +187,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);;
|
||||
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 +
|
||||
@ -203,7 +210,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);;
|
||||
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 +
|
||||
@ -274,7 +281,6 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
|
||||
@ -282,6 +288,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);
|
||||
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [realm_authentication_failed]\trealm=[_realm], " + origins +
|
||||
@ -322,7 +329,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
boolean runAs = randomBoolean();
|
||||
User user;
|
||||
if (runAs) {
|
||||
@ -352,13 +359,13 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
auditTrail.accessGranted(SystemUser.INSTANCE, "internal:_action", message);
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" +
|
||||
@ -374,7 +381,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
boolean runAs = randomBoolean();
|
||||
User user;
|
||||
if (runAs) {
|
||||
@ -404,7 +411,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
boolean runAs = randomBoolean();
|
||||
User user;
|
||||
if (runAs) {
|
||||
@ -457,9 +464,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
public void testTamperedRequest() throws Exception {
|
||||
String action = "_action";
|
||||
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);
|
||||
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 +
|
||||
@ -484,9 +491,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
}
|
||||
String userInfo = runAs ? "principal=[running as], run_by_principal=[_username]" : "principal=[_username]";
|
||||
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);
|
||||
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 +
|
||||
@ -543,7 +550,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
|
||||
auditTrail.runAsGranted(user, "_action", message);
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_granted]\t" + origins +
|
||||
@ -561,7 +568,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
User user = new User("running as", new String[]{"r2"}, new User("_username", new String[] {"r1"}));
|
||||
auditTrail.runAsDenied(user, "_action", message);
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [run_as_denied]\t" + origins +
|
||||
@ -578,7 +585,8 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
public void testOriginAttributes() throws Exception {
|
||||
|
||||
MockMessage message = new MockMessage(threadContext);
|
||||
String text = LoggingAuditTrail.originAttributes(message, localNode, threadContext);;
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext);
|
||||
String text = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(threadContext);
|
||||
if (restAddress != null) {
|
||||
assertThat(text, equalTo("origin_type=[rest], origin_address=[" +
|
||||
@ -642,7 +650,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||
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);
|
||||
String origins = LoggingAuditTrail.originAttributes(threadContext, message, auditTrail.localNodeInfo);
|
||||
boolean runAs = randomBoolean();
|
||||
User user;
|
||||
if (runAs) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user