安全性
Cassandra 提供的安全功能有三個主要組成部分
-
用於客戶端和節點間通訊的 TLS/SSL 加密
-
客戶端驗證
-
授權
預設情況下,這些功能會停用,因為 Cassandra 已設定為輕鬆尋找和被叢集的其他成員找到。換句話說,現成的 Cassandra 安裝會為惡意行為者提供大量的攻擊面。啟用使用二進位協定的客戶端驗證不足以保護叢集。能夠存取節點間通訊和 JMX 埠的惡意使用者仍然可以
-
建立節點間訊息將使用者插入驗證架構
-
建立節點間訊息來截斷或刪除架構
-
使用
sstableloader
等工具覆寫system_auth
表格 -
直接附加到叢集以擷取寫入流量
正確設定所有三個安全組成部分應否認這些向量。因此,瞭解 Cassandra 的安全功能對於設定叢集以滿足您的安全需求至關重要。
TLS/SSL 加密
Cassandra 提供客戶端機器與資料庫叢集之間以及叢集內節點之間的安全通訊。啟用加密可確保傳輸中的資料不會受到損害,並安全地傳輸。客戶端到節點和節點到節點加密的選項是分開管理的,並且可以獨立設定。
在兩種情況下,啟用加密時,都會使用受支援協定和加密組的 JVM 預設值。可以使用 cassandra.yaml
中的設定覆寫這些設定,但除非有政策規定某些設定或需要在無法更新 JVM 的情況下停用容易受到攻擊的加密或協定,否則不建議這樣做。
FIPS 相容設定可以在 JVM 層級進行設定,不應涉及變更 cassandra.yaml 中的加密設定。請參閱 Java FIPS 文件 以取得更多詳細資料。
Cassandra 提供使用 Java 為基礎的金鑰資料或完全自訂 SSL 環境的彈性。您可以選擇 Java 支援的任何金鑰庫格式(例如 JKS、PKCS12 等),以及其他標準(例如 PEM)。您甚至可以自訂 SSL 環境建立,以使用雲端原生技術(例如 Kuberenetes Secrets),來儲存金鑰資料或與您的內部金鑰管理系統整合。
如需有關產生 SSL 通訊中使用的 Java 支援金鑰庫所需的關鍵庫和信任儲存檔案的資訊,請參閱 建立金鑰庫的 Java 文件。
如需自訂 SSL 環境建立,您可以實作 ISslContextCreationFactory 介面或適當地延伸其公開子類別之一。然後,您可以將 ssl_context_factory
設定用於 server_encryption_options
或 client_encryption_options
區段。請參閱 ssl-factory 範例 以取得詳細資料。請參閱下方的類別圖表,以了解類別層級。

