Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport issue(#1156) and issue(#1057) to branch opendistro-1.2 #1271

Merged
merged 2 commits into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@

import com.amazon.opendistroforelasticsearch.security.ssl.rest.OpenDistroSecuritySSLReloadCertsAction;
import com.amazon.opendistroforelasticsearch.security.ssl.rest.OpenDistroSecuritySSLCertsInfoAction;
import com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter;
import com.amazon.opendistroforelasticsearch.security.http.OpenDistroSecurityHttpServerTransport;
import com.amazon.opendistroforelasticsearch.security.ssl.OpenDistroSecuritySSLPlugin;
import com.amazon.opendistroforelasticsearch.security.transport.OpenDistroSecurityInterceptor;
import com.amazon.opendistroforelasticsearch.security.setting.OpenDistroDynamicSetting;
import com.amazon.opendistroforelasticsearch.security.setting.TransportPassiveAuthSetting;
import com.amazon.opendistroforelasticsearch.security.ssl.transport.DefaultPrincipalExtractor;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.amazon.opendistroforelasticsearch.security.ssl.transport.OpenDistroSSLConfig;
import org.apache.lucene.search.QueryCachingPolicy;
import org.apache.lucene.search.Weight;
Expand Down Expand Up @@ -188,6 +198,7 @@ public final class OpenDistroSecurityPlugin extends OpenDistroSecuritySSLPlugin
private volatile OpenDistroSecurityFilter odsf;
private volatile ComplianceConfig complianceConfig;
private volatile IndexResolverReplacer irr;
private volatile OpenDistroDynamicSetting<Boolean> transportPassiveAuthSetting;

@Override
public void close() throws IOException {
Expand Down Expand Up @@ -222,6 +233,8 @@ public OpenDistroSecurityPlugin(final Settings settings, final Path configPath)
disabled = isDisabled(settings);
sslCertReloadEnabled = isSslCertReloadEnabled(settings);

transportPassiveAuthSetting = new TransportPassiveAuthSetting(settings);

if (disabled) {
this.dlsFlsAvailable = false;
this.dlsFlsConstructor = null;
Expand Down Expand Up @@ -726,6 +739,10 @@ public Collection<Object> createComponents(Client localClient, ClusterService cl
if (client || disabled) {
return components;
}

//Register opensearch dynamic settings
transportPassiveAuthSetting.registerClusterSettingsChangeListener(clusterService.getClusterSettings());

final ClusterInfoHolder cih = new ClusterInfoHolder();
this.cs.addListener(cih);

Expand Down Expand Up @@ -761,10 +778,8 @@ public Collection<Object> createComponents(Client localClient, ClusterService cl
//cr.subscribeOnLicenseChange(complianceConfig); TODO : Remove this line post compilation
final XFFResolver xffResolver = new XFFResolver(threadPool);
backendRegistry = new BackendRegistry(settings, adminDns, xffResolver, auditLog, threadPool);

final CompatConfig compatConfig = new CompatConfig(environment);


final CompatConfig compatConfig = new CompatConfig(environment, transportPassiveAuthSetting);

evaluator = new PrivilegesEvaluator(clusterService, threadPool, cr, resolver, auditLog,
settings, privilegesInterceptor, cih, irr, advancedModulesEnabled);
Expand All @@ -790,8 +805,9 @@ public Collection<Object> createComponents(Client localClient, ClusterService cl
principalExtractor = ReflectionHelper.instantiatePrincipalExtractor(principalExtractorClass);
}


odsi = new OpenDistroSecurityInterceptor(settings, threadPool, backendRegistry, auditLog, principalExtractor,
interClusterRequestEvaluator, cs, Objects.requireNonNull(sslExceptionHandler), Objects.requireNonNull(cih));
interClusterRequestEvaluator, cs, Objects.requireNonNull(sslExceptionHandler), Objects.requireNonNull(cih), openDistroSSLConfig);
components.add(principalExtractor);


Expand Down Expand Up @@ -955,7 +971,7 @@ public List<Setting<?>> getSettings() {
settings.add(Setting.listSetting(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_IMMUTABLE_INDICES, Collections.emptyList(), Function.identity(), Property.NodeScope)); //not filtered here
settings.add(Setting.simpleString(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_SALT, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(ConfigConstants.OPENDISTRO_SECURITY_COMPLIANCE_HISTORY_INTERNAL_CONFIG_ENABLED, false, Property.NodeScope, Property.Filtered));

settings.add(transportPassiveAuthSetting.getDynamicSetting());
//compat
settings.add(Setting.boolSetting(ConfigConstants.OPENDISTRO_SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY, false, Property.NodeScope, Property.Filtered));
settings.add(Setting.boolSetting(ConfigConstants.OPENDISTRO_SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY, false, Property.NodeScope, Property.Filtered));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

package com.amazon.opendistroforelasticsearch.security.configuration;

import com.amazon.opendistroforelasticsearch.security.setting.OpenDistroDynamicSetting;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -39,15 +40,18 @@
import com.amazon.opendistroforelasticsearch.security.securityconf.DynamicConfigModel;
import com.amazon.opendistroforelasticsearch.security.support.ConfigConstants;


public class CompatConfig {

private final Logger log = LogManager.getLogger(getClass());
private final Settings staticSettings;
private DynamicConfigModel dcm;
private final OpenDistroDynamicSetting<Boolean> transportPassiveAuthSetting;

public CompatConfig(final Environment environment) {
public CompatConfig(final Environment environment, final OpenDistroDynamicSetting<Boolean> transportPassiveAuthSetting) {
super();
this.staticSettings = environment.settings();
this.staticSettings = environment.settings();
this.transportPassiveAuthSetting = transportPassiveAuthSetting;
}

@Subscribe
Expand Down Expand Up @@ -100,4 +104,15 @@ public boolean transportInterClusterAuthEnabled() {
return true;
}
}

/**
* Returns true if passive transport auth is enabled
*/
public boolean transportInterClusterPassiveAuthEnabled() {
final boolean interClusterAuthInitiallyPassive = transportPassiveAuthSetting.getDynamicSettingValue();
if(log.isTraceEnabled()) {
log.trace("{} {}", ConfigConstants.OPENDISTRO_SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY, interClusterAuthInitiallyPassive);
}
return interClusterAuthInitiallyPassive;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ private <Request extends ActionRequest, Response extends ActionResponse> void ap
attachSourceFieldContext(request);
}

final User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
final boolean userIsAdmin = isUserAdmin(user, adminDns);
final boolean interClusterRequest = HeaderHelper.isInterClusterRequest(threadContext);
final boolean trustedClusterRequest = HeaderHelper.isTrustedClusterRequest(threadContext);
Expand Down Expand Up @@ -242,14 +242,20 @@ private <Request extends ActionRequest, Response extends ActionResponse> void ap
return;
}

boolean skipSecurityIfDualMode = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_DUAL_MODE_SKIP_SECURITY) == Boolean.TRUE;
if((interClusterRequest || trustedClusterRequest || request.remoteAddress() == null) && !compatConfig.transportInterClusterAuthEnabled()) {
chain.proceed(task, action, request, listener);
return;
} else if((interClusterRequest || trustedClusterRequest || request.remoteAddress() == null || skipSecurityIfDualMode) && compatConfig.transportInterClusterPassiveAuthEnabled()) {
log.info("Transport auth in passive mode and no user found. Injecting default user");
user = User.DEFAULT_TRANSPORT_USER;
threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_USER, user);
} else {
log.error("No user found for "+ action+" from "+request.remoteAddress()+" "+threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN)+" via "+threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE)+" "+threadContext.getHeaders());
listener.onFailure(new ElasticsearchSecurityException("No user found for "+action, RestStatus.INTERNAL_SERVER_ERROR));
return;
}

log.error("No user found for "+ action+" from "+request.remoteAddress()+" "+threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN)+" via "+threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE)+" "+threadContext.getHeaders());
listener.onFailure(new ElasticsearchSecurityException("No user found for "+action, RestStatus.INTERNAL_SERVER_ERROR));
return;
}

final PrivilegesEvaluator eval = evalp;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amazon.opendistroforelasticsearch.security.setting;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;

/**
* An abstract class to track the state of an opensearch dynamic setting.
* To instantiate for a dynamic setting, pass the Setting and the Setting's fetched value to the constructor
*
* @param <T> The type of the Setting
*/
public abstract class OpenDistroDynamicSetting<T> {
private final Setting<T> dynamicSetting;
private volatile T dynamicSettingValue;

private final Logger logger = LogManager.getLogger(getClass());

public OpenDistroDynamicSetting(Setting<T> dynamicSetting, T dynamicSettingValue) {
this.dynamicSetting = dynamicSetting;
this.dynamicSettingValue = dynamicSettingValue;
}

public void registerClusterSettingsChangeListener(final ClusterSettings clusterSettings) {
clusterSettings.addSettingsUpdateConsumer(dynamicSetting,
dynamicSettingNewValue -> {
logger.info(getClusterChangeMessage(dynamicSettingNewValue));
setDynamicSettingValue(dynamicSettingNewValue);
});
}

protected String getClusterChangeMessage(final T dynamicSettingNewValue) {
return String.format("Detected change in settings, updated cluster setting value is %s", dynamicSettingNewValue);
}

private void setDynamicSettingValue(final T dynamicSettingValue) {
this.dynamicSettingValue = dynamicSettingValue;
}

public T getDynamicSettingValue() {
return dynamicSettingValue;
}

public Setting<T> getDynamicSetting() {
return dynamicSetting;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amazon.opendistroforelasticsearch.security.setting;

import com.amazon.opendistroforelasticsearch.security.support.ConfigConstants;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;

public class TransportPassiveAuthSetting extends OpenDistroDynamicSetting<Boolean> {

private static final String SETTING = ConfigConstants.OPENDISTRO_SECURITY_UNSUPPORTED_PASSIVE_INTERTRANSPORT_AUTH_INITIALLY;

public TransportPassiveAuthSetting(final Settings settings) {
super(getSetting(), getSettingInitialValue(settings));
}

private static Setting<Boolean> getSetting() {
return Setting.boolSetting(
SETTING,
false,
Setting.Property.NodeScope, Setting.Property.Dynamic);
}

private static Boolean getSettingInitialValue(final Settings settings) {
return settings.getAsBoolean(SETTING, false);
}

@Override
protected String getClusterChangeMessage(final Boolean dynamicSettingNewValue) {
return String.format("Detected change in settings, cluster setting for transportPassiveAuth is %s", dynamicSettingNewValue ? "enabled" : "disabled");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public List<TransportInterceptor> getTransportInterceptors(NamedWriteableRegistr
List<TransportInterceptor> interceptors = new ArrayList<TransportInterceptor>(1);

if(transportSSLEnabled && !client) {
interceptors.add(new OpenDistroSecuritySSLTransportInterceptor(settings, null, null, NOOP_SSL_EXCEPTION_HANDLER));
interceptors.add(new OpenDistroSecuritySSLTransportInterceptor(settings, null, null, openDistroSSLConfig, NOOP_SSL_EXCEPTION_HANDLER));
}

return interceptors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ public class OpenDistroSSLConfig {
public OpenDistroSSLConfig(final boolean sslOnly, final boolean dualModeEnabled) {
this.sslOnly = sslOnly;
this.dualModeEnabled = dualModeEnabled;
if (this.dualModeEnabled && !this.sslOnly) {
logger.warn("opendistro_security_config.ssl_dual_mode_enabled is enabled but opendistro_security.ssl_only mode is disabled. "
+ "SSL Dual mode is supported only when security plugin is in ssl_only mode");
}
logger.info("SSL dual mode is {}", isDualModeEnabled() ? "enabled" : "disabled");
}

Expand All @@ -60,8 +56,7 @@ private void setDualModeEnabled(boolean dualModeEnabled) {
}

public boolean isDualModeEnabled() {
// currently dual mode can be enabled only when SSLOnly is enabled. This stance can change in future.
return sslOnly && dualModeEnabled;
return dualModeEnabled;
}

public boolean isSslOnlyMode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import javax.net.ssl.SSLPeerUnverifiedException;

import com.amazon.opendistroforelasticsearch.security.support.ConfigConstants;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.ElasticsearchException;
Expand Down Expand Up @@ -53,22 +54,26 @@ public class OpenDistroSecuritySSLRequestHandler<T extends TransportRequest>
protected final Logger log = LogManager.getLogger(this.getClass());
private final PrincipalExtractor principalExtractor;
private final SslExceptionHandler errorHandler;
private final OpenDistroSSLConfig openDistroSSLConfig;

public OpenDistroSecuritySSLRequestHandler(String action, TransportRequestHandler<T> actualHandler,
ThreadPool threadPool, final PrincipalExtractor principalExtractor, final SslExceptionHandler errorHandler) {

public OpenDistroSecuritySSLRequestHandler(String action, TransportRequestHandler<T> actualHandler,
ThreadPool threadPool, final PrincipalExtractor principalExtractor, final OpenDistroSSLConfig openDistroSSLConfig,
final SslExceptionHandler errorHandler) {
super();
this.action = action;
this.actualHandler = actualHandler;
this.threadPool = threadPool;
this.principalExtractor = principalExtractor;
this.openDistroSSLConfig = openDistroSSLConfig;
this.errorHandler = errorHandler;
}

protected ThreadContext getThreadContext() {
if(threadPool == null) {
return null;
}

return threadPool.getThreadContext();
}

Expand Down Expand Up @@ -105,6 +110,12 @@ public final void messageReceived(T request, TransportChannel channel, Task task
final SslHandler sslhandler = (SslHandler) nettyChannel.getNettyChannel().pipeline().get("ssl_server");

if (sslhandler == null) {
if (openDistroSSLConfig.isDualModeEnabled()) {
log.info("Communication in dual mode. Skipping SSL handler check");
threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_DUAL_MODE_SKIP_SECURITY, Boolean.TRUE);
messageReceivedDecorate(request, actualHandler, channel, task);
return;
}
final String msg = "No ssl handler found (SG 11)";
//log.error(msg);
final Exception exception = new ElasticsearchException(msg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,22 @@ public final class OpenDistroSecuritySSLTransportInterceptor implements Transpor
protected final ThreadPool threadPool;
protected final PrincipalExtractor principalExtractor;
protected final SslExceptionHandler errorHandler;

public OpenDistroSecuritySSLTransportInterceptor(final Settings settings, final ThreadPool threadPool,
PrincipalExtractor principalExtractor, final SslExceptionHandler errorHandler) {
protected final OpenDistroSSLConfig openDistroSSLConfig;

public OpenDistroSecuritySSLTransportInterceptor(final Settings settings, final ThreadPool threadPool,
PrincipalExtractor principalExtractor, final OpenDistroSSLConfig openDistroSSLConfig,
final SslExceptionHandler errorHandler) {
this.threadPool = threadPool;
this.principalExtractor = principalExtractor;
this.errorHandler = errorHandler;
this.openDistroSSLConfig = openDistroSSLConfig;
}

@Override
public <T extends TransportRequest> TransportRequestHandler<T> interceptHandler(String action, String executor, boolean forceExecution,
TransportRequestHandler<T> actualHandler) {
return new OpenDistroSecuritySSLRequestHandler<T>(action, actualHandler, threadPool, principalExtractor, errorHandler);
return new OpenDistroSecuritySSLRequestHandler<>(action, actualHandler, threadPool, principalExtractor, openDistroSSLConfig, errorHandler);

}


Expand Down
Loading