當前位置: 妍妍網 > 碼農

Qdrant 向量資料庫的部署以及如何在 .NET 中使用 TLS 安全存取

2024-03-11碼農

本文介紹如何使用 Docker 部署 Qdrant 向量資料庫,以及其相關的安全配置,並演示如何使用 .NET 透過 TLS 安全存取 Qdrant 向量資料庫。

1. 背景

隨著 AIGC 的發展,向量資料庫已經成為一個重要的資源,可以高效地儲存和檢索大量的向量數據。向量資料庫在需要相似性搜尋的各種套用中起著至關重要的作用,例如:作為推薦系統,基於內容的影像檢索和個人化搜尋。透過使用向量資料庫,我們可以有效地處理大規模的 Embedding 數據,從而支持各種AI和機器學習套用。Qdrant 是一個開源的向量資料庫,它提供了高效的向量索引和查詢功能,以及便捷的 API 介面和多種語言的客戶端庫,如 Python、Go、Rust、.NET 和 Java 等。

在實際套用中,我們通常需要保護向量資料庫的存取安全,以防止未經授權的存取和數據泄露。為了保護向量資料庫的存取安全,我們可以使用 TLS 協定對資料庫的存取進行加密。本文將介紹如何使用 Docker 部署 Qdrant 向量資料庫,以及其相關的安全配置,並演示如何使用 .NET 透過 TLS 安全存取 Qdrant 向量資料庫。

qdrant

Qdrant 開源地址:https://github.com/qdrant/qdrant?wt.mc_id=DT-MVP-5005195

文件和相關介紹:https://qdrant.tech/

2. Qdrant 向量資料庫的部署

一般來說,我們可以使用 Docker 部署 Qdrant 向量資料庫。首先,我們需要安裝 Docker,然後使用以下命令拉取 Qdrant 的映像並啟動容器:

docker pull qdrant/qdrantdocker run -p 6333:6333 qdrant/qdrant

上面的命令將拉取 Qdrant 的映像並啟動容器,容器的 6333 埠將對映到主機的 6333 埠。這樣,我們就可以透過主機的 6333 埠存取 Qdrant 向量資料庫了。這對於一般的測試和開發環境來說是足夠的,對於生產環境如果僅在本機使用,也可以使用這種簡單的方式。但是,如果需要在生產環境中使用,我們通常需要對 Qdrant 向量資料庫進行一些安全配置。

2.1 Qdrant 向量資料庫的安全配置

在 Qdrant 的伺服端配置中,已經提供了相關的安全配置。我們可以透過配置檔 config.yaml 來配置 Qdrant 向量資料庫的安全選項。下面是安全相關的一些配置選項和建議:

1. 修改埠:預設情況下,Qdrant 向量資料庫的伺服端口是 http 6333 和 grpc 6334。我們可以透過配置檔中的 service.http_port service.grpc_port 選項來修改伺服端口。 2. 啟用TLS:配置檔中的 service.enable_tls cluster.p2p.enable_tls 預設為 false,這意味著服務和集群間的通訊都是不加密的。可以將兩個選項設定為 true,然後提供相應的證書檔路徑,以啟用安全的 TLS 通訊。需要在 tls 部份提供伺服器證書(cert)、伺服器私鑰(key)和證書頒發機構證書(ca_cert)。 3. 設定API金鑰:配置檔中的 service.api_key service.read_only_api_key ,啟用後可以進行 API 認證。設定一個復雜的 API 金鑰,以便只有擁有金鑰的客戶端才能存取服務。這個金鑰分為讀寫金鑰和唯讀金鑰,可以根據需要進行設定。 4. 驗證HTTPS客戶端證書:配置檔中的 service.verify_https_client_certificate 也可以啟用,服務會驗證 HTTPS 客戶端的證書。這樣可以增加一個額外的安全層,伺服端會要求客戶端也提供一個有效的證書。 5. 限制CORS:配置檔中的 service.enable_cors 預設為 true,這可能會導致跨站請求偽造(CSRF)攻擊。如果條件允許則應該考慮限制 CORS,允許來自可信來源的請求。 6. 限制並行更新:配置檔中的 storage.performance.update_rate_limit 預設為 null,服務沒有限制並行更新的數量。正式環境應該設定一個合理的限制,以防止拒絕服務(DoS)攻擊。 7. 關閉遙測:配置檔中的 telemetry_disabled 預設為 false,服務會將使用統計資訊發送給開發者。出於私密考慮,可以將此選項設定為 true。

2.2 使用 Docker 部署安全的 Qdrant 向量資料庫

前面一小節介紹了 Qdrant 向量資料庫的安全配置,接下來我們將介紹如何使用 Docker 部署安全的 Qdrant 向量資料庫。演示中我們將使用 TLS 安全存取 Qdrant 向量資料庫,包括伺服端和客戶端的證書驗證。

2.2.1 準備證書檔

首先我們需要準備好證書檔,包括伺服器證書(cert)、伺服器私鑰(key)和證書頒發機構證書(ca_cert)以及客戶端證書(client_cert)和客戶端私鑰(client_key)。這裏我們可以使用 OpenSSL 工具生成自簽名的證書,這裏不再贅述。

演示這裏我使用的是自己搭建的私有證書頒發機構,生成的證書。這裏我使用了二級證書頒發機構,簽發的伺服器證書和客戶端證書都是由二級證書頒發機構簽發的。

證書資訊

對於客戶端證書,我們需要將客戶端證書和客戶端私鑰放在一個檔中,可以直接生成一個 pfx 檔:

openssl pkcs12 -export -out client.pfx -inkey client.key -in client.cer

根據提示輸入密碼,生成的 client.pfx 檔就是客戶端證書和客戶端私鑰的合並檔。

2.2.2 Docker 部署及配置

接下來我們需要規劃好 Qdrant 的配置檔 production.yaml ,並將數據目錄、證書檔和配置檔放到 Docker 容器中。首先我們將證書檔放到一個目錄中,然後將這個目錄掛載到 Docker 容器中。

這裏我的配置如下:

log_level: INFOtelemetry_disabled: trueservice: host: 0.0.0.0 http_port: 6333 grpc_port: 6334 enable_tls: true verify_https_client_certificate: truetls: cert: ./tls/server.pem key: ./tls/server.key ca_cert: ./tls/cacert.pem

配置完成後,我們可以使用以下命令啟動 Qdrant 容器:

docker run -p 6333:6333 \ -v $(pwd)/path/to/data:/qdrant/storage \ -v $(pwd)/path/to/tls:/qdrant/tls \ -v $(pwd)/path/to/production.yaml:/qdrant/config/production.yaml \ qdrant/qdrant

註意修改 path/to/data path/to/tls path/to/production.yaml 為實際的路徑。

2.3 管理後台的存取

Qdrant 向量資料庫提供了一個簡單的管理後台,可以透過瀏覽器存取。預設情況下,管理後台的埠是 6333,我們可以透過配置檔中的 service.http_port 選項來修改埠。在瀏覽器中輸入 http://localhost:6333/dashboard 即可存取管理後台。

Qdrant 的 Web UI 是一個直觀高效的圖形界面,可以方便的檢視 Qdrant 集合、REST API 和數據點。這裏我們啟動的服務已經啟用了 TLS 安全存取,並要求客戶端提供有效的證書,所以我們需要使用 https 協定存取管理後台。

除了安裝並信任我們的證書,我們還需要在瀏覽器中匯入客戶端證書。如果沒有安裝客戶端證書,則會提示證書錯誤 ERR_BAD_SSL_CLIENT_AUTH_CERT ,無法存取管理後台。

未安裝證書

此時我們需要雙擊開啟客戶端證書 client.pfx ,然後根據提示安裝證書,中間需要輸入密碼,其他一路預設即可:

安裝證書

安裝完成後,我們直接重新整理頁面,會提示選擇證書:

提示選擇證書