使用基於 PEM 的金鑰資料
您可以將內建類別 PEMBasedSSLContextFactory
用作基於 PEM 的金鑰資料的 ssl_context_factory
設定。
您可以使用內嵌 PEM 資料或具有所需 PEM 資料的檔案來設定此工廠,如下所示:
-
設定:內嵌定義的 PEM 金鑰/憑證(注意 YAML 中的空格!)
client/server_encryption_options: ssl_context_factory: class_name: org.apache.cassandra.security.PEMBasedSslContextFactory parameters: private_key: | -----BEGIN ENCRYPTED PRIVATE KEY----- OR -----BEGIN PRIVATE KEY----- <your base64 encoded private key> -----END ENCRYPTED PRIVATE KEY----- OR -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- <your base64 encoded certificate chain> -----END CERTIFICATE----- private_key_password: "<your password if the private key is encrypted with a password>" trusted_certificates: | -----BEGIN CERTIFICATE----- <your base64 encoded certificate> -----END CERTIFICATE-----
-
設定:檔案中定義的 PEM 金鑰/憑證
client/server_encryption_options: ssl_context_factory: class_name: org.apache.cassandra.security.PEMBasedSslContextFactory keystore: <file path to the keystore file in the PEM format with the private key and the certificate chain> keystore_password: "<your password if the private key is encrypted with a password>" truststore: <file path to the truststore file in the PEM format>
SSL 憑證熱重新載入
從 Cassandra 4 開始,Cassandra 支援 SSL 憑證熱重新載入。如果在 Cassandra 中啟用 SSL/TLS 支援,而且您使用的是預設的基於檔案的金鑰資料,則節點會定期(每 10 分鐘)輪詢 cassandra.yaml 中指定的信任和金鑰儲存。當檔案更新時,Cassandra 會重新載入它們,並將它們用於後續連線。請注意,信任和金鑰儲存密碼是 yaml 的一部分,因此更新的檔案也應使用相同的密碼。
如果您透過 ssl_context_factory
設定自訂 SSL 設定,Cassandra 會輪詢(在上述相同的定期區間)您的實作,以檢查 SSL 憑證是否需要重新載入。請參閱 ISslContextFactory 文件以取得更多詳細資料。如果您使用 Cassandra 的內建 SSL 環境工廠類別之一(範例:PEMBasedSslContextFactory)搭配基於檔案的金鑰資料,它會支援上述的 SSL 憑證熱重新載入。
也可以使用 nodetool reloadssl
指令觸發憑證熱重新載入。如果您希望 Cassandra 立即注意到已變更的憑證,請使用此指令。
節點間加密
管理節點間加密的設定位於 cassandra.yaml
中的 server_encryption_options
區段。若要啟用節點間加密,請將 internode_encryption
設定從其預設值 none
變更為下列值之一:rack
、dc
或 all
。
用戶端對節點加密
管理用戶端對節點加密的設定位於 cassandra.yaml
中的 client_encryption_options
區段。此處有兩個主要切換開關可啟用加密,分別為 enabled
和 optional
。
-
如果兩個都未設定為
true
,則用戶端連線將完全未加密。 -
如果將
enabled
設定為true
,且將optional
設定為false
,則所有用戶端連線都必須安全。 -
如果將兩個選項都設定為
true
,則使用相同埠支援加密和未加密的連線。使用此組態進行加密的用戶端連線將由伺服器自動偵測並處理。
作為 optional
設定的替代方案,也可以針對安全和非安全的連線設定個別埠,以符合作業需求。若要執行此動作,請將 optional
設定為 false,並在 cassandra.yaml
中使用 native_transport_port_ssl
設定來指定要使用於安全用戶端通訊的埠。
角色
Cassandra 使用資料庫角色(可能代表單一使用者或使用者群組)來進行驗證和權限管理。角色管理是 Cassandra 中的延伸點,可以使用 cassandra.yaml
中的 role_manager
設定來設定。預設設定使用 CassandraRoleManager
,此實作將角色資訊儲存在 system_auth
鍵集的表格中。
另請參閱 角色的 CQL 文件
。
驗證
驗證在 Cassandra 中可插入,並使用 cassandra.yaml
中的 authenticator
設定來設定。Cassandra 附帶兩個選項,包含在預設發行版中。
預設情況下,Cassandra 會設定為 AllowAllAuthenticator
,它不會執行任何驗證檢查,因此不需要任何憑證。它用於完全停用驗證。請注意,驗證是 Cassandra 權限子系統的必要條件,因此如果停用驗證,權限也會有效停用。
預設發行版也包含 PasswordAuthenticator
,它會將加密的憑證儲存在系統表格中。這可以用於啟用簡單的使用者名稱/密碼驗證。
啟用密碼驗證
在叢集上啟用用戶端驗證之前,應先使用預期的憑證預先設定用戶端應用程式。當建立連線時,伺服器只會在啟用驗證後要求提供憑證,因此事先設定用戶端側設定是安全的。相反地,一旦伺服器啟用驗證,任何沒有適當憑證的連線嘗試都會被拒絕,這可能會導致用戶端應用程式的可用性問題。一旦用戶端設定完成並準備好啟用驗證,請按照此程序在叢集上啟用驗證。
在叢集中選擇一個節點來執行初始設定。理想情況下,在設定過程中不應有任何用戶端連線到此節點,因此您可能想從用戶端設定中移除它、在網路層級中封鎖它,或可能為此目的新增一個新的暫時節點到叢集中。在該節點上,執行下列步驟
-
開啟一個
cqlsh
會話,並變更system_auth
鍵集的複製因子。預設情況下,此鍵集使用SimpleReplicationStrategy
和replication_factor
為 1。建議對任何非平凡的部署變更此設定,以確保在節點無法使用時,仍能登入。最佳做法是為每個資料中心設定 3 到 5 的複製因子。
ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': 3, 'DC2': 3};
-
編輯
cassandra.yaml
以變更authenticator
選項,如下所示
authenticator: PasswordAuthenticator
-
重新啟動節點。
-
使用預設超級使用者的憑證開啟一個新的
cqlsh
會話
$ cqlsh -u cassandra -p cassandra
-
在登入期間,預設超級使用者的憑證會以
QUORUM
的一致性層級讀取,而所有其他使用者(包括超級使用者)的憑證會以LOCAL_ONE
讀取。為了效能、可用性以及安全性,操作員應建立另一個超級使用者並停用預設超級使用者。此步驟是選用的,但強烈建議執行。在以預設超級使用者身分登入時,建立另一個超級使用者角色,可將其用於引導後續設定。
# create a new superuser
CREATE ROLE dba WITH SUPERUSER = true AND LOGIN = true AND PASSWORD = 'super';
-
啟動一個新的 cqlsh 會話,這次以 new_superuser 身分登入並停用預設超級使用者。
ALTER ROLE cassandra WITH SUPERUSER = false AND LOGIN = false;
-
最後,使用
CREATE ROLE
陳述設定應用程式使用者的角色和憑證。
在這些步驟的最後,一個節點會被設定為使用密碼驗證。若要將此設定推廣到整個叢集,請對叢集中的每個節點重複步驟 2 和 3。一旦所有節點重新啟動,驗證就會在整個叢集中完全啟用。
請注意,使用 PasswordAuthenticator
也需要使用 CassandraRoleManager
。
另請參閱:setting-credentials-for-internal-authentication
、CREATE ROLE
、ALTER ROLE
、ALTER KEYSPACE
和 GRANT PERMISSION
。
授權
授權在 Cassandra 中是可插入的,並使用 cassandra.yaml
中的 authorizer
設定進行設定。Cassandra 附帶兩個選項,包含在預設發行版中。
預設情況下,Cassandra 設定為 AllowAllAuthorizer
,它不執行任何檢查,因此實際上會授予所有角色所有權限。如果 AllowAllAuthenticator
是設定的驗證器,則必須使用此設定。
預設發行版還包括 CassandraAuthorizer
,它確實實現了完整的權限管理功能,並將其資料儲存在 Cassandra 系統資料表中。
啟用內部授權
權限被建模為白名單,預設假設給定的角色無法存取任何資料庫資源。這意味著一旦在節點上啟用授權,所有要求都將被拒絕,直到授予所需的權限。因此,強烈建議在未處理客戶端要求的節點上執行初始設定。
以下假設已透過 password-authentication
中概述的程序啟用驗證。執行這些步驟以在叢集中啟用內部授權
-
在選定的節點上,編輯
cassandra.yaml
以變更authorizer
選項,如下所示
authorizer: CassandraAuthorizer
-
重新啟動節點。
-
使用具有超級使用者憑證的角色的憑證開啟新的
cqlsh
會話
$ cqlsh -u dba -p super
-
使用 GRANT PERMISSION 陳述式為您的客戶端設定適當的存取權限。在其他節點上,在更新設定並重新啟動節點之前,這不會產生任何影響,因此可以避免中斷客戶端。
GRANT SELECT ON ks.t1 TO db_user;
-
一旦授予所有必要的權限,請對每個節點依序重複步驟 1 和 2。隨著每個節點重新啟動且客戶端重新連線,授予的權限的執行將開始。
快取
啟用驗證和授權會藉由頻繁讀取 system_auth
表格對叢集造成額外負載。此外,這些讀取位於許多用戶端操作的關鍵路徑中,因此可能會嚴重影響服務品質。為了減輕此問題,會將憑證、權限和角色詳細資料等驗證資料快取一段可設定的期間。快取可以從 cassandra.yaml
或使用 JMX 用戶端設定(甚至停用)。JMX 介面也支援各種快取的失效,但透過 JMX 進行的任何變更都不具持久性,且會在重新啟動節點時從 cassandra.yaml
重新讀取。
每個快取有 3 個可設定的選項
- 有效期限
-
控制快取條目的到期時間。在此期間後,條目會失效並從快取中移除。
- 更新頻率
-
控制執行背景讀取的頻率,以擷取基礎資料的任何變更。在執行這些非同步更新時,快取將繼續提供(可能)過期的資料。通常,這會設定為比有效期限短的時間。
- 最大條目數
-
控制快取大小的上限。
這些選項在 cassandra.yaml
中的命名遵循慣例
-
<type>_validity_in_ms
-
<type>_update_interval_in_ms
-
<type>_cache_max_entries
其中 <type>
是 credentials
、permissions
或 roles
之一。
如前所述,這些選項也會透過 org.apache.cassandra.auth
網域下的 mbean 在 JMX 中公開。
JMX 存取
JMX 用戶端的存取控制與 CQL 的存取控制分開設定。對於驗證和授權,有兩個可用的提供者;第一個基於標準 JMX 安全性,第二個與 Cassandra 自有的驗證子系統更緊密整合。
Cassandra 的預設設定僅允許從 localhost 存取 JMX。若要啟用遠端 JMX 連線,請編輯 cassandra-env.sh
以將 LOCAL_JMX
設定變更為 no
。在標準設定下,當啟用遠端 JMX 連線時,標準 JMX 驗證 <standard-jmx-auth>
也會開啟。
請注意,預設情況下,僅限本機的連線不受驗證,但可以啟用此功能。
如果啟用遠端連線,建議也使用 SSL
連線。
最後,在啟用驗證和/或 SSL 之後,請確保使用 JMX 的工具(例如 nodetool
)已正確設定且運作正常。
標準 JMX 驗證
允許連線到 JMX 伺服器的使用者會指定在一個簡單的文字檔中。此檔案的位置會在 cassandra-env.sh
中設定,行如下所示
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
編輯密碼檔案以新增使用者名稱/密碼配對
jmx_user jmx_password
保護認證檔案,讓只有執行 Cassandra 程序的使用者可以讀取
$ chown cassandra:cassandra /etc/cassandra/jmxremote.password
$ chmod 400 /etc/cassandra/jmxremote.password
選擇性地啟用存取控制,以限制已定義使用者可透過 JMX 執行的範圍。請注意,在這個脈絡中,這是一個相當直接的工具,因為 Cassandra 中大多數的操作工具都需要完整的讀取/寫入存取權。若要設定一個簡單的存取檔案,請取消 cassandra-env.sh
中這一行的註解
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
然後編輯存取檔案,以授予您的 JMX 使用者讀寫權限
jmx_user readwrite
必須重新啟動 Cassandra 才能套用新的設定。
另請參閱:在 JMX 中使用基於檔案的密碼驗證
Cassandra 整合式驗證
現成的 JMX 驗證的替代方案是使用 Cassandra 自己針對 JMX 客戶端的驗證和/或授權提供者。這可能更具彈性和安全性,但有一個主要的警告。也就是說,在節點加入環狀網路之前,它不可用,因為在那個時間點之前,驗證子系統尚未完全設定。然而,在引導期間,為了監控目的,通常需要 JMX 存取權。因此,建議在可能的情況下,在引導期間僅使用本機 JMX 驗證,然後,如果需要遠端連線,則在節點加入環狀網路且初始設定完成後,切換到整合式驗證。
使用這個選項,可使用與 CQL 驗證相同的資料庫角色來控制對 JMX 的存取,因此可以使用 cqlsh
集中管理更新。此外,可透過 GRANT PERMISSION
精確控制對特定 MBean 允許執行的操作。
若要啟用整合式驗證,請編輯 cassandra-env.sh
以取消下列各行的註解
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.login.config=CassandraLogin"
#JVM_OPTS="$JVM_OPTS -Djava.security.auth.login.config=$CASSANDRA_HOME/conf/cassandra-jaas.config"
並透過註解這一行來停用 JMX 標準驗證
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
若要啟用整合式授權,請取消這一行的註解
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.authorizer=org.apache.cassandra.auth.jmx.AuthorizationProxy"
透過確保這一行已註解掉,來檢查標準存取控制是否已關閉
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
啟用整合式驗證和授權後,操作員可以定義特定角色,並授予他們存取特定 JMX 資源的權限。例如,具有使用 jconsole 或 jmc 等工具的唯讀模式所需權限的角色會定義為
CREATE ROLE jmx WITH LOGIN = false;
GRANT SELECT ON ALL MBEANS TO jmx;
GRANT DESCRIBE ON ALL MBEANS TO jmx;
GRANT EXECUTE ON MBEAN 'java.lang:type=Threading' TO jmx;
GRANT EXECUTE ON MBEAN 'com.sun.management:type=HotSpotDiagnostic' TO jmx;
# Grant the role with necessary permissions to use nodetool commands (including nodetool status) in read-only mode
GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=EndpointSnitchInfo' TO jmx;
GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=StorageService' TO jmx;
# Grant the jmx role to one with login permissions so that it can access the JMX tooling
CREATE ROLE ks_user WITH PASSWORD = 'password' AND LOGIN = true AND SUPERUSER = false;
GRANT jmx TO ks_user;
也支援對個別 MBean 的細緻存取控制
GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=Tables,keyspace=test_keyspace,table=t1' TO ks_user;
GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=Tables,keyspace=test_keyspace,table=*' TO ks_owner;
這允許 ks_user
角色呼叫 test_keyspace
中單一表格的 MBean 上的方法,同時授予 ks_owner
角色對該鍵空間中所有表格層級 MBean 的相同權限。
完成初始設定後,會動態處理新增/移除角色和授予/撤銷權限,因此如果權限有變更,不需要進一步重新啟動。
另請參閱:Permissions
。
使用 SSL 的 JMX
JMX SSL 組態由多個系統屬性控制,其中一些屬性是選用的。若要開啟 SSL,請編輯 cassandra-env.sh
中相關行,取消註解並根據需要設定這些屬性的值
com.sun.management.jmxremote.ssl
-
設為 true 以啟用 SSL
com.sun.management.jmxremote.ssl.need.client.auth
-
設為 true 以啟用客戶端憑證驗證
com.sun.management.jmxremote.registry.ssl
-
為 RMI 註冊表啟用 SSL socket,客戶端可從中取得 JMX 連接器 stub
com.sun.management.jmxremote.ssl.enabled.protocols
-
預設情況下,將使用 JVM 支援的通訊協定,使用逗號分隔的清單覆寫。請注意,這通常並非必要,使用預設值是較佳選項。
com.sun.management.jmxremote.ssl.enabled.cipher.suites
-
預設情況下,將使用 JVM 支援的加密組,使用逗號分隔的清單覆寫。請注意,這通常並非必要,使用預設值是較佳選項。
javax.net.ssl.keyStore
-
設定包含伺服器私密金鑰和公開憑證的本機檔案系統上的金鑰庫路徑
javax.net.ssl.keyStorePassword
-
設定金鑰庫檔案的密碼
javax.net.ssl.trustStore
-
如果需要驗證客戶端憑證,請使用此屬性指定包含受信任客戶端公開憑證的信任庫路徑
javax.net.ssl.trustStorePassword
-
設定信任庫檔案的密碼
加密提供者
指定自訂 Java 加密提供者的功能是 CASSANDRA-18624 的一部分
cassandra.yaml
中 crypto_provider
的預設組態如下所示
# Configures Java crypto provider. By default, it will use
# DefaultCryptoProvider which will install Amazon Correto
# Crypto Provider.
#
# Amazon Correto Crypto Provider works currently for
# x86_64 and aarch_64 platforms. If this provider fails it will
# fall back to the default crypto provider in the JRE.
#
# To force failure when the provider was not installed properly,
# set the property "fail_on_missing_provider" to "true".
#
# To bypass the installation of a crypto provider use
# class 'org.apache.cassandra.security.JREProvider'
#
crypto_provider:
- class_name: org.apache.cassandra.security.DefaultCryptoProvider
parameters:
- fail_on_missing_provider: "false"
對於較舊的節點,當它們使用尚未設定 crypto_provider
區段的相同 cassandra.yaml
升級到 Cassandra 5.0 時,它們將預設為 JREProvider
,不會安裝任何提供者,而且會使用 Cassandra 執行的 JRE 中的提供者。
如上述程式片段所示,DefaultCryptoProvider
正在安裝 Amazon Corretto 加密提供者,已證明其效能遠高於 JRE 安裝中的預設加密提供者。
如果您想使用其他加密提供者,您有兩個選項。
第一個選項是組態您的 JRE,特別是 java.security
檔案,以指示 JRE 使用哪個加密提供者。您還需要將該加密提供者的相關實作放入 JRE 的類別路徑中。
第二個選項是透過延伸 org.apache.cassandra.security.AbstractCryptoProvider
並實作四個方法來實作您自己的加密提供者
- getProviderName
-
傳回您的提供者名稱
- getProviderClassAsString
-
傳回延伸
java.security.Provider
的實際加密提供者的 FQCN。 - installator
-
傳回在執行階段安裝您的
java.security.Provider
的Runnable
。 - isHealthyInstallation
-
如果安裝「正常」,則傳回
true
,否則傳回 false。這可用於檢查您的提供者安裝是否成功。
在安裝加密提供者時,AbstractCryptoProvider
會檢查您要安裝的提供者是否已安裝。如果已安裝,而且其安裝位置為 1
(因為提供者是依序安裝的),系統會記錄一則關於此事實的訊息。如果您直接透過 java.security
組態您的 JRE,而且您嘗試也透過 Cassandra 安裝相同的提供者,可能會發生這種情況。
如果已安裝但不在第一個位置,如果將 fail_on_missing_provider
設為 true
,將會擲回例外,且節點將無法啟動。如果安裝供應器不成功,也會發生相同情況。
平台特定函式庫會自動透過 cassandra.in.sh
指令碼加入 Cassandra 的類別路徑。目前有 lib/aarch64
和 lib/x86_64
目錄,其中包含每個各自架構的 JAR 檔案。平台由 uname -m
指令碼的輸出決定。