我再次帶來了我作為ScyllaDB開發倡導者的日常工作中的一些知識,這次我將教您有關安全和加密連接的知識!這個主題可能會讓新手感到非常焦慮,但我會讓你變得更容易。

如果您剛開始使用一般資料庫或特定資料庫,您可能需要先閱讀我的第一篇文章資料庫 101:初學者的資料一致性

本文記錄了我自己對有多少資料庫範例的探索,因為我的眼光遠遠超出了我以前僅使用 SQL 和 MySQL 的經驗。我正在資料庫 101系列中追蹤我的研究。

目錄

- [4.1 No Authentication](#41-no-authentication)
- [4.2 Username/Password Authentication](#42-usernamepassword-authentication)
- [4.3 Creating Users and Roles](#43-creating-users-and-roles)
- [4.4 Certificated / Role Certificated Authentication](#44-certificated--role-certificated-authentication)
    - [4.4.1 Change the Authentication Type](#441-change-the-authentication-type)
    - [4.4.2 Enable the Encryption Port](#442-enable-the-encryption-port)
    - [4.4.3 Enable the Client Encryption Port](#443-enable-the-client-encryption-port)
  1. 序言

在 NoSQL 資料庫上工作具有挑戰性,因為我必須學習作為普通 Web 開發人員永遠不會接觸或研究的東西。我的意思是,大多數情況下,您建立一個 CRUD 應用程式,盡力不要搞砸資料庫索引(對的人??????)並繪製一些按鈕。

但如果您一直在關注我的 Database 101 之旅,您可能知道,當我來到 Scylla 時,除了 MySQL 是什麼以及如何使用 Laravel 建立東西之外,對資料庫一無所知,現在我開始了解它:

  • 使用 ScyllaDB 建立高度可擴展的應用程式

  • 仍在學習 Rust - 1 年 6 個月(我覺得我對此一無所知)

  • 開始學習 ShellScript、Go、Python、JavaScript 以及任何具有 ScyllaDB 驅動程式的語言

  • 使用 Grafana/Prometheus 學習了可觀察性的基礎知識

  • 和我的新朋友傳輸層安全(又稱TLS

如果您正在設定自己的伺服器,您可能已經使用certbot安裝憑證以順利執行 HTTPS,這就是我過去 6~7 年一直在做的事情。說實話,了解如何使用工具是我們開發人員所做的。

這甚至看起來像是一個預兆,但我正在開發一個瀏覽器擴展,其後端是用 Rust 編寫的,而且我沒有設法在那裡使用certbot ,所以我不得不使用奇怪的命令建立我的憑證並加入一個奇怪的openssl板條箱到我的專案並相信它會起作用:

let mut certs_file = BufReader::new(File::open(cert_path).unwrap());
let mut key_file = BufReader::new(File::open(key_path).unwrap());

// load TLS certs and key to create a self-signed temporary cert for testing:
// `openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'`
let tls_certs = rustls_pemfile::certs(&mut certs_file)
    .collect::<Result<Vec<_>, _>>()
    .unwrap();
let tls_key = rustls_pemfile::pkcs8_private_keys(&mut key_file)
    .next()
    .unwrap()
    .unwrap();

經過幾個小時的嘗試/捕捉,我終於成功地使用憑證部署了 API,但我沒有學到任何東西。然後,幾天后,我的老闆要求我擴展ScyllaDB 安全頁面並了解基於憑證的連接的工作原理,因為我從未使用過它。

我花了 10 個小時並設法讓它工作,但主要與文件無關,而是我缺乏這方面的知識,這不再是問題,我會教你我所學到的一切到目前為止已經學到了!

2.什麼是SSL和TLS?

TLDR:這是一個無聊的部分,如果您願意,可以跳過。

SSL(安全通訊端層)由 Netscape 於 1995 年推出,旨在為網路通訊(主要是在瀏覽器中)提供隱私、驗證和資料完整性。 TLS(傳輸層安全性)繼承了 SSL,現已成為網路上電子郵件、訊息傳遞和 VoIP 等應用程式使用的標準安全協定。

如果沒有 SSL/TLS,客戶端和伺服器之間傳輸的資料是未加密的,並且容易被攔截和濫用,這很容易成為網路釣魚和其他攻擊的目標。 SSL/TLS 確保在資料傳輸之前發生安全的“握手”,這表示該特定會話的所有資料都經過加密。

然而,即使 SSL/TLS 提供加密,它也不能保證伺服器本身完全值得信賴或安全。 SSL 自 1996 年以來因其漏洞而被棄用,但由於其歷史意義,開發人員仍經常將其與 TLS 一起稱為「SSL/TLS」。

了解了 SSL/TLS 後,現在讓我們深入了解有助於管理安全連線的工具。

  1. 菜鳥用的 OpenSSL

目前有許多資料加密工具包可用,但我們將討論一個非常具體的工具包: openssl-library.org

該庫於 1998 年首次發布,附在每個有關資料加密的教程中,並且被開源/閉源環境中的許多其他工具使用 - 例如 Let's Encrypt 和 Certbot - 以及我們將要使用的工具在這裡使用。

OpenSSL 手冊

該工具的目的是建立鑰匙串和憑證以授權某人做您想做的任何事情。

想像一下,您在一座商業建築中工作,必須向保安出示您的徽章才能進入:

  • 您的公司建立一個“主密鑰”並為其產生一個憑證。

  • 您也可以為保全產生金鑰和憑證,並將其連同所有員工憑證的清單一起交給他。

  • 警衛有一個信任庫鑰匙串,上面有各種標籤。

  • 當你到達入口時,他會檢查你的標籤是否與他的根憑證相同,以決定你是否可以通過。

加密目的圖

在命令方面,我們做了這樣的事情:

# Creating the root/master key and certificate
# -----
openssl genpkey -algorithm RSA -out root_key.pem -pkeyopt rsa_keygen_bits:2048 # Generate the root key
openssl req -x509 -new -key root_key.pem -days 3650 -out root_cert.pem -subj "/CN=administrator" # Generate the root certificate
# -----

# Creating the Employee Key and Certificate
# -----
openssl genpkey -algorithm RSA -out employee_key.pem -pkeyopt rsa_keygen_bits:2048 # Generate the employee base key
openssl req -new -key employee_key.pem -out employee.csr -subj "/CN=employee" # Generate the employee CSR
openssl x509 -req -in employee.csr -CA root_cert.pem -CAkey root_key.pem -CAcreateserial -out employee_cert.pem -days 365 # Sign and generate the employee certificate with the root/master key and certificate
cat root_cert.pem employee_cert.pem > employee_truststore.pem # Create a truststore (tag) to be used together with the key.
# -----

# Creating the Security (server) Key and Certificate
# -----
openssl genpkey -algorithm RSA -out security_key.pem -pkeyopt rsa_keygen_bits:2048 # Generate the security key
openssl req -new -key security_key.pem -out security.csr -subj "/CN=server" # Generate the security CSR
openssl x509 -req -in security.csr -CA root_cert.pem -CAkey root_key.pem -CAcreateserial -out security_cert.pem -days 365 # Sign and generate the security certificate with the root/master key and certificate
cat root_cert.pem security_cert.pem > security_truststore.pem # Create a truststore (tag) to be used together with the key.
# -----

# Creating the Malicious Root and Client Key and Certificate
# -----
openssl genpkey -algorithm RSA -out malicious_key.pem -pkeyopt rsa_keygen_bits:2048 # Generate the malicious root key
openssl req -x509 -new -key malicious_key.pem -days 3650 -out malicious_cert.pem -subj "/CN=fake-admin" # Generate the malicious root certificate
cat root_cert.pem malicious_cert.pem > malicious_truststore.pem # Combine root and malicious root certificates into a truststore
# -----

命令太多了,但基本上是這樣的:

  • 產生了root_key.pemroot_cert.pem

  • 這些金鑰和憑證用於為員工簽署其他金鑰和憑證:

* `security_key.pem` was signed by `root_key.pem`.
* `employee_key.pem` was signed by `root_key.pem`.
* `server_key.pem` has been signed by `root_key.pem`.
  • 所有這些金鑰都位於名為security_truststore.pem的檔案中。

  • 有人試圖使用root_cert.pem建立一個名為malicious_key.pem假金鑰

現在讓我們來做一些驗證。理論上,只應允許security_truststore.pem中的金鑰加入:

# Validating the certificates with the truststores
# ----- 
openssl verify -CAfile security_truststore.pem employee_cert.pem # Check if the certificate is valid
# employee_cert.pem: OK

openssl verify -CAfile security_truststore.pem malicious_cert.pem # Check if the certificate is valid
# CN = fake-admin
#  error 18 at 0 depth lookup: self-signed certificate
#  error malicious_cert.pem: verification failed
# ----- 

正如預期的那樣,由於惡意金鑰未由根用戶簽名,因此身份驗證失敗並且該人被踢出。

現在我們了解了加密的基礎知識。但在現實世界中你在哪裡使用它呢?讓我告訴你更多關於我目前的任務,然後你就會明白。

  1. 資料庫認證

假設您正在 Docker 中執行任何資料庫(例如 MySQL、Postgres、ScyllaDB、Redis 等)。當您在容器化環境中啟動這些實例時,通常不需要密碼,除非您設定了密碼。無論如何,當我們談論現代網路任何部分的身份驗證時,我們都有很多選擇,當我們談論資料庫時也是如此。

我們將在本範例中使用ScyllaDB ,但此流程在許多資料庫中非常常見。

在此步驟中,我們將了解:

  1. 無需身份驗證:實際上不需要任何憑證,只需旋轉您的實例就可以了;

  2. 使用者名稱/密碼身份驗證:一些基本憑證可以讓人們遠離您的資料;

  3. 認證/角色認證認證:這是大公司喜歡玩的地方,你應該學習這一點。

簡單介紹完加密101之後,我們就可以開始了解內容本身了。

4.1 無需認證

在 Scylla 中,如果您在開發環境(本機或使用 Docker)中執行節點或集群,則預設沒有密碼。此外, ScyllaDB 預設在連接埠 9042 上使用 CQL 協議,可以在設定檔中輕鬆變更。

我為什麼要告訴你這個連接埠資訊?因為這些資訊稍後會很重要,請相信我。

您可以透過執行 Docker 實例來啟動它:

# Running a ScyllaDB Node with Docker
docker  run --name some_scylla -p 9042:9042 -p 9142:9142 -d scylladb/scylla:6.1.2 \
  --overprovisioned 1 --smp 1 

# Checking the node status -> Expect for UN (Up And Running)Cassandra
docker exec -it some_scylla nodetool status
# Datacenter: datacenter1
# =======================
# Status=Up/Down
# |/ State=Normal/Leaving/Joining/Moving
# -- Address   Load      Tokens Owns Host ID                              Rack 
# UN 10.10.5.2 509.46 KB 256    ?    9f597eb5-a77f-493f-9835-85dd1e571fcc rack1
# --

之後,您可以透過執行以下命令登入cqlsh(CQL Shell)

docker exec -it some_scylla cqlsh
# Connected to  at 10.10.5.5:9042
# [cqlsh 6.0.18 | Scylla 6.0.1-0.20240612.bc89aac9d017 | CQL spec 3.3.1 | Native protocol v4]
# Use HELP for help.
# cqlsh> select address, port, client_type, username from system.clients;
#
#  address   | port  | client_type | username
# -----------+-------+-------------+-----------
#  10.10.5.5 | 50854 |         cql | anonymous
#  10.10.5.5 | 50868 |         cql | anonymous
# -----------+-------+-------------+-----------

是的,我們以匿名用戶的身份連接!非常適合開發新東西和本地測試。但隨後您決定將相同的配置部署到生產中...

當然,不到一小時,你就會被某個隨機的資料庫爬蟲所擁有,哈哈。

擁有 PostgreSQL

如果您願意,您可以閱讀有關此勒索軟體的更多資訊。無論如何,讓我們加入一些基本憑證並在下一步中正確配置它。

說真的,不要使用預設配置或不綁定唯一的 IP 位址來存取資料庫,從而將資料庫開放到 Internet。

4.2 使用者名稱/密碼認證

在執行任何其他資料庫時,您可以透過變更一堆設定檔來切換身份驗證類型。在ScyllaDB ,我們對配置的模組化和簡單性感到非常自豪。

如果您在 docker 中查看/etc/scylla/scylla.yaml (您可以透過點擊此處更好地查看儲存庫(檔案:scylla.yaml#247) ,您將找到這些設定標誌:

# file: /etc/scylla/scylla.yaml
# ...
# ...
# Authentication backend, identifying users
# Out of the box, Scylla provides org.apache.cassandra.auth.{AllowAllAuthenticator,
# PasswordAuthenticator}.
#
# - AllowAllAuthenticator performs no checks - set it to disable authentication.
# - PasswordAuthenticator relies on username/password pairs to authenticate
#   users. It keeps usernames and hashed passwords in system_auth.credentials table.
#   Please increase system_auth keyspace replication factor if you use this authenticator.
# - com.scylladb.auth.TransitionalAuthenticator requires username/password pair
#   to authenticate in the same manner as PasswordAuthenticator, but improper credentials
#   result in being logged in as an anonymous user. Use for upgrading clusters' auth.
# authenticator: AllowAllAuthenticator
# ...

預設值是AllowAllAuthenticator ,它允許與超能力的匿名連接。現在,我們取消註解# authenticator:行並替換為PasswordAuthenticator

# file: /etc/scylla/scylla.yaml
# ...
-#authenticator: AllowAllAuthenticator  # line ~247
+authenticator: PasswordAuthenticator

好的!現在我們只需要告訴 Scylla 節點我們已經進行了此更改。由於這是對我們的系統環境的“關鍵”更改,因此我們需要drain然後重新啟動節點。這是逐步指南:

# Before Editing
docker exec -it some_scylla nodetool drain # Stop gossiping and preparing to shut down
docker exec -it some_scylla supervisorctl stop scylla # Stop ScyllaDB
docker exec -it some_scylla cat /etc/scylla/scylla.yaml | grep authenticator: # Check the current flag

# Edit /etc/scylla/scylla.yaml ...
docker exec -it some_scylla sed -i 's/# authenticator:.*/authenticator: PasswordAuthenticator/' /etc/scylla/scylla.yaml

# After Edit
docker exec -it some_scylla cat /etc/scylla/scylla.yaml | grep authenticator: # Check if the update is there
docker exec -it some_scylla supervisorctl start scylla # Run ScyllaDB

這樣我們終於能夠執行cqlsh並收到一張巨大的「你需要憑證,婊子」:

docker exec -it some_scylla cqlsh
Connection error: ('Unable to connect to any servers', {'10.10.5.5:9042': AuthenticationFailed('Remote end requires authentication')})

預設情況下,在 ScyllaDB,我們可以使用使用者名稱/密碼「cassandra」(超級使用者)登入:

docker exec -it some_scylla cqlsh -u cassandra -p cassandra
# Connected to  at 10.10.5.5:9042
# [cqlsh 6.0.18 | Scylla 6.0.1-0.20240612.bc89aac9d017 | CQL spec 3.3.1 | Native protocol v4]
# Use HELP for help.
# cassandra@cqlsh> select address, port, client_type, username from system.clients; 

#  address   | port  | client_type | username
# -----------+-------+-------------+-----------
#  10.10.5.5 | 56998 |         cql | cassandra
#  10.10.5.5 | 57014 |         cql | cassandra
# -----------+-------+-------------+-----------

……至此,我們知道如何在 ScyllaDB 中配置身份驗證的基礎知識,如果您想知道為什麼用戶/密碼是“cassandra”,您可以閱讀我本系列的第一篇文章。另外,請務必在部署之前更改您的預設憑證。

CQL 協定預設執行在連接埠 9042 上,並且眾所周知。就像您可以透過讓資料庫在沒有身份驗證的情況下執行來獲得所有權一樣,您也可以透過在那裡使用預設憑證來獲得所有權

目前,所有連線仍未unencrypted但至少我們有最低限度的安全性,但不用擔心!我們很快就會修復加密問題!在此之前,讓我們在資料庫中建立一些使用者/角色。

4.3 建立使用者和角色

在為此資料庫建立新使用者之前,我們需要了解它是如何運作的。在 Scylla,我們每天都使用Role Based Authentication 。因此每個用戶都作為一個角色放置在system.roles中。

這不是問題,因為您可以為角色設定PASSWORD 。它看起來很奇怪,但我會告訴你它是如何工作的。一探究竟:

scylladb@cqlsh> desc system.roles;

CREATE TABLE system.roles (
    role text,
    can_login boolean,
    is_superuser boolean,
    member_of set<text>,
    salted_hash text,
    PRIMARY KEY (role)
);

scylladb@cqlsh> select * from system.roles;

 role        | can_login | is_superuser |     member_of | salted_hash
-------------+-----------+--------------+---------------+--------------------
 scylladb    |      True |         True |          null | $6$rAJ6FflUo8Chf...
 employee    |     False |        False |          null | null
 danielhe4rt |      True |        False |  {'employee'} | $6$AF4F6CflAA8Cw...
-------------+-----------+--------------+---------------+--------------------

此輸出為我們提供了有關身份驗證本身的一些訊息,例如

  • can_login標誌設為true時,角色變得可驗證;

  • 角色成為可驗證角色後必須/可以擁有密碼;

  • 一個角色可以屬於another role ,該角色將繼承該角色的所有權限。

這只是一個為您提供建模和功能如何運作的範例而建立的環境。請務必閱讀文件。

DCL(資料控制語言)DML(資料操作語言)方面,我們將執行以下基本命令:

-- Create our user/roles
CREATE ROLE developer;
CREATE ROLE danielhe4rt WITH PASSWORD = 'some_cool_password' AND LOGIN = true;

-- Grant roles to our users
GRANT developer TO danielhe4rt;

……我們將按照本文開頭建立的密鑰在 ScyllaDB Docker 實例中執行它:

docker exec -it some-scylla cqlsh -u cassandra -p cassandra -e "CREATE ROLE IF NOT EXISTS 'employee' WITH LOGIN = true;";
docker exec -it some-scylla cqlsh -u cassandra -p cassandra -e "CREATE ROLE IF NOT EXISTS 'server' WITH LOGIN = true;";

注意:您只能使用經過驗證的帳戶建立新角色/用戶

4.4 憑證/角色憑證認證

在本教程的開頭,我們透過談論某人擁有有效鑰匙進入建築物的故事來介紹該主題,現在的目標是了解與常規身份驗證的不同之處。正如我所說,如果沒有 TLS/SSL,您的資料在傳輸過程中不會經過任何加密,這很糟糕,具體取決於您發送/接收的內容。

使用憑證意味著在您發送資料之前,我們可以保證,如果有人攔截資料,即使他們沒有解密金鑰也不會出現問題。

  • 預設情況下,ScyllaDB 在連接埠 9042 上偵聽 CQL 協議,可以使用native_transport_port配置選項進行設定。

  • Scylla 也透過 TLS/SSL 加密支援 CQL 協議,該協議預設為停用,可以使用native_transport_port_ssl配置選項啟用。

安全連線的傳統連接埠選擇是 9142,但如果指定了client_encryption_options而未指定native_transport_port_ssl ,則native_transport_port將只處理加密連線。如果native_transport_portnative_transport_port_ssl設定為相同的值,也會發生相同的事情。

我知道,所有這些標誌和選項似乎有點瘋狂,但我會盡力使其更簡單。查看管理連接埠分配/加密的規則,下表總結了這些規則:

np  := native_transport_port is set
nps := native_transport_port_ssl is set
ceo := client_encryption_options are enabled
eq  := native_transport_port_ssl == native_transport_port

+-----+-----+-----+-----+
|  np | nps | ceo |  eq |
+-----+-----+-----+-----+
|  0  |  0  |  0  |  *  |   =>   listen on native_transport_port, unencrypted
|  0  |  0  |  1  |  *  |   =>   listen on native_transport_port, encrypted
|  0  |  1  |  0  |  *  |   =>   don't listen
|  0  |  1  |  1  |  *  |   =>   listen on native_transport_port_ssl, encrypted
|  1  |  0  |  0  |  *  |   =>   listen on native_transport_port, unencrypted
|  1  |  0  |  1  |  *  |   =>   listen on native_transport_port, encrypted
|  1  |  1  |  0  |  *  |   =>   listen on native_transport_port, unencrypted
|  1  |  1  |  1  |  0  |   =>   listen on native_transport_port, unencrypted + native_transport_port_ssl, encrypted
|  1  |  1  |  1  |  1  |   =>   listen on native_transport_port(_ssl - same thing), encrypted
+-----+-----+-----+-----+

// More at: https://github.com/scylladb/scylladb/blob/master/docs/dev/protocols.md#cql-client-protocol

這告訴我們,如果我們想啟用加密,我們需要在scylla.yaml中更新一些內容。我們將切換到com.scylladb.auth.CertificateAuthenticator功能,而不是使用PasswordAuthenticator

在我們進行任何更改之前,讓我們清空並停止叢集:

docker exec -it some_scylla nodetool drain # Stop gossiping and preparing to shut down
docker exec -it some_scylla supervisorctl stop scylla # Stop ScyllaDB

在上一個步驟中,我們建立了一些啟用了登入的角色。我們將這些「角色」加入到頂部的 OpenSSL 命令中,並使用CN=server/blabla ,對嗎?現在是時候讓它變得有用並且不再使用憑證了。

私鑰+憑證可以保存更多訊息,例如握手完成後可以使用的原始字串。在本例中,我們已將用於登入的使用者/角色儲存在我們的金鑰內。有了這個,我們可以與憑證內容進行模式匹配,並檢查是否有任何CN=something與我們的select * from system.roles where role = 'something'匹配。

讓我們透過輸入 ScyllaDB 實例來開始修改:

# Enter the ScyllaDB Instance
docker exec -it some_scylla shell

# root@c531i213hu:/#
# Install any editor of your choice
apt install nano

# Enter the ScyllaDB Config File
nano -l /etc/scylla/scylla.yaml

打開設定檔後,讓我們進行所需的修改。

4.4.1 更改認證類型

我保證,這是我們最後一次打開此文件!這裡的想法是將身份驗證類型從PasswordAuthenticator更改為com.scylladb.auth.CertificateAuthenticator 。我們還將設定一條規則,從每個憑證中提取CN=標誌並將內容用於身份驗證目的:

# file: /etc/scylla/scylla.yaml

-authenticator: PasswordAuthenticator # line ~247
+authenticator: com.scylladb.auth.CertificateAuthenticator
+auth_certificate_role_queries:
+  - source: SUBJECT
+    query: CN=([^,\s]+)

4.4.2 啟用加密連接埠

即使設定了身份驗證器後,我們仍然沒有啟用TLS/SSL 。我們仍然需要取消註解native_transport_port_ssl以將連接埠9142(用於傳輸我們的加密資料)引入遊戲。那麼,回到scylla.yaml ,讓我們更改它:

# file: /etc/scylla/scylla.yaml
# ...
-# native_transport_port_ssl: 9142 # <- line ~131
+native_transport_port_ssl: 9142

4.4.3 啟用客戶端加密連接埠

一步一步來,我們一定會成功的!我們最後的更改是對上表中定義的client_encryption_options進行更改。我們需要取消所有內容的註釋並確保這些配置中的所有內容都相符。以下是每個配置的簡要說明:

  • 啟用:啟用 TLS/SSL 加密 -> 變更為true (預設值:false)

  • 憑證:伺服器憑證的absolute path (security_cert.pem / server_cert.pem)

  • keyfile:由 root_key 簽署的伺服器金鑰的absolute path (security_key.pem / server_key.pem)

  • truststore:包含伺服器+根憑證的伺服器信任庫的absolute path (security_truststore.pem / server_truststore.pem)

  • require_client_auth:您的伺服器必須接收憑證才能進行身份驗證 -> 變更為 true

那麼,讓我們來進行這些更改:

# file: /etc/scylla/scylla.yaml
# ...
# enable or disable client/server encryption.
-# client_encryption_options:
-#   enabled: true
-#   certificate: /etc/scylla/certs/cert.pem
-#   keyfile: /etc/scylla/certs/key.pem
-#   truststore: /etc/scylla/certs/truststore.pem
-#   require_client_auth: true
+client_encryption_options:
+  enabled: true
+  certificate: /etc/scylla/certs/server_cert.pem
+  keyfile: /etc/scylla/certs/server_key.pem
+  truststore: /etc/scylla/certs/server_truststore.pem
+  require_client_auth: true

好的!現在我們可以出發了。讓我們透過執行以下命令來開啟 ScyllaDB 叢集:

docker exec -it some_scylla supervisorctl start scylla # Start ScyllaDB

讓我們看看連接埠 9142 是否正在執行並偵聽 TLS/SSL 連線:

openssl s_client -connect localhost:9042 
# CONNECTED(00000003)
# 40873B60D2750000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:354:
# no peer certificate available
# No client certificate CA names sent

openssl s_client -connect localhost:9142
# CONNECTED(00000003)
# Can't use SSL_get_servername
# depth=0 CN = server
# verify error:num=20:unable to get local issuer certificate
# verify return:1
# depth=0 CN = server
# verify error:num=21:unable to verify the first certificate
# verify return:1
# depth=0 CN = server
# verify return:1
# ---
# Certificate chain
# 0 s:CN = server
#   i:CN = administrator
#   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
#   v:NotBefore: Aug  1 20:09:38 2024 GMT; NotAfter: Aug  1 20:09:38 2025 GMT
# ---
# YAY IT'S ASKING FOR CERTIFICATES!!!

此時,我們 100% 確定 TLS 已啟用並要求與我們先前產生的金鑰相符的憑證。

  1. 測試加密連接

要配置的東西太多了,但是我們要如何連接到它?為了簡單起見,我們將使用 NodeJS,而不是使用 CQLSH(因為設定它很麻煩,而且我更喜歡讓它在 Node 上執行,而不是解釋如何使用它)。

首先,讓我們透過執行來快速設定我們的驅動程式:

npm install @lambda-group/scylladb

之後,您已經可以建立一個指向節點的示範腳本,並且不要忘記在連接字串處切換連接埠:

import { Cluster } from "@lambda-group/scylladb";

const cluster = new Cluster({  
    nodes: ["127.0.0.1:9142"],
    ssl: {  
        enabled: true,  
        truststoreFilepath: "/your/path/to/certificates/developer_cert.pem",  
        privateKeyFilepath: "/your/path/to/certificates/developer_key.pem",  
        caFilepath: "/your/path/to/certificates/developer_truststore.pem",  
        verifyMode: VerifyMode.Peer,  
    }});
let result = await session.execute(
    "SELECT address, port, username, driver_name, driver_version FROM system.clients"
    );

console.log(result)
// [
//  {
//     address: '127.0.0.1',
//     driver_name: 'scylla-js-driver',
//     driver_version: '0.0.1',
//     port: 58846,
//     username: 'developer' // We're logged in as the role 'developer'
//  }
// ]

正如輸出告訴我們的那樣,我們只需將密鑰和憑證發送到伺服器即可成功連接!

六、結論

這篇「文章/教學」我花了很長時間寫,有幾個原因,但其中之一是透過幾次來確定內容。

我還製作了一個演示(gh:danielhe4rt/scylladb-role-tls-auth),您可以在其中執行makefile命令並設定所有這些步驟。所以如果你以某種方式來到這裡,請不要忘記給你一顆星:D

安全是當今人們開始更加關注的話題之一,了解更多資訊是非常令人興奮的。不管怎樣,請告訴我您想在本系列中看到哪些主題!

注意安全,別忘了喝水!


原文出處:https://dev.to/danielhe4rt/database-101-ssltls-for-beginners-4lmn


共有 0 則留言