選擇證書確認後,即可存取管理後台。

管理後台

3. 使用 .NET 透過 TLS 安全存取

雖然伺服端提供了API金鑰的方式,但仍然建議在客戶端與伺服端之間使用TLS加密。

3.1 證書驗證

以下是一些關於如何在.NET中使用TLS加密的建議:

首先,需要從證書檔中載入證書。可以使用 X509Certificate2 類來實作。例如,如果證書和私鑰都在一個 PKCS#12 檔(通常副檔名為 .pfx 或 .p12)中,可以這樣載入它:

var clientCert = new X509Certificate2("path/to/client.pfx", "password");

除了載入客戶端證書,我們還需要對伺服器證書進行驗證。可以使用 SocketsHttpHandler 類來實作。例如,可以使用以下程式碼來驗證伺服器證書:

stringCertificateThumbprint = "<certificate-thumbprint>";var clientCertificate = new X509Certificate2("<path-to-your-certificate.pfx>", "<your-password>");var channel = GrpcChannel.ForAddress("<your-server-address>", newGrpcChannelOptions{HttpHandler = newSocketsHttpHandler {SslOptions = newSslClientAuthenticationOptions {RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {if (sslPolicyErrors == SslPolicyErrors.None) {var x509Certificate = certificate as X509Certificate2;if (x509Certificate != null) {return x509Certificate.Thumbprint.ToLower() == CertificateThumbprint; } }returnfalse; },ClientCertificates = new X509CertificateCollection { clientCertificate } } }});

在上面的程式碼中,我們使用 SocketsHttpHandler 類來實作對伺服器證書的驗證。我們可以在 RemoteCertificateValidationCallback 回呼函式中實作自訂的證書驗證邏輯。在這個回呼函式中,我們可以驗證伺服器證書的有效性,例如:驗證證書的頒發機構、證書的有效期、證書的主題等。如果伺服器證書驗證透過,我們可以返回 true ,否則返回 false

這裏參考了官方的驗證方式,使用 Thumbprint 內容來驗證伺服器證書的指紋。我們可以在 RemoteCertificateValidationCallback 回呼函式中將伺服器證書的指紋與預期的證書指紋進行比較,如果一致則返回 true ,否則返回 false

這裏的 x509Certificate.Thumbprint 獲取的是證書的 sha1 指紋資訊。對於證書的指紋,我們可以使用以下命令來獲取:

openssl x509 -fingerprint -sha1 -in server.cer

Edge 瀏覽器的證書資訊界面重新設計了,並且顯示的是 sha256 指紋,所以需要註意。不過該指紋資訊可以方面我們使用官方下面的案例時直接使用:

var channel = QdrantChannel.ForAddress("https://localhost:6334", newClientConfiguration{ApiKey = "<api key>",CertificateThumbprint = "<certificate thumbprint>"});var grpcClient = newQdrantGrpcClient(channel);var client = newQdrantClient(grpcClient);

當然,如果需要獲取 sha1 指紋資訊也可以下載證書檔,直接在電腦中開啟開啟,然後在詳細資訊中檢視指紋資訊。

3.2 使用 .NET 客戶端存取

完成了驗證的配置,剩下的就是使用 .NET 客戶端存取 Qdrant 向量資料庫了。我們直接參考官方的案例即可,以下是一個簡單的 .NET 客戶端存取 Qdrant 向量資料庫建立集合的範例:

var grpcClient = newQdrantGrpcClient(channel);var client = newQdrantClient(grpcClient);await client.CreateCollectionAsync("my_collection",newVectorParams { Size = 100, Distance = Distance.Cosine });

4. 總結

本文介紹了如何使用 Docker 部署 Qdrant 向量資料庫,以及其相關的安全配置,並演示了如何使用 .NET 透過 TLS 安全存取 Qdrant 向量資料庫。透過本文的介紹,我們可以了解到如何在生產環境中安全地部署 Qdrant 向量資料庫,並使用 .NET 客戶端透過 TLS 安全存取 Qdrant 向量資料庫。