mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-2.1' into cassandra-2.2
This commit is contained in:
commit
734a3bfa78
|
|
@ -5,6 +5,7 @@
|
|||
* Deprecate Pig support (CASSANDRA-10542)
|
||||
* Reduce contention getting instances of CompositeType (CASSANDRA-10433)
|
||||
Merged from 2.1:
|
||||
* Support encrypted and plain traffic on the same port (CASSANDRA-10559)
|
||||
* Do STCS in DTCS windows (CASSANDRA-10276)
|
||||
* Don't try to get ancestors from half-renamed sstables (CASSANDRA-10501)
|
||||
* Avoid repetition of JVM_OPTS in debian package (CASSANDRA-10251)
|
||||
|
|
|
|||
5
NEWS.txt
5
NEWS.txt
|
|
@ -28,6 +28,11 @@ Operations
|
|||
If moving from the SimpleSnitch, make sure the rack containing all current
|
||||
nodes is named "rack1".
|
||||
|
||||
New features
|
||||
------------
|
||||
- Native protocol server now allows both SSL and non-SSL connections on
|
||||
the same port.
|
||||
|
||||
|
||||
2.2.3
|
||||
=====
|
||||
|
|
|
|||
|
|
@ -827,6 +827,8 @@ server_encryption_options:
|
|||
# enable or disable client/server encryption.
|
||||
client_encryption_options:
|
||||
enabled: false
|
||||
# If enabled and optional is set to true encrypted and unencrypted connections are handled.
|
||||
optional: false
|
||||
keystore: conf/.keystore
|
||||
keystore_password: cassandra
|
||||
# require_client_auth: false
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public abstract class EncryptionOptions
|
|||
public static class ClientEncryptionOptions extends EncryptionOptions
|
||||
{
|
||||
public boolean enabled = false;
|
||||
public boolean optional = false;
|
||||
}
|
||||
|
||||
public static class ServerEncryptionOptions extends EncryptionOptions
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import java.net.InetAddress;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
|
@ -34,6 +34,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
|
|
@ -42,6 +43,7 @@ import io.netty.channel.group.ChannelGroup;
|
|||
import io.netty.channel.group.DefaultChannelGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.ssl.SslHandler;
|
||||
import io.netty.util.Version;
|
||||
import io.netty.util.concurrent.EventExecutor;
|
||||
|
|
@ -162,8 +164,16 @@ public class Server implements CassandraDaemon.Server
|
|||
final EncryptionOptions.ClientEncryptionOptions clientEnc = DatabaseDescriptor.getClientEncryptionOptions();
|
||||
if (clientEnc.enabled)
|
||||
{
|
||||
logger.info("Enabling encrypted CQL connections between client and server");
|
||||
bootstrap.childHandler(new SecureInitializer(this, clientEnc));
|
||||
if (clientEnc.optional)
|
||||
{
|
||||
logger.info("Enabling optionally encrypted CQL connections between client and server");
|
||||
bootstrap.childHandler(new OptionalSecureInitializer(this, clientEnc));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("Enabling encrypted CQL connections between client and server");
|
||||
bootstrap.childHandler(new SecureInitializer(this, clientEnc));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -299,12 +309,12 @@ public class Server implements CassandraDaemon.Server
|
|||
}
|
||||
}
|
||||
|
||||
private static class SecureInitializer extends Initializer
|
||||
protected abstract static class AbstractSecureIntializer extends Initializer
|
||||
{
|
||||
private final SSLContext sslContext;
|
||||
private final EncryptionOptions encryptionOptions;
|
||||
|
||||
public SecureInitializer(Server server, EncryptionOptions encryptionOptions)
|
||||
protected AbstractSecureIntializer(Server server, EncryptionOptions encryptionOptions)
|
||||
{
|
||||
super(server);
|
||||
this.encryptionOptions = encryptionOptions;
|
||||
|
|
@ -318,14 +328,65 @@ public class Server implements CassandraDaemon.Server
|
|||
}
|
||||
}
|
||||
|
||||
protected void initChannel(Channel channel) throws Exception
|
||||
{
|
||||
protected final SslHandler createSslHandler() {
|
||||
SSLEngine sslEngine = sslContext.createSSLEngine();
|
||||
sslEngine.setUseClientMode(false);
|
||||
sslEngine.setEnabledCipherSuites(encryptionOptions.cipher_suites);
|
||||
sslEngine.setNeedClientAuth(encryptionOptions.require_client_auth);
|
||||
sslEngine.setEnabledProtocols(SSLFactory.ACCEPTED_PROTOCOLS);
|
||||
SslHandler sslHandler = new SslHandler(sslEngine);
|
||||
return new SslHandler(sslEngine);
|
||||
}
|
||||
}
|
||||
|
||||
private static class OptionalSecureInitializer extends AbstractSecureIntializer
|
||||
{
|
||||
public OptionalSecureInitializer(Server server, EncryptionOptions encryptionOptions)
|
||||
{
|
||||
super(server, encryptionOptions);
|
||||
}
|
||||
|
||||
protected void initChannel(final Channel channel) throws Exception
|
||||
{
|
||||
super.initChannel(channel);
|
||||
channel.pipeline().addFirst("sslDetectionHandler", new ByteToMessageDecoder()
|
||||
{
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception
|
||||
{
|
||||
if (byteBuf.readableBytes() < 5)
|
||||
{
|
||||
// To detect if SSL must be used we need to have at least 5 bytes, so return here and try again
|
||||
// once more bytes a ready.
|
||||
return;
|
||||
}
|
||||
if (SslHandler.isEncrypted(byteBuf))
|
||||
{
|
||||
// Connection uses SSL/TLS, replace the detection handler with a SslHandler and so use
|
||||
// encryption.
|
||||
SslHandler sslHandler = createSslHandler();
|
||||
channelHandlerContext.pipeline().replace(this, "ssl", sslHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Connection use no TLS/SSL encryption, just remove the detection handler and continue without
|
||||
// SslHandler in the pipeline.
|
||||
channelHandlerContext.pipeline().remove(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class SecureInitializer extends AbstractSecureIntializer
|
||||
{
|
||||
public SecureInitializer(Server server, EncryptionOptions encryptionOptions)
|
||||
{
|
||||
super(server, encryptionOptions);
|
||||
}
|
||||
|
||||
protected void initChannel(Channel channel) throws Exception
|
||||
{
|
||||
SslHandler sslHandler = createSslHandler();
|
||||
super.initChannel(channel);
|
||||
channel.pipeline().addFirst("ssl", sslHandler);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue