IDIEP-105
Author
Sponsor
Created

 

Status


DRAFT

Basic requirements

To ensure security, all connections in the context of the cluster should be covered by the ability to configure the SSL, both internal and user interaction interfaces. 

Categories of communication can be splitted to 3 points 

  1. User <-> Cluster (Node)
    1. Rest
  2. User <-> Clients
    1. CLI
    2. Thin Client
  3. Node <-> Node
    1. Network (Messaging, Scalecube)


Any SSL configuration management should be done on Node level. Each node should have separate security config and 

Due to Micronaut limitations we are going to support PKCS12 and JKS keystore. Providing direct paths to SSL certificates is not secure and we DON’T support that.

Design

Connections

REST

The standard implementation of SSL support for REST involves configuring a secure connection on a separate port. Also, we should support the DUAL protocol feature. 


Micronaut provides support for REST SSL setting via micronaut-security framework, this is a part of Micronaut infrastructure. This is a new 3rd party dependency which needs to be added to Apache Ignite 3 (Micronaut Security (micronaut-projects.github.io).


Due to Micronaut limitations we are going to support PKCS12 and JKS keystore. 

To correctly configure SSL in Micronaut, we must provide a security config with all the necessary properties in Micronaut notation. For that we should introduce AI3 rest security configuration and map to Micronaut one.

The follow configuration should be introduced:

"rest": {
    "dualProtocol": false,
    "httpToHttpsRedirection": false,
    "ssl": {
        "enabled": false,
        "port": 10400,
        "portRange": 100,
        "keyStore": {
            "type": "PKCS12",
            "path": "must not be empty",
            "password": "may be empty"
        }
    }
}

Ignite Thin Client and JDBC

Apache Ignite 3 Thin Client implementation based on Netty Framework. 

Netty provides support for configuration security connections, via SSLContextBuilder for server and client sides.

Client

SslContextBuilder sslBuilder = SslContextBuilder
   .forClient()
   .keyManager(getKeyManagerFactory())
   .trustManager(getTrustManagerFactory());


Server

SslContextBuilder builder = SslContextBuilder.forServer(certChainInput, keyInput)
       .ciphers(getCiphers(), getCiphersFilter())
       .sessionTimeout(serverSslConfig.getSessionTimeout())
       .sslProvider(sslProvider)
       .trustManager(trustedCerts.toArray(new X509Certificate[0]))
       .clientAuth(serverSslConfig.getClientAuth());


Netty SSL configuration: https://github.com/devsunny/netty-ssl-example/blob/master/src/main/java/com/asksunny/ssl/SecureSocketSslContextFactory.java

We need to introduce client configuration in AI3 server side and map it to settings for Netty Security Context on Server side. 

The follow configuration should be introduced:

"clientConnector": {
    "ssl": {
        "enabled": false,
        "clientAuth": "none",
        "keyStore": {
            "type": "PKCS12",
            "path": "must not be empty",
            "password": "may be empty"
        },
        "trustStore": {
            "type": "PKCS12",
            "path": "must not be empty",
            "password": "may be empty"
        }
    }
}


If a user has enabled SSL for clientConnector, they have to set corresponding properties in ConnectionProperties as well. 

.NET Client


Follow the existing approach from Ignite 2.x:


Basic usage without client auth looks like

 var cfg = new IgniteClientConfiguration { SslStreamFactory = new() }

C++ Client


TBD.


CLI config

In the CLI we use OkHTTP to communicate with Ignite. To enable SSL we have to create an SSLSocketFactory and pass it to the OkHttpClient builder. 

X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;

try {
  trustManager = trustManagerForCertificates(trustedCertificatesInputStream());
  SSLContext sslContext = SSLContext.getInstance("TLS");
  sslContext.init(null, new TrustManager[] { trustManager }, null);
  sslSocketFactory = sslContext.getSocketFactory();
} catch (GeneralSecurityException e) {
  throw new RuntimeException(e);
}

client = new OkHttpClient.Builder()
    .sslSocketFactory(sslSocketFactory, trustManager)
    .build();


Users can enable SSL on the CLI side via ‘cli config set’ command.

cli.trust-store.type=******
cli.trust-store.path=******
cli.trust-store.password=******


Security configuration of CLI should be stored in a separate config file with special permission settings to protect it from unauthorized read\write operations. This configuration file should match profiles from a common configuration file.

Network

Node network based on Netty also and configuration will be the same as described in Ignite Client part. The only difference will be in the AI3 configuration part.

"network": {
    "ssl": {
        "enabled": false,
        "clientAuth": "none",
        "keyStore": {
            "type": "PKCS12",
            "path": "must not be empty",
            "password": "may be empty"
        },
        "trustStore": {
            "type": "PKCS12",
            "path": "must not be empty",
            "password": "may be empty"
        }
    }
}

SSL client authentication (mTLS support)


In part of each connection type we should support the client authentication feature. It should be configured separately for each connection on the server side.

Two way authentication requires that both server and client have certificates that the other trusts. The client needs to generate a private key, store it in his keystore, and get it signed by somebody that the server's truststore trusts. 

Connections which support it will contain clientAuth property.

clientAuth must be one of "none", "optional", "require"


Tickets

[IGNITE-18575] Basic auth and SSL - ASF JIRA (apache.org)



  • No labels

2 Comments

  1. "clientConnector": { "ssl": { "enabled": false, "clientAuth": "none", "keyStore": { "type": "PKCS12", "path": "must not be empty", "password": "may be empty" }, "trustStore": { "type": "PKCS12", "path": "must not be empty", "password": "may be empty" } }}
    client auth is none but both keystore and trustStore are configured. I think it might be confusing.
  2. Aleksandr Pakhomov Thanks for your comment. So, clientAuth configuration property is show use or not SSL client authentication (mTLS support) and this is doesn't dependent on KeyStore and TrustStore, because they used for basic SSL support