|
@@ -9,6 +9,7 @@ import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.apache.logging.log4j.message.ParameterizedMessage;
|
|
import org.apache.logging.log4j.message.ParameterizedMessage;
|
|
import org.elasticsearch.Version;
|
|
import org.elasticsearch.Version;
|
|
|
|
+import org.elasticsearch.cluster.node.DiscoveryNode;
|
|
import org.elasticsearch.common.Nullable;
|
|
import org.elasticsearch.common.Nullable;
|
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
|
import org.elasticsearch.common.network.CloseableChannel;
|
|
import org.elasticsearch.common.network.CloseableChannel;
|
|
@@ -19,12 +20,14 @@ import org.elasticsearch.common.util.BigArrays;
|
|
import org.elasticsearch.common.util.PageCacheRecycler;
|
|
import org.elasticsearch.common.util.PageCacheRecycler;
|
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
|
import org.elasticsearch.nio.BytesChannelContext;
|
|
import org.elasticsearch.nio.BytesChannelContext;
|
|
|
|
+import org.elasticsearch.nio.ChannelFactory;
|
|
import org.elasticsearch.nio.InboundChannelBuffer;
|
|
import org.elasticsearch.nio.InboundChannelBuffer;
|
|
import org.elasticsearch.nio.NioSelector;
|
|
import org.elasticsearch.nio.NioSelector;
|
|
import org.elasticsearch.nio.NioSocketChannel;
|
|
import org.elasticsearch.nio.NioSocketChannel;
|
|
import org.elasticsearch.nio.ServerChannelContext;
|
|
import org.elasticsearch.nio.ServerChannelContext;
|
|
import org.elasticsearch.nio.SocketChannelContext;
|
|
import org.elasticsearch.nio.SocketChannelContext;
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
|
|
+import org.elasticsearch.transport.ConnectTransportException;
|
|
import org.elasticsearch.transport.TcpChannel;
|
|
import org.elasticsearch.transport.TcpChannel;
|
|
import org.elasticsearch.transport.TcpTransport;
|
|
import org.elasticsearch.transport.TcpTransport;
|
|
import org.elasticsearch.transport.nio.NioTcpChannel;
|
|
import org.elasticsearch.transport.nio.NioTcpChannel;
|
|
@@ -38,7 +41,9 @@ import org.elasticsearch.xpack.core.ssl.SSLConfiguration;
|
|
import org.elasticsearch.xpack.core.ssl.SSLService;
|
|
import org.elasticsearch.xpack.core.ssl.SSLService;
|
|
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
|
import org.elasticsearch.xpack.security.transport.filter.IPFilter;
|
|
|
|
|
|
|
|
+import javax.net.ssl.SNIHostName;
|
|
import javax.net.ssl.SSLEngine;
|
|
import javax.net.ssl.SSLEngine;
|
|
|
|
+import javax.net.ssl.SSLParameters;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.InetSocketAddress;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteBuffer;
|
|
@@ -47,6 +52,7 @@ import java.nio.channels.SocketChannel;
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Consumer;
|
|
|
|
+import java.util.function.Function;
|
|
import java.util.function.Supplier;
|
|
import java.util.function.Supplier;
|
|
|
|
|
|
import static org.elasticsearch.xpack.core.security.SecurityField.setting;
|
|
import static org.elasticsearch.xpack.core.security.SecurityField.setting;
|
|
@@ -128,8 +134,29 @@ public class SecurityNioTransport extends NioTransport {
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- protected TcpChannelFactory channelFactory(ProfileSettings profileSettings, boolean isClient) {
|
|
|
|
- return new SecurityTcpChannelFactory(profileSettings, isClient);
|
|
|
|
|
|
+ protected TcpChannelFactory serverChannelFactory(ProfileSettings profileSettings) {
|
|
|
|
+ return new SecurityTcpChannelFactory(profileSettings, false);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected Function<DiscoveryNode, TcpChannelFactory> clientChannelFactoryFunction(ProfileSettings profileSettings) {
|
|
|
|
+ return (node) -> {
|
|
|
|
+ final ChannelFactory.RawChannelFactory rawChannelFactory = new ChannelFactory.RawChannelFactory(profileSettings.tcpNoDelay,
|
|
|
|
+ profileSettings.tcpKeepAlive, profileSettings.reuseAddress, Math.toIntExact(profileSettings.sendBufferSize.getBytes()),
|
|
|
|
+ Math.toIntExact(profileSettings.receiveBufferSize.getBytes()));
|
|
|
|
+ SNIHostName serverName;
|
|
|
|
+ String configuredServerName = node.getAttributes().get("server_name");
|
|
|
|
+ if (configuredServerName != null) {
|
|
|
|
+ try {
|
|
|
|
+ serverName = new SNIHostName(configuredServerName);
|
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
|
+ throw new ConnectTransportException(node, "invalid DiscoveryNode server_name [" + configuredServerName + "]", e);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ serverName = null;
|
|
|
|
+ }
|
|
|
|
+ return new SecurityClientTcpChannelFactory(rawChannelFactory, serverName);
|
|
|
|
+ };
|
|
}
|
|
}
|
|
|
|
|
|
private class SecurityTcpChannelFactory extends TcpChannelFactory {
|
|
private class SecurityTcpChannelFactory extends TcpChannelFactory {
|
|
@@ -139,12 +166,16 @@ public class SecurityNioTransport extends NioTransport {
|
|
private final NioIPFilter ipFilter;
|
|
private final NioIPFilter ipFilter;
|
|
|
|
|
|
private SecurityTcpChannelFactory(ProfileSettings profileSettings, boolean isClient) {
|
|
private SecurityTcpChannelFactory(ProfileSettings profileSettings, boolean isClient) {
|
|
- super(new RawChannelFactory(profileSettings.tcpNoDelay,
|
|
|
|
|
|
+ this(new RawChannelFactory(profileSettings.tcpNoDelay,
|
|
profileSettings.tcpKeepAlive,
|
|
profileSettings.tcpKeepAlive,
|
|
profileSettings.reuseAddress,
|
|
profileSettings.reuseAddress,
|
|
Math.toIntExact(profileSettings.sendBufferSize.getBytes()),
|
|
Math.toIntExact(profileSettings.sendBufferSize.getBytes()),
|
|
- Math.toIntExact(profileSettings.receiveBufferSize.getBytes())));
|
|
|
|
- this.profileName = profileSettings.profileName;
|
|
|
|
|
|
+ Math.toIntExact(profileSettings.receiveBufferSize.getBytes())), profileSettings.profileName, isClient);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private SecurityTcpChannelFactory(RawChannelFactory rawChannelFactory, String profileName, boolean isClient) {
|
|
|
|
+ super(rawChannelFactory);
|
|
|
|
+ this.profileName = profileName;
|
|
this.isClient = isClient;
|
|
this.isClient = isClient;
|
|
this.ipFilter = new NioIPFilter(authenticator, profileName);
|
|
this.ipFilter = new NioIPFilter(authenticator, profileName);
|
|
}
|
|
}
|
|
@@ -162,18 +193,7 @@ public class SecurityNioTransport extends NioTransport {
|
|
|
|
|
|
SocketChannelContext context;
|
|
SocketChannelContext context;
|
|
if (sslEnabled) {
|
|
if (sslEnabled) {
|
|
- SSLEngine sslEngine;
|
|
|
|
- SSLConfiguration defaultConfig = profileConfiguration.get(TcpTransport.DEFAULT_PROFILE);
|
|
|
|
- SSLConfiguration sslConfig = profileConfiguration.getOrDefault(profileName, defaultConfig);
|
|
|
|
- boolean hostnameVerificationEnabled = sslConfig.verificationMode().isHostnameVerificationEnabled();
|
|
|
|
- if (hostnameVerificationEnabled) {
|
|
|
|
- InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.getRemoteAddress();
|
|
|
|
- // we create the socket based on the name given. don't reverse DNS
|
|
|
|
- sslEngine = sslService.createSSLEngine(sslConfig, inetSocketAddress.getHostString(), inetSocketAddress.getPort());
|
|
|
|
- } else {
|
|
|
|
- sslEngine = sslService.createSSLEngine(sslConfig, null, -1);
|
|
|
|
- }
|
|
|
|
- SSLDriver sslDriver = new SSLDriver(sslEngine, isClient);
|
|
|
|
|
|
+ SSLDriver sslDriver = new SSLDriver(createSSLEngine(channel), isClient);
|
|
context = new SSLChannelContext(nioChannel, selector, exceptionHandler, sslDriver, readWriteHandler, buffer, ipFilter);
|
|
context = new SSLChannelContext(nioChannel, selector, exceptionHandler, sslDriver, readWriteHandler, buffer, ipFilter);
|
|
} else {
|
|
} else {
|
|
context = new BytesChannelContext(nioChannel, selector, exceptionHandler, readWriteHandler, buffer, ipFilter);
|
|
context = new BytesChannelContext(nioChannel, selector, exceptionHandler, readWriteHandler, buffer, ipFilter);
|
|
@@ -192,5 +212,46 @@ public class SecurityNioTransport extends NioTransport {
|
|
nioChannel.setContext(context);
|
|
nioChannel.setContext(context);
|
|
return nioChannel;
|
|
return nioChannel;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException {
|
|
|
|
+ SSLEngine sslEngine;
|
|
|
|
+ SSLConfiguration defaultConfig = profileConfiguration.get(TcpTransport.DEFAULT_PROFILE);
|
|
|
|
+ SSLConfiguration sslConfig = profileConfiguration.getOrDefault(profileName, defaultConfig);
|
|
|
|
+ boolean hostnameVerificationEnabled = sslConfig.verificationMode().isHostnameVerificationEnabled();
|
|
|
|
+ if (hostnameVerificationEnabled) {
|
|
|
|
+ InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.getRemoteAddress();
|
|
|
|
+ // we create the socket based on the name given. don't reverse DNS
|
|
|
|
+ sslEngine = sslService.createSSLEngine(sslConfig, inetSocketAddress.getHostString(), inetSocketAddress.getPort());
|
|
|
|
+ } else {
|
|
|
|
+ sslEngine = sslService.createSSLEngine(sslConfig, null, -1);
|
|
|
|
+ }
|
|
|
|
+ return sslEngine;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private class SecurityClientTcpChannelFactory extends SecurityTcpChannelFactory {
|
|
|
|
+
|
|
|
|
+ private final SNIHostName serverName;
|
|
|
|
+
|
|
|
|
+ private SecurityClientTcpChannelFactory(RawChannelFactory rawChannelFactory, SNIHostName serverName) {
|
|
|
|
+ super(rawChannelFactory, TcpTransport.DEFAULT_PROFILE, true);
|
|
|
|
+ this.serverName = serverName;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public NioTcpServerChannel createServerChannel(NioSelector selector, ServerSocketChannel channel) {
|
|
|
|
+ throw new AssertionError("Cannot create TcpServerChannel with client factory");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException {
|
|
|
|
+ SSLEngine sslEngine = super.createSSLEngine(channel);
|
|
|
|
+ if (serverName != null) {
|
|
|
|
+ SSLParameters sslParameters = sslEngine.getSSLParameters();
|
|
|
|
+ sslParameters.setServerNames(Collections.singletonList(serverName));
|
|
|
|
+ sslEngine.setSSLParameters(sslParameters);
|
|
|
|
+ }
|
|
|
|
+ return sslEngine;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|