当前位置: 欣欣网 > 码农

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 向量数据库。