Securing YugabyteDB: Part 3 – CQL Client-to-Server Encryption in Transit

Sanketh Indarapu

In Part 1 and Part 2 of this blog series, we covered securing YugabyteDB through the database’s internal RPC and SQL protocols using the TLS encryption protocol. In this post, we explore how to secure communication between CQL clients and the CQL-compatible YCQL query interface of YugabyteDB, as part of the client-to-server encryption in transit setup.

Encryption in transit is a common requirement for client-to-server communication. More specifically, it’s important for YugabyteDB—a 100% open source, distributed SQL database—to store important user and customer data at an organization.

Securing YugabyteDB: Brief architecture overview

As covered in earlier posts (and shown in the below diagram), YugabyteDB has three primary client-to-server communication protocols:

  1. The internal RPC protocol between masters and tserver processes.
  2. PostgreSQL-compatible YSQL clients talking to the default port 5433 on the tserver hosts.
  3. CQL-compatible YCQL clients talking to the default port 9042 on the tserver hosts.

Securing YugabyteDB: A brief architecture overview.

We’ll demonstrate how to set up client-to-server encryption in transit for the third option.

But there are three different goals organizations can achieve with encryption in transit:

  1. Make it cryptographically impossible to snoop or modify network communications.
  2. Enable the client to identify and verify the server.
  3. Finally, enable the server to identify and verify the client.

Goal 1 is typically a common minimum requirement, while Goal 3 depends on the specific use case. Mutual TLS (or mTLS) happens when achieving both Goal 2 and Goal 3.

Securing YugabyteDB: Encryption in transit for CQL clients

To enable TLS communication for CQL client communication, the command line flags are similar to the ones used for SQL client-to-server encryption.

  • --use_client_to_server_encryption=true
  • --certs_for_client_dir=<path to a directory>, e.g. 
    --certs_for_client_dir=/home/yugabyte/yugabyte-tls-config/
  • --allow_insecure_connections=false

More specifically, the directory pointed to by this flag contains three files in PEM format:

  • ca.crt –  The public certificate of the Certificate Authority (CA) that this YugabyteDB server should trust. This is the CA that will verify other certificates. YugabyteDB does not trust any system CA certificates that might already be present on the host. This single file includes a chain of root and intermediate CA certificates.
  • node.<host-ip-address>.crt – Public server certificate for this host.
  • node.<host-ip-address>.key – Private key for this host’s server certificate.

Once these settings are specified, all CQL client connections to this yb-tserver will use TLS. This achieves Goal 1 above (resilience to snooping).

Verification of server certificates

Achieving Goal 2 (client verifies server cert) depends on the exact CQL client involved. For the standard command line client, ycqlsh, the default SSL mode is to verify the CA certificate specified by the SSL_CERTFILE environment variable signs the server certificate. However, to disable this validation, the environment variable SSL_VALIDATE can be set to false.

$ export SSL_CERTFILE=<path to ca.crt>

$ ./bin/ycqlsh --ssl <server ip/hostname> 9042

But ycqlsh does not verify that the server certificate’s Common Name / Subject Alternate Names contain the server hostname. To perform this strict validation, we can use the underlying Python CQL driver directly instead of through ycqlsh. You can find a snippet of a Python script that performs this validation below.

Verification of server certificates

This check is highly recommended when connecting over unsafe networks like the internet. Yugabyte Cloud supports this verification when connecting over public internet using IP allow lists.

Verification of client certificates

Yugabyte’s CQL implementation does not support the verification of client certificates by the server. To request this feature, please file a Github issue.

Min SSL version

Additionally, organizations may wish to disallow older versions of the TLS protocol. The –ssl_protocols flag can be used to specify an explicit allowlist of TLS protocols for YugabyteDB’s internal RPC communication. In order to specify a minimum TLS version of 1.2, for example, the flag would be set to tls12,tls13. Specific ciphers can be configured by the user of --cipher_list for TLS <= 1.2 and --ciphersuites for TLS >= 1.3.

On the ycqlsh client side, an explicit ssl version can be specified using the SSL_VERSION environment variable (e.g., export SSL_VERSION=TLSv1_2).

Conclusion

Up to now, we’ve explored how securing YugabyteDB helps organizations achieve security goals by supporting different modes of encryption in transit, both in the server-to-server RPC interface and in the client-to-server SQL and CQL interfaces. In the next post, we will present a practical hands-on example of using these encryption in transit flags on a single-node YugabyteDB database.

YugabyteDB Anywhere, a private DBaaS version of YugabyteDB for enterprises, helps companies manage their encryption in transit requirements. More specifically, it does this by supporting custom CAs and CA-signed certificates. It also enables encryption in transit and rotating server and CA certificates seamlessly on managed database clusters.

Finally, build your own YugabyteDB-as-a-service today by signing up for a free 30-day trial to YugabyteDB Anywhere!

Sanketh Indarapu

Related Posts

Explore Distributed SQL and YugabyteDB in Depth

Discover the future of data management.
Learn at Yugabyte University
Get Started
Browse Yugabyte Docs
Explore docs
PostgreSQL For Cloud Native World
Read for Free