blob: 885609ca9a47794d18201db4841306f2e2680f89 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Apache Cassandra | Apache Cassandra Documentation</title>
<link rel="stylesheet" href="../../assets/css/site.css">
<meta name="description" content="The Apache Cassandra Community">
<link rel="schema.dcterms" href="https://purl.org/dc/terms/">
<meta name="dcterms.subject" content="_">
<meta name="dcterms.identifier" content="master">
<meta name="generator" content="Antora 2.3.4">
<link rel="icon" href="../../assets/img/favicon.ico" type="image/x-icon">
<script>
const script = document.createElement("script");
const domain = window.location.hostname;
script.type = "text/javascript";
script.src = "https://plausible.cassandra.apache.org/js/plausible.js";
script.setAttribute("data-domain",domain);
script.setAttribute("defer",'true');
script.setAttribute("async",'true');
document.getElementsByTagName("head")[0].appendChild(script);
</script> </head>
<body class="single-post">
<div class="container mx-auto relative">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<meta property="og:type" content="website" />
<meta property="og:description" content="" />
<meta property="og:url" content="/" />
<meta property="og:site_name" content="Apache Cassandra" />
<header id="top-nav">
<div class="inner relative">
<div class="header-social-icons text-right">
<a href="https://twitter.com/cassandra?lang=en" target="_blank" styles="margin-left: 20px;"><img src="../../assets/img/twitter-icon-circle-white.svg" alt="twitter icon" width="24"></a>
<a href="https://www.linkedin.com/company/apache-cassandra/" target="_blank" styles="margin-left: 20px;"><img src="../../assets/img/LI-In-Bug.png" alt="linked-in icon" width="24"></a>
<a href="https://www.youtube.com/c/PlanetCassandra" target="_blank" styles="margin-left: 20px;"><img src="../../assets/img/youtube-icon.png" alt="youtube icon" width="24"></a>
</div>
<div class="cf">
<div class="logo left"><a href="/"><img src="../../assets/img/logo-white-r.png" alt="cassandra logo"></a></div>
<div class="mobile-nav-icon right">
<img class="toggle-icon" src="../../assets/img/hamburger-nav.svg">
</div>
<ul class="main-nav nav-links right flex flex-vert-center flex-space-between">
<li>
<a class="nav-link hide-mobile">Get Started</a>
<ul class="sub-menu bg-white">
<li class="pa-micro">
<a href="/_/cassandra-basics.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-basics.png" alt="cassandra basics icon">
</div>
<div class="sub-nav-text teal py-small">
Cassandra Basics
</div>
</a>
</li>
<li class="pa-micro">
<a href="/_/quickstart.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-rocket.png" alt="cassandra basics icon">
</div>
<div class="sub-nav-text teal py-small">
Quickstart
</div>
</a>
</li>
<li class="pa-micro">
<a href="/_/ecosystem.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-ecosystem.png" alt="cassandra basics icon">
</div>
<div class="sub-nav-text teal py-small">
Ecosystem
</div>
</a>
</li>
</ul>
</li>
<li><a class="nav-link" href="/doc/latest/">Documentation</a></li>
<li>
<a class="nav-link" href="/_/community.html">Community</a>
<ul class="sub-menu bg-white">
<li class="pa-micro">
<a href="/_/community.html#code-of-conduct">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-welcome.png" alt="welcome icon">
</div>
<div class="sub-nav-text teal py-small">
Welcome
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/community.html#discussions">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-discussions.png" alt="discussions icon">
</div>
<div class="sub-nav-text teal py-small">
Discussions
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/community.html#project-governance">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-governance.png" alt="Governance icon">
</div>
<div class="sub-nav-text teal py-small">
Governance
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/community.html#how-to-contribute">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-contribute.png" alt="Contribute icon">
</div>
<div class="sub-nav-text teal py-small">
Contribute
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/community.html#meet-the-community">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-community.png" alt="Meet the Community icon">
</div>
<div class="sub-nav-text teal py-small">
Meet the Community
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/cassandra-catalyst-program.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-catalyst.png" alt="Catalyst icon">
</div>
<div class="sub-nav-text teal py-small">
Catalyst Program
</div>
</a>
</li>
<li class="pa-micro hide-mobile">
<a href="/_/events.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-events.png" alt="Events icon">
</div>
<div class="sub-nav-text teal py-small">
Events
</div>
</a>
</li>
</ul>
</li>
<li>
<a class="nav-link hide-mobile">Learn</a>
<ul class="sub-menu bg-white">
<li class="pa-micro">
<a href="/_/Apache-Cassandra-5.0-Moving-Toward-an-AI-Driven-Future.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-basics.png" alt="Basics icon">
</div>
<div class="sub-nav-text teal py-small">
Cassandra 5.0
</div>
</a>
</li>
<li class="pa-micro">
<a href="/_/case-studies.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-case-study.png" alt="Case Studies icon">
</div>
<div class="sub-nav-text teal py-small">
Case Studies
</div>
</a>
</li>
<li class="pa-micro">
<a href="/_/resources.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-resources.png" alt="Resources icon">
</div>
<div class="sub-nav-text teal py-small">
Resources
</div>
</a>
</li>
<li class="pa-micro">
<a href="/_/blog.html">
<div class="sub-nav-icon">
<img src="../../assets/img/sub-menu-blog.png" alt="Blog icon">
</div>
<div class="sub-nav-text teal py-small">
Blog
</div>
</a>
</li>
</ul>
</li>
<li><a class="nav-link btn btn--filled" href="/_/download.html">Download Now</a></li>
</ul>
</div>
</div>
</header>
<div class="hero hero--home grad">
<div class="eye"></div>
<div id="home-content" class="text-center flex flex-center flex-column relative z2 ma-xlarge">
<h1>Tightening security for Apache Cassandra: Part 2</h1>
<h3>February, 7 2022 | Maulin Vasavada</h3>
</div>
</div>
<div id="blog-post" class="flex-center py-large arrow">
<div class="blog-breadcrumb mb-medium">
<div class="inner inner--narrow">
<a href="/_/blog.html">« Back to the Apache Cassandra Blog</a>
</div>
</div>
<div class="post-content">
<div class="inner inner--narrow">
<div id="preamble">
<div class="sectionbody">
<div class="imageblock">
<div class="content">
<img src="../_images/blog/tightening-security-p2-unsplash-paradoxxxx.jpg" alt="blurred arrows of light on a highway">
</div>
</div>
<div class="paragraph">
<p>Image credit: Photo by <a href="https://unsplash.com/@paradoxxxx" target="_blank" rel="noopener">躺着的诗人 on Unsplash</a></p>
</div>
<div class="paragraph">
<p>In <a href="Tightening-Security-for-Apache-Cassandra-Part-1.html" class="page">Part 1</a>, we discussed how the growth in e-commerce transactions globally has required more secure software and one avenue to pursue securing data in transit is TLS/mTLS. This time we will discuss the challenges of TLS/mTLS, how it&#8217;s configured, and what Apache Cassandra offered before the latest release, version 4.0.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="challenges-involved-in-tlsmtls"><a class="anchor" href="#challenges-involved-in-tlsmtls"></a>Challenges involved in TLS/mTLS</h3>
<div class="paragraph">
<p>We need to consider several operational challenges when using TLS/mTLS. As a note, we will refer to private/public keys, certificates, and passwords as ‘security credentials’ in the remainder of the article.</p>
</div>
<div class="sect3">
<h4 id="storing-private-key-and-password"><a class="anchor" href="#storing-private-key-and-password"></a>Storing private key and password</h4>
<div class="paragraph">
<p>In the same way you need to consider keeping the key safe to your bank deposit box, storing long-lived security credentials on the filesystem poses significant risks. The implications of compromised or lost credentials are severe, although you can use filesystem permissions to buy yourself time to apply a better solution. As key distribution is a challenging problem, Apache Cassandra assumes that you already have a secure way to distribute those credentials to your Cassandra machines.</p>
</div>
</div>
<div class="sect3">
<h4 id="credential-rotations"><a class="anchor" href="#credential-rotations"></a>Credential rotations</h4>
<div class="paragraph">
<p>Even if you keep credentials safe, the best practice in the industry is to rotate them periodically. This is particularly important in the case of mTLS as you will want to introduce new trusted clients or remove old ones. Additionally, the security landscape and its standards keep evolving; and find that you will have better algorithms and standards today than a few months or years ago. To take advantage of improvements and deal with client housekeeping, you will need to generate new keys/certificates. Therefore, a robust solution requires a secure and operator-friendly way to distribute updates to the security credentials across machines.</p>
</div>
</div>
<div class="sect3">
<h4 id="operations-at-scale"><a class="anchor" href="#operations-at-scale"></a>Operations at scale</h4>
<div class="paragraph">
<p>Operators who maintain and manage large distributed system deployments know the importance of easy operations and automation. It’s essential for guaranteeing faster turn-around times while ensuring security is not compromised. You may have thousands of computers (thousands of servers and possibly 10x clients for mTLS) when you operate at scale. The challenge is distributing and maintaining the security credentials on each computer without it quickly becoming an operational nightmare and creating a higher risk to the system’s security. The challenge is to rotate the older keys/certificates smoothly and reliably across thousands of VMs, with zero to minimal downtime, with possible tighter compliance deadlines to meet.</p>
</div>
</div>
<div class="sect3">
<h4 id="context-specific-security-constraints"><a class="anchor" href="#context-specific-security-constraints"></a>Context specific security constraints</h4>
<div class="paragraph">
<p>On top of all these challenges, you may have to work within context-specific security constraints that require you to pull the security credentials in a customized format or mechanism.</p>
</div>
<div class="paragraph">
<p>Let’s see how Apache Cassandra (pre-4.0) overcomes the above challenges for configuring TLS/mTLS on the server-side.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="tls-support-before-apache-cassandra-4-0"><a class="anchor" href="#tls-support-before-apache-cassandra-4-0"></a>TLS support before Apache Cassandra 4.0</h3>
<div class="paragraph">
<p>Since Apache Cassandra is written in Java, it uses the <a href="https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html" target="_blank" rel="noopener">notion of ‘keystore’</a> to store asymmetric key-pair and ‘truststore’ for storing ‘trusted certificate entries,’ which are optionally required to trust the caller end of the connection. Cassandra also enables hot-reloading of those security credentials based on the filesystem&#8217;s <code>last-updated</code> timestamp. Apache Cassandra achieves this by periodically querying the filesystem without restarting the server. Of course, the new security credentials are only applicable for newly established SSL connections.</p>
</div>
<div class="sect3">
<h4 id="tls-configuration"><a class="anchor" href="#tls-configuration"></a>TLS configuration</h4>
<div class="paragraph">
<p>In the <code>cassandra.yaml</code> file on the server, you must specify the <code>keystore</code> and <code>keystore_password</code> configurations. The <code>keystore</code> configuration refers to the file path for the keystore relative to the location the server is going to run from. This configuration supports the standard <a href="https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#keystore-types" target="_blank" rel="noopener">keystore types supported by Java</a>. <code>keystore_password</code> refers to the password for the keystore in plain text.</p>
</div>
<div class="paragraph">
<p>For the TLS between the client application and the Cassandra server, you must specify these configurations under <code>client_encryption_options</code>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-asciidoc hljs" data-lang="asciidoc">client_encryption_options:
keystore: conf/.keystore
keystore_password: cassandra</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the TLS between Cassandra server nodes (e.g., for data replication), you must specify these configurations under <code>server_encryption_options</code>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-asciidoc hljs" data-lang="asciidoc">server_encryption_options:
keystore: conf/.keystore
keystore_password: cassandra</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="mtls-configuration"><a class="anchor" href="#mtls-configuration"></a>mTLS configuration</h4>
<div class="paragraph">
<p>Besides the ‘keystore’ configuration, you need to add a ‘truststore’ configuration to store trusted certificates coming from either the client application or the other Cassandra server nodes to the Cassandra server. You can do this by specifying <code>truststore</code> and <code>truststore_password</code> configurations in the <code>cassandra.yaml</code> file on the server. The ‘<code>truststore</code>’ configuration refers to the file path for the truststore, relative to the location where the server will run from. It supports the standard truststore types supported by Java. ‘<code>truststore_password</code>’ refers to the password for the truststore in plain text.</p>
</div>
<div class="paragraph">
<p>For the mTLS between the client application and the Cassandra server, you must specify these configurations under <code>client_encryption_options</code>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-asciidoc hljs" data-lang="asciidoc">client_encryption_options:
keystore: conf/.keystore
keystore_password: cassandra
truststore: conf/.truststore
truststore_password: cassandra</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the mTLS between Cassandra server nodes (again, for example, data replication), you must specify these configurations under <code>server_encryption_options</code>.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-asciidoc hljs" data-lang="asciidoc">server_encryption_options:
keystore: conf/.keystore
keystore_password: cassandra
truststore: conf/.truststore
truststore_password: cassandra</code></pre>
</div>
</div>
<div class="paragraph">
<p>As you will have noticed, we must have keystore and truststore files on the filesystem to use TLS/mTLS. While this configuration enables us to secure traffic between the client application and Cassandra server and inter-server traffic, it doesn’t address all the challenges of using TLS/mTLS. In the final article of the series, we tackle those problems head-on and discuss how Apache Cassandra 4.0+ solves them.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="want-to-learn-more-about-apache-cassandras-security-features"><a class="anchor" href="#want-to-learn-more-about-apache-cassandras-security-features"></a>Want to learn more about Apache Cassandra’s security features?</h3>
<div class="paragraph">
<p>Head to our <a href="/doc/latest/cassandra/operating/security.html">Security documentation</a> section for more details.</p>
</div>
</div>
</div>
</div>
</div>
<footer class="grad grad--two flex-center pb-xlarge">
<div class="inner text-center z2 relative">
<h2 class="white py-small">Get started with Cassandra, fast.</h2>
<a id="footer-cta" href="/_/quickstart.html" class="btn btn--filled ma-medium">Quickstart Guide</a>
</div>
<div class="inner flex flex-distribute-items mt-xlarge z2 relative">
<div class="col-2">
<div id="footer-logo" class="logo logo--footer mb-medium"><img src="../../assets/img/logo-white-r.png" alt="Cassandra Logo"></div>
<p>Apache Cassandra<img src="../../assets/img/registered.svg" alt="®" style="width:18px;"> powers mission-critical deployments with improved performance and unparalleled levels of scale in the cloud.</p>
<div class="footer-social-icons">
<a href="https://twitter.com/cassandra?lang=en" target="_blank"><img src="../../assets/img/twitter-icon-circle-white.svg" alt="twitter icon" width="24"></a>
<a href="https://www.linkedin.com/company/apache-cassandra/" target="_blank"><img src="../../assets/img/LI-In-Bug.png" alt="linked-in icon" width="24"></a>
<a href="https://www.youtube.com/c/PlanetCassandra" target="_blank"><img src="../../assets/img/youtube-icon.png" alt="youtube icon" width="24"></a>
</div>
</div>
<div class="col-2 flex flex-center">
<ul class="columns-2">
<li class="mb-small"><a href="/">Home</a></li>
<li class="mb-small"><a href="/_/cassandra-basics.html">Cassandra Basics</a></li>
<li class="mb-small"><a href="/_/quickstart.html">Quickstart</a></li>
<li class="mb-small"><a href="/_/ecosystem.html">Ecosystem</a></li>
<li class="mb-small"><a href="/doc/latest/">Documentation</a></li>
<li class="mb-small"><a href="/_/community.html">Community</a></li>
<li class="mb-small"><a href="/_/case-studies.html">Case Studies</a></li>
<li class="mb-small"><a href="/_/resources.html">Resources</a></li>
<li class="mb-small"><a href="/_/blog.html">Blog</a></li>
</ul>
</div>
</div>
</footer>
<div class="lower-footer bg-white pa-medium">
<div class="flex flex-row flex-vert-center">
<div class="pr-medium"><img src="../../assets/img//feather-small.png" alt="ASF" width="20"></div>
<div class="pr-medium"><a href="http://www.apache.org/" target="_blank">Foundation</a></div>
<div class="pr-medium"><a href="https://www.apache.org/events/current-event.html" target="_blank">Events</a></div>
<div class="pr-medium"><a href="https://www.apache.org/licenses/" target="_blank">License</a></div>
<div class="pr-medium"><a href="https://www.apache.org/foundation/thanks" target="_blank">Thanks</a></div>
<div class="pr-medium"><a href="https://www.apache.org/security" target="_blank">Security</a></div>
<div class="pr-medium"><a href="https://privacy.apache.org/policies/privacy-policy-public.html" target="_blank">Privacy</a></div>
<div class="pr-medium"><a href="https://www.apache.org/foundation/sponsorship" target="_blank">Sponsorship</a></div>
</div>
<p class="my-medium">© 2009-<script>document.write(new Date().getFullYear())</script> <a href="https://apache.org" target="_blank">The Apache Software Foundation</a> under the terms of the Apache License 2.0. Apache, the Apache feather logo, Apache Cassandra, Cassandra, and the Cassandra logo, are either registered trademarks or trademarks of The Apache Software Foundation.</p>
</div>
<div id="fade" class="hidden"></div>
<div id="modal" class="hidden">
<div id="close-modal" class="cursor-pointer"><svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></div>
<div id="mod-content" class="vid-mod-content resp-container"></div>
</div>
<script>
jQuery(function(){
var windowW = $(window).width();
$(document)
.on('click','.mobile-nav-icon',function(){
$('.main-nav').fadeIn();
})
.on('click','.main-nav',function(){
if(windowW <= 1000){
$(this).fadeOut();
}
})
.on('click','#version-toggle',function(){
$(this).toggleClass('active');
$(this).next().fadeToggle();
})
.on('click','#mobile-docs-nav-burger', function(){
$(this).toggleClass('active');
$('.docs-nav').toggleClass('active');
});
var url = window.location.pathname;
var isQuickstart = url.includes('quickstart.html');
if(isQuickstart){
var footerCTA = document.getElementById('footer-cta');
footerCTA.innerHTML = 'Get latest updates';
footerCTA.setAttribute('href', '/_/blog.html');
}
});
</script>
</div>
</body>
<script>
jQuery(function(){
});
</script>
</html>