[Fix] removed null hosts in the audit logs
Some request are created locally by elasticsearch and therefore are not associated with a remote address (we only associate the remote address with a request that arrives remotely from via the transport layer). An example of such request is the periodic nodes info that is collected by elasticsearch. Also, requests that originate from the REST layer also create transport requests locally. This commit takes this behaviour into account and makes sure that we'll always log the host in the audit logs. We do that in the following way: - `host` is replaced by two attributes: `origin_type` and `origin_address`. `origin_type` can be either `rest`, `remote_node` or `local_node`. `origin_address` holds the host address of the origin - when no remote address is associated with the request, it's safe to assume it was created locally. We'll then output `origin_type=[local_node] origin_address=[<the localhost address>]` - when a rest request gets in, we'll copy and place its remote address in the context of the request (the context of the rest request is copied to the context of the transport request) - . in the audit logs, we'll inspect the transport request and look for a `rest_host` in its context. if we find it, we'll log the log entry under `origin_type=[rest], origin_address=[<the remote rest address>]` attributes. This way, the origin of the request won't get "lost" and we'll still differentiate between transport hosts and rest hosts. - if the request is holds a remote address, it can only come from the transport layer, so we'll output "origin_type=[transport] origin_address=[<remote address]" While at it, also changed the format of the log entries: - lowercased the whole message (e.g. `ANONYMOUS_ACCESS` to `[anonymous_access]` (for consistency sake) - introduced layer categorization for every entry to indicate whether its `[transport]`, `[rest]` or `[ip_filter]` related. I reckon this will make it easier to parse the logs if one wishes to do so. Fixes elastic/elasticsearch#550 Original commit: elastic/x-pack-elasticsearch@b84f0c5548
This commit is contained in:
parent
98c3531bf9
commit
d7d96d866e
|
@ -10,19 +10,24 @@ import org.elasticsearch.common.Strings;
|
|||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.network.NetworkUtils;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.shield.User;
|
||||
import org.elasticsearch.shield.audit.AuditTrail;
|
||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
||||
import org.elasticsearch.shield.authz.Privilege;
|
||||
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
||||
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
||||
import org.elasticsearch.transport.TransportMessage;
|
||||
import org.elasticsearch.transport.TransportRequest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/**
|
||||
|
@ -63,15 +68,15 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
String indices = indices(message);
|
||||
if (indices != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ANONYMOUS_ACCESS\thost=[{}], action=[{}], indices=[{}], request=[{}]", prefix, message.remoteAddress(), action, indices, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [anonymous_access]\t{}, action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.warn("{}ANONYMOUS_ACCESS\thost=[{}], action=[{}], indices=[{}]", prefix, message.remoteAddress(), action, indices);
|
||||
logger.warn("{}[transport] [anonymous_access]\t{}, action=[{}], indices=[{}]", prefix, originAttributes(message), action, indices);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ANONYMOUS_ACCESS\thost=[{}], action=[{}], request=[{}]", prefix, message.remoteAddress(), action, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [anonymous_access]\t{}, action=[{}], request=[{}]", prefix, originAttributes(message), action, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.warn("{}ANONYMOUS_ACCESS\thost=[{}], action=[{}]", prefix, message.remoteAddress(), action);
|
||||
logger.warn("{}[transport] [anonymous_access]\t{}, action=[{}]", prefix, originAttributes(message), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,9 +84,9 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
@Override
|
||||
public void anonymousAccess(RestRequest request) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ANONYMOUS_ACCESS\thost=[{}], URI=[{}], request=[{}]", prefix, request.getRemoteAddress(), request.uri(), restRequestContent(request));
|
||||
logger.debug("{}[rest] [anonymous_access]\t{}, uri=[{}], request_body=[{}]", prefix, hostAttributes(request), request.uri(), restRequestContent(request));
|
||||
} else {
|
||||
logger.warn("{}ANONYMOUS_ACCESS\thost=[{}], URI=[{}]", prefix, request.getRemoteAddress(), request.uri());
|
||||
logger.warn("{}[rest] [anonymous_access]\t{}, uri=[{}]", prefix, hostAttributes(request), request.uri());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,15 +95,15 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
String indices = indices(message);
|
||||
if (indices != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, message.remoteAddress(), token.principal(), action, indices, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message), token.principal(), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], action=[{}], indices=[{}]", prefix, message.remoteAddress(), token.principal(), action, indices);
|
||||
logger.error("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], indices=[{}]", prefix, originAttributes(message), token.principal(), action, indices);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, message.remoteAddress(), token.principal(), action, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}], request=[{}]", prefix, originAttributes(message), token.principal(), action, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], action=[{}]", prefix, message.remoteAddress(), token.principal(), action);
|
||||
logger.error("{}[transport] [authentication_failed]\t{}, principal=[{}], action=[{}]", prefix, originAttributes(message), token.principal(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,9 +111,9 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
@Override
|
||||
public void authenticationFailed(AuthenticationToken token, RestRequest request) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], URI=[{}], request=[{}]", prefix, request.getRemoteAddress(), token.principal(), request.uri(), restRequestContent(request));
|
||||
logger.debug("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}], request_body=[{}]", prefix, hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
|
||||
} else {
|
||||
logger.error("{}AUTHENTICATION_FAILED\thost=[{}], principal=[{}], URI=[{}]", prefix, request.getRemoteAddress(), token.principal(), request.uri());
|
||||
logger.error("{}[rest] [authentication_failed]\t{}, principal=[{}], uri=[{}]", prefix, hostAttributes(request), token.principal(), request.uri());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,9 +122,9 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
if (logger.isTraceEnabled()) {
|
||||
String indices = indices(message);
|
||||
if (indices != null) {
|
||||
logger.trace("{}AUTHENTICATION_FAILED[{}]\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, realm, message.remoteAddress(), token.principal(), action, indices, message.getClass().getSimpleName());
|
||||
logger.trace("{}[transport] [authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, realm, originAttributes(message), token.principal(), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.trace("{}AUTHENTICATION_FAILED[{}]\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, realm, message.remoteAddress(), token.principal(), action, message.getClass().getSimpleName());
|
||||
logger.trace("{}[transport] [authentication_failed]\trealm=[{}], {}, principal=[{}], action=[{}], request=[{}]", prefix, realm, originAttributes(message), token.principal(), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +132,7 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
@Override
|
||||
public void authenticationFailed(String realm, AuthenticationToken token, RestRequest request) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("{}AUTHENTICATION_FAILED[{}]\thost=[{}], principal=[{}], URI=[{}], request=[{}]", prefix, realm, request.getRemoteAddress(), token.principal(), request.uri(), restRequestContent(request));
|
||||
logger.trace("{}[rest] [authentication_failed]\trealm=[{}], {}, principal=[{}], uri=[{}], request_body=[{}]", prefix, realm, hostAttributes(request), token.principal(), request.uri(), restRequestContent(request));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,9 +144,9 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
if (Privilege.SYSTEM.internalActionPredicate().apply(action)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
if (indices != null) {
|
||||
logger.trace("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
logger.trace("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.trace("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, message.getClass().getSimpleName());
|
||||
logger.trace("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, message.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -149,15 +154,15 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
|
||||
if (indices != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.info("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}], indices=[{}]", prefix, message.remoteAddress(), user.principal(), action, indices);
|
||||
logger.info("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}], indices=[{}]", prefix, originAttributes(message), user.principal(), action, indices);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.info("{}ACCESS_GRANTED\thost=[{}], principal=[{}], action=[{}]", prefix, message.remoteAddress(), user.principal(), action);
|
||||
logger.info("{}[transport] [access_granted]\t{}, principal=[{}], action=[{}]", prefix, originAttributes(message), user.principal(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,15 +172,15 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
String indices = indices(message);
|
||||
if (indices != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ACCESS_DENIED\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [access_denied]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, indices, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}ACCESS_DENIED\thost=[{}], principal=[{}], action=[{}], indices=[{}]", prefix, message.remoteAddress(), user.principal(), action, indices);
|
||||
logger.error("{}[transport] [access_denied]\t{}, principal=[{}], action=[{}], indices=[{}]", prefix, originAttributes(message), user.principal(), action, indices);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}ACCESS_DENIED\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, message.remoteAddress(), user.principal(), action, message.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [access_denied]\t{}, principal=[{}], action=[{}], request=[{}]", prefix, originAttributes(message), user.principal(), action, message.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}ACCESS_DENIED\thost=[{}], principal=[{}], action=[{}]", prefix, message.remoteAddress(), user.principal(), action);
|
||||
logger.error("{}[transport] [access_denied]\t{}, principal=[{}], action=[{}]", prefix, originAttributes(message), user.principal(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,15 +190,15 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
String indices = indices(request);
|
||||
if (indices != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}TAMPERED REQUEST\thost=[{}], principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, request.remoteAddress(), user.principal(), action, indices, request.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [tampered_request]\t{}, principal=[{}], action=[{}], indices=[{}], request=[{}]", prefix, request.remoteAddress(), user.principal(), action, indices, request.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}TAMPERED REQUEST\thost=[{}], principal=[{}], action=[{}], indices=[{}]", prefix, request.remoteAddress(), user.principal(), action, indices);
|
||||
logger.error("{}[transport] [tampered_request]\t{}, principal=[{}], action=[{}], indices=[{}]", prefix, request.remoteAddress(), user.principal(), action, indices);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("{}TAMPERED REQUEST\thost=[{}], principal=[{}], action=[{}], request=[{}]", prefix, request.remoteAddress(), user.principal(), action, request.getClass().getSimpleName());
|
||||
logger.debug("{}[transport] [tampered_request]\t{}, principal=[{}], action=[{}], request=[{}]", prefix, request.remoteAddress(), user.principal(), action, request.getClass().getSimpleName());
|
||||
} else {
|
||||
logger.error("{}TAMPERED REQUEST\thost=[{}], principal=[{}], action=[{}]", prefix, request.remoteAddress(), user.principal(), action);
|
||||
logger.error("{}[transport] [tampered_request]\t{}, principal=[{}], action=[{}]", prefix, request.remoteAddress(), user.principal(), action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,13 +206,13 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
@Override
|
||||
public void connectionGranted(InetAddress inetAddress, String profile, ShieldIpFilterRule rule) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("{}CONNECTION_GRANTED\thost=[{}], profile=[{}], rule=[{}]", prefix, inetAddress.getHostAddress(), profile, rule);
|
||||
logger.trace("{}[ip_filter] [connection_granted]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", prefix, inetAddress.getHostAddress(), profile, rule);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionDenied(InetAddress inetAddress, String profile, ShieldIpFilterRule rule) {
|
||||
logger.error("{}CONNECTION_DENIED\thost=[{}], profile=[{}], rule=[{}]", prefix, inetAddress.getHostAddress(), profile, rule);
|
||||
logger.error("{}[ip_filter] [connection_denied]\torigin_address=[{}], transport_profile=[{}], rule=[{}]", prefix, inetAddress.getHostAddress(), profile, rule);
|
||||
}
|
||||
|
||||
private static String indices(TransportMessage message) {
|
||||
|
@ -228,6 +233,39 @@ public class LoggingAuditTrail implements AuditTrail {
|
|||
return "";
|
||||
}
|
||||
|
||||
private static String hostAttributes(RestRequest request) {
|
||||
return "origin_address=[" + request.getRemoteAddress() + "]";
|
||||
}
|
||||
|
||||
static String originAttributes(TransportMessage message) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// first checking if the message originated in a rest call
|
||||
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(message);
|
||||
if (restAddress != null) {
|
||||
builder.append("origin_type=[rest], origin_address=[").append(restAddress).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], ");
|
||||
if (address instanceof InetSocketTransportAddress) {
|
||||
builder.append("origin_address=[").append(((InetSocketTransportAddress) address).address()).append("]");
|
||||
} else {
|
||||
builder.append("origin_address=[").append(address).append("]");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
// the call was originated locally on this node
|
||||
return builder.append("origin_type=[local_node], origin_address=[")
|
||||
.append(NetworkUtils.getLocalHostAddress("_local"))
|
||||
.append("]")
|
||||
.toString();
|
||||
}
|
||||
|
||||
static String resolvePrefix(Settings settings) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (settings.getAsBoolean("shield.audit.logfile.prefix.node_host_address", false)) {
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.shield.rest;
|
||||
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.transport.TransportMessage;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class RemoteHostHeader {
|
||||
|
||||
static final String KEY = "_rest_remote_address";
|
||||
|
||||
/**
|
||||
* Extracts the remote address from the given rest request and puts in the request context. This will
|
||||
* then be copied to the subsequent action requests.
|
||||
*/
|
||||
public static void process(RestRequest request) {
|
||||
request.putInContext(KEY, request.getRemoteAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the rest remote address from the message context. If not found, returns {@code null}. transport
|
||||
* messages that were created by rest handlers, should have this in their context.
|
||||
*/
|
||||
public static InetSocketAddress restRemoteAddress(TransportMessage message) {
|
||||
SocketAddress address = message.getFromContext(KEY);
|
||||
if (address != null && address instanceof InetSocketAddress) {
|
||||
return (InetSocketAddress) address;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void putRestRemoteAddress(TransportMessage message, SocketAddress address) {
|
||||
message.putInContext(KEY, address);
|
||||
}
|
||||
}
|
|
@ -35,6 +35,8 @@ public class ShieldRestFilter extends RestFilter {
|
|||
service.authenticate(request);
|
||||
}
|
||||
|
||||
RemoteHostHeader.process(request);
|
||||
|
||||
filterChain.continueProcessing(request, channel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,16 @@ import org.elasticsearch.action.IndicesRequest;
|
|||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.network.NetworkUtils;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.common.transport.LocalTransportAddress;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.shield.User;
|
||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
||||
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
||||
import org.elasticsearch.shield.transport.filter.IPFilter;
|
||||
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
|
@ -115,6 +119,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.anonymousAccess("_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
|
@ -123,17 +128,17 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
case WARN:
|
||||
case INFO:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.WARN, prefix + "ANONYMOUS_ACCESS\thost=[local[_host]], action=[_action], indices=[idx1,idx2]");
|
||||
assertMsg(logger, Level.WARN, prefix + "[transport] [anonymous_access]\t" + origins + ", action=[_action], indices=[idx1,idx2]");
|
||||
} else {
|
||||
assertMsg(logger, Level.WARN, prefix + "ANONYMOUS_ACCESS\thost=[local[_host]], action=[_action]");
|
||||
assertMsg(logger, Level.WARN, prefix + "[transport] [anonymous_access]\t" + origins + ", action=[_action]");
|
||||
}
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ANONYMOUS_ACCESS\thost=[local[_host]], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [anonymous_access]\t" + origins + ", action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ANONYMOUS_ACCESS\thost=[local[_host]], action=[_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [anonymous_access]\t" + origins + ", action=[_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,11 +161,11 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
break;
|
||||
case WARN:
|
||||
case INFO:
|
||||
assertMsg(logger, Level.WARN, prefix + "ANONYMOUS_ACCESS\thost=[_hostname:9200], URI=[_uri]");
|
||||
assertMsg(logger, Level.WARN, prefix + "[rest] [anonymous_access]\torigin_address=[_hostname:9200], uri=[_uri]");
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ANONYMOUS_ACCESS\thost=[_hostname:9200], URI=[_uri], request=[" + expectedMessage + "]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[rest] [anonymous_access]\torigin_address=[_hostname:9200], uri=[_uri], request_body=[" + expectedMessage + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,23 +176,24 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.authenticationFailed(new MockToken(), "_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
case WARN:
|
||||
case INFO:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.ERROR, prefix + "AUTHENTICATION_FAILED\thost=[local[_host]], principal=[_principal], action=[_action], indices=[idx1,idx2]");
|
||||
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins + ", principal=[_principal], action=[_action], indices=[idx1,idx2]");
|
||||
} else {
|
||||
assertMsg(logger, Level.ERROR, prefix + "AUTHENTICATION_FAILED\thost=[local[_host]], principal=[_principal], action=[_action]");
|
||||
assertMsg(logger, Level.ERROR, prefix + "[transport] [authentication_failed]\t" + origins + ", principal=[_principal], action=[_action]");
|
||||
}
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "AUTHENTICATION_FAILED\thost=[local[_host]], principal=[_principal], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins + ", principal=[_principal], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "AUTHENTICATION_FAILED\thost=[local[_host]], principal=[_principal], action=[_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [authentication_failed]\t" + origins + ", principal=[_principal], action=[_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,11 +213,11 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
case ERROR:
|
||||
case WARN:
|
||||
case INFO:
|
||||
assertMsg(logger, Level.ERROR, prefix + "AUTHENTICATION_FAILED\thost=[_hostname:9200], principal=[_principal], URI=[_uri]");
|
||||
assertMsg(logger, Level.ERROR, prefix + "[rest] [authentication_failed]\torigin_address=[_hostname:9200], principal=[_principal], uri=[_uri]");
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
assertMsg(logger, Level.DEBUG, prefix + "AUTHENTICATION_FAILED\thost=[_hostname:9200], principal=[_principal], URI=[_uri], request=[" + expectedMessage + "]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[rest] [authentication_failed]\torigin_address=[_hostname:9200], principal=[_principal], uri=[_uri], request_body=[" + expectedMessage + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,6 +228,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.authenticationFailed("_realm", new MockToken(), "_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
|
@ -232,9 +239,9 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
break;
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.TRACE, prefix + "AUTHENTICATION_FAILED[_realm]\thost=[local[_host]], principal=[_principal], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.TRACE, prefix + "[transport] [authentication_failed]\trealm=[_realm], " + origins + ", principal=[_principal], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.TRACE, prefix + "AUTHENTICATION_FAILED[_realm]\thost=[local[_host]], principal=[_principal], action=[_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.TRACE, prefix + "[transport] [authentication_failed]\trealm=[_realm], " + origins + ", principal=[_principal], action=[_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +265,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
assertEmptyLog(logger);
|
||||
break;
|
||||
case TRACE:
|
||||
assertMsg(logger, Level.TRACE, prefix + "AUTHENTICATION_FAILED[_realm]\thost=[_hostname:9200], principal=[_principal], URI=[_uri], request=[" + expectedMessage + "]");
|
||||
assertMsg(logger, Level.TRACE, prefix + "[rest] [authentication_failed]\trealm=[_realm], origin_address=[_hostname:9200], principal=[_principal], uri=[_uri], request_body=[" + expectedMessage + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +276,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.accessGranted(new User.Simple("_username", "r1"), "_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
|
@ -277,17 +285,17 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
break;
|
||||
case INFO:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.INFO, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[_action], indices=[idx1,idx2]");
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[_action], indices=[idx1,idx2]");
|
||||
} else {
|
||||
assertMsg(logger, Level.INFO, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[_action]");
|
||||
assertMsg(logger, Level.INFO, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[_action]");
|
||||
}
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +307,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.accessGranted(new User.Simple("_username", "r1"), "internal:_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
|
@ -309,9 +318,9 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
break;
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.TRACE, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[internal:_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[internal:_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.TRACE, prefix + "ACCESS_GRANTED\thost=[local[_host]], principal=[_username], action=[internal:_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[_username], action=[internal:_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,23 +332,24 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
CapturingLogger logger = new CapturingLogger(level);
|
||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, logger);
|
||||
TransportMessage message = randomBoolean() ? new MockMessage() : new MockIndicesRequest();
|
||||
String origins = LoggingAuditTrail.originAttributes(message);
|
||||
auditTrail.accessDenied(new User.Simple("_username", "r1"), "_action", message);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
case WARN:
|
||||
case INFO:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.ERROR, prefix + "ACCESS_DENIED\thost=[local[_host]], principal=[_username], action=[_action], indices=[idx1,idx2]");
|
||||
assertMsg(logger, Level.ERROR, prefix + "[transport] [access_denied]\t" + origins + ", principal=[_username], action=[_action], indices=[idx1,idx2]");
|
||||
} else {
|
||||
assertMsg(logger, Level.ERROR, prefix + "ACCESS_DENIED\thost=[local[_host]], principal=[_username], action=[_action]");
|
||||
assertMsg(logger, Level.ERROR, prefix + "[transport] [access_denied]\t" + origins + ", principal=[_username], action=[_action]");
|
||||
}
|
||||
break;
|
||||
case DEBUG:
|
||||
case TRACE:
|
||||
if (message instanceof IndicesRequest) {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ACCESS_DENIED\thost=[local[_host]], principal=[_username], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_denied]\t" + origins + ", principal=[_username], action=[_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
|
||||
} else {
|
||||
assertMsg(logger, Level.DEBUG, prefix + "ACCESS_DENIED\thost=[local[_host]], principal=[_username], action=[_action], request=[MockMessage]");
|
||||
assertMsg(logger, Level.DEBUG, prefix + "[transport] [access_denied]\t" + origins + ", principal=[_username], action=[_action], request=[MockMessage]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +365,7 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
auditTrail.connectionDenied(inetAddress, "default", rule);
|
||||
switch (level) {
|
||||
case ERROR:
|
||||
assertMsg(logger, Level.ERROR, String.format(Locale.ROOT, prefix + "CONNECTION_DENIED\thost=[%s], profile=[%s], rule=[deny %s]",
|
||||
assertMsg(logger, Level.ERROR, String.format(Locale.ROOT, prefix + "[ip_filter] [connection_denied]\torigin_address=[%s], transport_profile=[%s], rule=[deny %s]",
|
||||
inetAddress.getHostAddress(), "default", "_all"));
|
||||
break;
|
||||
case WARN:
|
||||
|
@ -383,12 +393,34 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
break;
|
||||
case TRACE:
|
||||
assertMsg(logger, Level.TRACE, String.format(Locale.ROOT,
|
||||
prefix + "CONNECTION_GRANTED\thost=[%s], profile=[default], rule=[allow default:accept_all]",
|
||||
prefix + "[ip_filter] [connection_granted]\torigin_address=[%s], transport_profile=[default], rule=[allow default:accept_all]",
|
||||
inetAddress.getHostAddress()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test @Repeat(iterations = 10)
|
||||
public void testOriginAttributes() throws Exception {
|
||||
MockMessage message = new MockMessage();
|
||||
String text = LoggingAuditTrail.originAttributes(message);
|
||||
InetSocketAddress restAddress = RemoteHostHeader.restRemoteAddress(message);
|
||||
if (restAddress != null) {
|
||||
assertThat(text, equalTo("origin_type=[rest], origin_address=[" + restAddress + "]"));
|
||||
return;
|
||||
}
|
||||
TransportAddress address = message.remoteAddress();
|
||||
if (address == null) {
|
||||
assertThat(text, equalTo("origin_type=[local_node], origin_address=[" + NetworkUtils.getLocalHostAddress("_local") + "]"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (address instanceof InetSocketTransportAddress) {
|
||||
assertThat(text, equalTo("origin_type=[transport], origin_address=[" + ((InetSocketTransportAddress) address).address() + "]"));
|
||||
} else {
|
||||
assertThat(text, equalTo("origin_type=[transport], origin_address=[" + address + "]"));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertMsg(CapturingLogger logger, Level msgLevel, String msg) {
|
||||
List<CapturingLogger.Msg> output = logger.output(msgLevel);
|
||||
assertThat(output.size(), is(1));
|
||||
|
@ -411,14 +443,28 @@ public class LoggingAuditTrailTests extends ElasticsearchTestCase {
|
|||
private static class MockMessage extends TransportMessage<MockMessage> {
|
||||
|
||||
private MockMessage() {
|
||||
remoteAddress(new LocalTransportAddress("_host"));
|
||||
if (randomBoolean()) {
|
||||
if (randomBoolean()) {
|
||||
remoteAddress(new LocalTransportAddress("local_host"));
|
||||
} else {
|
||||
remoteAddress(new InetSocketTransportAddress("remote_host", 1234));
|
||||
}
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
RemoteHostHeader.putRestRemoteAddress(this, InetSocketAddress.createUnresolved("localhost", 1234));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MockIndicesRequest extends TransportMessage<MockIndicesRequest> implements IndicesRequest {
|
||||
|
||||
private MockIndicesRequest() {
|
||||
remoteAddress(new LocalTransportAddress("_host"));
|
||||
if (randomBoolean()) {
|
||||
remoteAddress(new LocalTransportAddress("_host"));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
RemoteHostHeader.putRestRemoteAddress(this, InetSocketAddress.createUnresolved("localhost", 1234));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue