通信の暗号化
TLS (Transport Layer Security) は通信の安全性を確保するための暗号化プロトコルです。MilvusプロキシはTLSの片方向認証と双方向認証を使用します。
このトピックでは、gRPCとRESTfulトラフィックの両方でMilvusプロキシでTLSを有効にする方法について説明します。
TLSとユーザ認証は2つの異なるセキュリティアプローチです。Milvusシステムでユーザ認証とTLSの両方を有効にしている場合、ユーザ名、パスワード、証明書ファイルのパスを指定する必要があります。ユーザ認証を有効にする方法については、ユーザアクセスの認証を参照してください。
独自の証明書を作成する
前提条件
OpenSSLがインストールされていることを確認してください。インストールされていない場合は、まず OpenSSL をビルドしてインストールします。
openssl version
OpenSSLがインストールされていない場合。Ubuntuの以下のコマンドでインストールできます。
sudo apt install openssl
ファイルの作成
gen.sh
ファイルを作成する。
mkdir cert && cd cert
touch gen.sh
- 以下のスクリプトを
gen.sh
にコピーする。
gen.sh
ファイルでCommonName
を設定する必要がある。CommonName
は、クライアントが接続時に指定するサーバー名を指す。
gen.sh
#!/usr/bin/env sh
# your variables
Country="US"
State="CA"
Location="Redwood City"
Organization="zilliz"
OrganizationUnit="devops"
CommonName="localhost"
ExpireDays=3650 # 10 years
# generate private key for ca, server and client
openssl genpkey -quiet -algorithm rsa:2048 -out ca.key
openssl genpkey -quiet -algorithm rsa:2048 -out server.key
openssl genpkey -quiet -algorithm rsa:2048 -out client.key
# create a new ca certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 36500 -out ca.pem \
-subj "/C=$Country/ST=$State/L=$Location/O=$Organization/OU=$OrganizationUnit/CN=$CommonName"
# prepare extension config for signing certificates
echo '[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS = '$CommonName > openssl.cnf
# sign server certificate with ca
openssl req -new -key server.key\
-subj "/C=$Country/ST=$State/L=$Location/O=$Organization/OU=$OrganizationUnit/CN=$CommonName"\
| openssl x509 -req -days $ExpireDays -out server.pem -CA ca.pem -CAkey ca.key -CAcreateserial \
-extfile ./openssl.cnf -extensions v3_req
# sign client certificate with ca
openssl req -new -key client.key\
-subj "/C=$Country/ST=$State/L=$Location/O=$Organization/OU=$OrganizationUnit/CN=$CommonName"\
| openssl x509 -req -days $ExpireDays -out client.pem -CA ca.pem -CAkey ca.key -CAcreateserial \
-extfile ./openssl.cnf -extensions v3_req
gen.sh
ファイル内の変数は、証明書署名要求ファイルの作成プロセスにとって重要である。最初の5つの変数は、国、州、場所、組織、組織単位を含む基本的な署名情報である。クライアントとサーバーの通信中に検証されるため、CommonName
を設定する際には注意が必要である。
gen.sh
を実行して証明書を生成する。
gen.sh
ファイルを実行して証明書を作成する。
chmod +x gen.sh
./gen.sh
以下の7つのファイルが作成される:ca.key
ca.pem
,ca.srl
,server.key
,server.pem
,client.key
,client.pem
.
ca.key
,ca.pem
,ca.srl
は、後で証明書を更新するため、必ず安全な場所に保管してください。server.key
とserver.pem
ファイルはサーバーが使用し、client.key
とclient.pem
ファイルはクライアントが使用します。
証明書の更新(オプション)
証明書の有効期限が間もなく切れる場合など、証明書を更新したい場合は、以下のスクリプトを使用できます。
作業ディレクトリにca.key
,ca.pem
,ca.srl
が必要です。
renew.sh
#!/usr/bin/env sh
# your variables
Country="US"
State="CA"
Location="Redwood City"
Organization="zilliz"
OrganizationUnit="devops"
CommonName="localhost"
ExpireDays=3650 # 10 years
# generate private key for ca, server and client
openssl genpkey -quiet -algorithm rsa:2048 -out server.key
openssl genpkey -quiet -algorithm rsa:2048 -out client.key
# prepare extension config for signing certificates
echo '[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS = '$CommonName > openssl.cnf
# sign server certificate with ca
openssl req -new -key server.key\
-subj "/C=$Country/ST=$State/L=$Location/O=$Organization/OU=$OrganizationUnit/CN=$CommonName"\
| openssl x509 -req -days $ExpireDays -out server.pem -CA ca.pem -CAkey ca.key -CAcreateserial \
-extfile ./openssl.cnf -extensions v3_req
# sign client certificate with ca
openssl req -new -key client.key\
-subj "/C=$Country/ST=$State/L=$Location/O=$Organization/OU=$OrganizationUnit/CN=$CommonName"\
| openssl x509 -req -days $ExpireDays -out client.pem -CA ca.pem -CAkey ca.key -CAcreateserial \
-extfile ./openssl.cnf -extensions v3_req
renew.sh
ファイルを実行して証明書を作成する。
chmod +x renew.sh
./renew.sh
MilvusサーバーのTLS設定
このセクションでは、TLS暗号化でMilvusサーバを設定する手順の概要を説明します。
Docker Composeのセットアップ
1.Milvusサーバ設定の変更
外部TLSを有効にするには、milvus.yaml
:
proxy:
http:
# for now milvus do not support config restful on same port with grpc
# so we set to 8080, grpc will still use 19530
port: 8080
tls:
serverPemPath: /milvus/tls/server.pem
serverKeyPath: /milvus/tls/server.key
caPemPath: /milvus/tls/ca.pem
common:
security:
tlsMode: 1
パラメータ
serverPemPath
:サーバ証明書ファイルへのパス。serverKeyPath
:サーバー鍵ファイルへのパス。caPemPath
:CA証明書ファイルへのパスtlsMode
:外部サービスのTLSモード。有効な値:1
:サーバのみが証明書を必要とし、クライアントがそれを検証する一方向認証。このモードでは、サーバー側でserver.pem
とserver.key
、クライアント側でserver.pem
。2
:双方向認証:安全な接続を確立するために、サーバーとクライアントの両方が証明書を必要とします。このモードでは、サーバー側にserver.pem
、server.key
、ca.pem
、クライアント側にclient.pem
、client.key
、ca.pem
。
内部TLSを有効にするには、milvus.yaml
ファイルに以下の設定を追加する:
internaltls:
serverPemPath: /milvus/tls/server.pem
serverKeyPath: /milvus/tls/server.key
caPemPath: /milvus/tls/ca.pem
common:
security:
internaltlsEnabled: true
パラメータ
serverPemPath
:サーバー証明書ファイルへのパス。serverKeyPath
:サーバー鍵ファイルへのパス。caPemPath
:CA証明書ファイルへのパスinternaltlsEnabled
:内部TLSを有効にするかどうか。今のところ、片方向TLSのみがサポートされている。
2.証明書ファイルをコンテナにマッピングする。
証明書ファイルの準備
docker-compose.yaml
と同じディレクトリにtls
という新しいフォルダを作成する。server.pem
、server.key
、ca.pem
をtls
フォルダにコピーする。以下のようなディレクトリ構造に配置します:
├── docker-compose.yml
├── milvus.yaml
└── tls
├── server.pem
├── server.key
└── ca.pem
Docker Composeの設定を更新する
docker-compose.yaml
ファイルを編集し、以下のようにコンテナ内の証明書ファイルパスをマッピングする:
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:latest
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
- ${DOCKER_VOLUME_DIRECTORY:-.}/tls:/milvus/tls
- ${DOCKER_VOLUME_DIRECTORY:-.}/milvus.yaml:/milvus/configs/milvus.yaml
Docker Composeを使用したMilvusのデプロイ
以下のコマンドを実行し、Milvusをデプロイする:
sudo docker compose up -d
Milvus Operatorのセットアップ
作業ディレクトリに証明書ファイルを配置します。ディレクトリ構成は以下のようにします:
├── milvus.yaml (to be created later)
├── server.pem
├── server.key
└── ca.pem
証明書ファイルと一緒にsecretを作成します:
kubectl create secret generic certs --from-file=server.pem --from-file=server.key --from-file=ca.pem
外部TLSを有効にするには、milvus.yaml
ファイルに以下の設定を追加する:
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: my-release
spec:
config:
proxy:
http:
# for now not support config restful on same port with grpc
# so we set to 8080, grpc will still use 19530
port: 8080
common:
security:
tlsMode: 1 # tlsMode for external service 1 for one-way TLS, 2 for Mutual TLS, 0 for disable
tls:
serverPemPath: /certs/server.pem
serverKeyPath: /certs/server.key
caPemPath: /certs/ca.pem
components:
# mount the certs secret to the milvus container
volumes:
- name: certs
secret:
secretName: certs
volumeMounts:
- name: certs
mountPath: /certs
readOnly: true
内部TLSを有効にするには、milvus.yaml
:
internaltls.sni
フィールドを証明書の CommonName に置き換えることを忘れないこと。
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: my-release
spec:
config:
proxy:
http:
# for now not support config restful on same port with grpc
# so we set to 8080, grpc will still use 19530
port: 8080
common:
security:
internaltlsEnabled: true # whether to enable internal tls
# Configure tls certificates path for internal service
internaltls:
serverPemPath: /certs/server.pem
serverKeyPath: /certs/server.key
caPemPath: /certs/ca.pem
sni: localhost # the CommonName in your certificates
components:
# mount the certs secret to the milvus container
volumes:
- name: certs
secret:
secretName: certs
volumeMounts:
- name: certs
mountPath: /certs
readOnly: true
Milvus CRを作成する:
kubectl create -f milvus.yaml
Milvus Helmのセットアップ
証明書ファイルを作業ディレクトリに置く。ディレクトリ構造は以下のようになるはずです:
├── values.yaml (to be created later)
├── server.pem
├── server.key
└── ca.pem
証明書ファイルと一緒にシークレットを作成する:
kubectl create secret generic certs --from-file=server.pem --from-file=server.key --from-file=ca.pem
外部TLSを有効にするには、values.yaml
ファイルに以下の設定を追加する:
extraConfigFiles:
user.yaml: |+
proxy:
http:
# for now not support config restful on same port with grpc
# so we set to 8080, grpc will still use 19530
port: 8080
common:
security:
tlsMode: 1 # tlsMode for external service 1 means set to 2 to enable Mutual TLS
# Configure tls certificates path for external service
tls:
serverPemPath: /certs/server.pem
serverKeyPath: /certs/server.key
caPemPath: /certs/ca.pem
# mount the certs secret to the milvus container
volumes:
- name: certs
secret:
secretName: certs
volumeMounts:
- name: certs
mountPath: /certs
readOnly: true
内部TLSを有効にするには、values.yaml
:
internaltls.sni
フィールドを証明書の CommonName に置き換えることを忘れないこと。
extraConfigFiles:
user.yaml: |+
common:
security:
internaltlsEnabled: true # whether to enable internal tls
# Configure tls certificates path for internal service
internaltls:
serverPemPath: /certs/server.pem
serverKeyPath: /certs/server.key
caPemPath: /certs/ca.pem
sni: localhost
# mount the certs secret to the milvus container
volumes:
- name: certs
secret:
secretName: certs
volumeMounts:
- name: certs
mountPath: /certs
readOnly: true
milvusリリースを作成する:
helm repo add milvus https://zilliztech.github.io/milvus-helm/
helm repo update milvus
helm install my-release milvus/milvus -f values.yaml
内部TLSが有効になっていることを確認する
内部TLSを直接確認するのは難しい。Milvusのログを確認することで、内部TLSが有効になっているかどうかを確認することができます。
Milvusのログでは、内部TLSが有効になっている場合、以下のメッセージが表示されるはずです:
[...date time...] [INFO] [utils/util.go:56] ["Internal TLS Enabled"] [value=true]
TLSでMilvusサーバに接続してください。
SDKとのやり取りには、TLSモードに応じて以下の設定を使用します。
一方向TLS接続
server.pem
へのパスを提供し、server_name
が証明書に設定されたCommonName
と一致することを確認します。
from pymilvus import MilvusClient
client = MilvusClient(
uri="https://localhost:19530",
secure=True,
server_pem_path="path_to/server.pem",
server_name="localhost"
)
双方向TLS接続
client.pem
、client.key
、ca.pem
へのパスを提供し、server_name
が証明書に設定されているCommonName
と一致することを確認する。
from pymilvus import MilvusClient
client = MilvusClient(
uri="https://localhost:19530",
secure=True,
client_pem_path="path_to/client.pem",
client_key_path="path_to/client.key",
ca_pem_path="path_to/ca.pem",
server_name="localhost"
)
詳細はexample_tls1.pyと example_tls2.pyを参照。
Milvus RESTfulサーバへのTLS接続
RESTful APIの場合、curl
コマンドでTLSを確認することができます。
片方向TLS接続
curl --cacert path_to/ca.pem https://localhost:8080/v2/vectordb/collections/list
双方向TLS接続
curl --cert path_to/client.pem --key path_to/client.key --cacert path_to/ca.pem https://localhost:8080/v2/vectordb/collections/list