Skip to content

Using SSL TLS Encryption (and connecting to Compose.IO)

bchavez edited this page Jun 10, 2019 · 9 revisions

The RethinkDB C# driver is dual-licensed. Using SSL/TLS encryption features of the driver or connecting any part of the RethinkDB C# driver to Compose.IO requires a commercial license. Commercial licenses are sold by Bit Armory Inc and can be purchased at this link:

After a commercial license subscription is purchased, an email containing a unique license key is emailed to the purchaser. As long as the subscription remains active, the legal entity is granted exclusive rights to use SSL/TLS encryption features of the RethinkDB C# driver. Any licensing / subscription issues can be worked out by contacting support@bitarmory.com or bchavez@bitarmory.com.

Documentation for connecting to Compose.IO can be found here.

RethinkDB Server TLS Support

Currently, the Linux binary of the RethinkDB Server is the only distribution of RethinkDB Server that supports TLS encryption. TLS encryption for RethinkDB Server on Windows is still pending.

The RethinkDB C# client driver supports connecting to TLS instances of RethinkDB Server on Linux from both Windows client apps and Linux client apps (via .NET Core).

Linux
RethinkDB Server
with TLS
Windows
RethinkDB Server
with TLS
C# driver with TLS
running on Windows
C# driver with TLS
running on Linux

Manual Server Setup

The following instructions walk through setting up TLS with RethinkDB server on Linux.

Start by following the official documentation on generating a key (key.pem) and matching certificate (cert.pem) here: RethinkDB Docs: Secure your cluster.

Once a key.pem and cert.pem exist, add an extra command line argument --tls-ciphers to rethinkdb that enables TLS cipher compatibility with .NET:

user@test:~/# rethinkdb \
     --driver-tls-key key.pem \
     --driver-tls-cert cert.pem \
     --bind all \
     --tls-ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:AES256-SHA

Enabling Driver SSL/TLS

To create a server TLS encrypted connection in the C# driver, use the .EnableSsl API and the SslContext class when building a new connection as shown below:

var conn = R.Connection()
    .Hostname("my.secure.rethinkdb.server.com")
    .EnableSsl(new SslContext
            {
                ServerCertificateValidationCallback = RemoteServerValidation
            },
        licenseTo: "Brian Chavez",
        licenseKey: "...purchased key..."
    )
    .Connect();

The licenseTo and licenseKey are available in the confirmation email when a commercial license subscription has been purchased here. RemoteServerValidation callback is the next critical step in the connection setup and is discussed below.

Validating the Remote Server

The RemoteServerValidation callback is executed when a TLS connection is about to be established. When the callback is executed, the remote server's certificate is presented in the X509Certificate parameter. Use the X509Certificate parameter to validate the identity of the remote host server. If the RemoteServerValidation callback returns true the connection is established. Returning false (an indication of an invalid identity), the connection is denied and an exception is thrown.

private static bool RemoteServerValidation(
    object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    //Implement your own custom remote server validation here
    //to verify the identity of your server.

    //It might be helpful to cast the certificate to an X509Certificate2
    //Use the extended properties on cert2 to help verify your server.
    var cert2 = (X509Certificate2)certificate;
       

    return true; //Returning true allows the .NET framework to proceed
                 //forward with the connection.
}

If the server's SSL/TLS certificate is self-signed (as with self-generated key.pem/cert.pem or Compose.IO), implementing a RemoteServerValidation callback is required. However, if the key.pem and cert.pem are from a trusted root authority, then handling the RemoteServerValidation callback is optional. When the certificates are from a trusted root authorty the .NET framework will validate the authenticity of the remote server's certificate automatically by examining the certificate chain from its trusted root store.

Connecting to Compose.IO

Connecting to Compose.IO is pretty easy since no manual setup of servers is necessary. Simply configure the driver with the variables from Compose's deployment dashboard as shown below:

var conn = R.Connection()
    .Hostname("compose.host.dblayer.com") //Compose's Hostname
    .Port(15327)                          //Compose's Port Number
    .AuthKey("ac3da82d91adeb...")         //Compose's Authentication Credential
    .EnableSsl(new SslContext
            {
                ServerCertificateValidationCallback = RemoteServerValidation
            },
        licenseTo: "Brian Chavez",
        licenseKey: "...purchased key..."
    )
    .Connect();

The licenseTo and licenseKey are available in the confirmation email when a commercial license subscription has been purchased here. The PEM certificate in Compose's dashboard is not necessary. RemoteServerValidation is the next critical step and discussed above in the previous section. Handling the RemoteServerValidation callback and returning true on a valid connection is required since Compose uses self-signed SSL/TLS certificates.

Using Compose.IO's Dashboard PEM certificate

This section is optional. The PEM certificate provided by Compose.IO can be helpful in manually validating the remote server in the RemoteServerValidation callback. The PEM certificate provided by Compose.IO can be loaded by the .NET framework. First save the Compose.IO's dashboard certificate in a file called compose.crt. Next, load the compose.crt as follows:

private static bool RemoteServerValidation(
    object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    var remoteServer = (X509Certificate2)certificate;
    var composeDashboardPEM = new X509Certificate2("compose.crt");
    
    //Can check the attributes in the compose.pem 
    //and compare them to the remote server's certificate
    //being connecting to.
    
    var isFromSameIssuer = remoteServer.Issuer == composeDashboardPEM.Issuer;

    //and do other checks to validate the remote certificate
    //using compose's PEM certificate

    return true; //If everything looks valid, return true and continue
                 //connecting.
}
Clone this wiki locally