Encriptação em trânsito

O TLS (Transport Layer Security) é um protocolo de encriptação que garante a segurança das comunicações. O proxy Milvus utiliza a autenticação unidirecional e bidirecional TLS.

Este tópico descreve como ativar o TLS no proxy Milvus para os tráfegos gRPC e RESTful.

O TLS e a autenticação do utilizador são duas abordagens de segurança distintas. Se tiver ativado a autenticação do utilizador e o TLS no seu sistema Milvus, terá de fornecer um nome de utilizador, uma palavra-passe e caminhos de ficheiros de certificados. Para obter informações sobre como ativar a autenticação do utilizador, consulte Autenticar o acesso do utilizador.

Criar seu próprio certificado

Pré-requisitos

Certifique-se de que o OpenSSL esteja instalado. Se não o tiver instalado, compile e instale o OpenSSL primeiro.

openssl version

Se o OpenSSL não estiver instalado. Ele pode ser instalado com o seguinte comando no Ubuntu.

sudo apt install openssl

Criar ficheiros

  1. Crie o ficheiro gen.sh.
mkdir cert && cd cert
touch gen.sh
  1. Copie o seguinte script para o ficheiro gen.sh.

É necessário configurar o CommonName no ficheiro gen.sh. O CommonName refere-se ao nome do servidor que o cliente deve especificar durante a ligação.

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

As variáveis no ficheiro gen.sh são cruciais para o processo de criação de um ficheiro de pedido de assinatura de certificado. As primeiras cinco variáveis são as informações básicas de assinatura, incluindo país, estado, localização, organização e unidade organizacional. É necessário ter cuidado ao configurar o CommonName, pois ele será verificado durante a comunicação cliente-servidor.

Execute gen.sh para gerar o certificado

Execute o ficheiro gen.sh para criar o certificado.

chmod +x gen.sh
./gen.sh

Serão criados os sete ficheiros seguintes: ca.key, ca.pem, ca.srl, server.key, server.pem, client.key, client.pem.

Certifique-se de que mantém os ficheiros ca.key, ca.pem, ca.srl seguros para poder renovar os seus certificados mais tarde. Os ficheiros server.key e server.pem são utilizados pelo servidor e os ficheiros client.key e client.pem são utilizados pelo cliente.

Renovar certificados (opcional)

Se pretender renovar os certificados em alguns casos, por exemplo, se expirarem em breve, pode utilizar o seguinte script.

É necessário ter ca.key, ca.pem, ca.srl no seu diretório de trabalho.

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

Execute o ficheiro renew.sh para criar o certificado.

chmod +x renew.sh
./renew.sh

Configurar um servidor Milvus com TLS

Esta secção descreve os passos para configurar um servidor Milvus com encriptação TLS.

Configuração para o Docker Compose

1. Modificar a configuração do servidor Milvus

Para ativar o TLS externo, adicione as seguintes configurações no ficheiro 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

Parâmetros:

  • serverPemPath: O caminho para o ficheiro de certificado do servidor.
  • serverKeyPath: O caminho para o ficheiro da chave do servidor.
  • caPemPath: O caminho para o ficheiro do certificado da CA.
  • tlsMode: O modo TLS para o serviço externo. Valores válidos:
    • 1: Autenticação unidirecional, em que apenas o servidor requer um certificado e o cliente o verifica. Este modo requer server.pem e server.key do lado do servidor, e server.pem do lado do cliente.
    • 2: Autenticação bidirecional, em que tanto o servidor como o cliente necessitam de certificados para estabelecer uma ligação segura. Este modo requer server.pem, server.key, e ca.pem do lado do servidor, e client.pem, client.key, e ca.pem do lado do cliente.

Para ativar o TLS interno, adicione as seguintes configurações no arquivo milvus.yaml:

internaltls:
  serverPemPath: /milvus/tls/server.pem
  serverKeyPath: /milvus/tls/server.key
  caPemPath: /milvus/tls/ca.pem

common:
  security:
    internaltlsEnabled: true 

Parâmetros:

  • serverPemPath: O caminho para o arquivo de certificado do servidor.
  • serverKeyPath: O caminho para o ficheiro da chave do servidor.
  • caPemPath: O caminho para o ficheiro do certificado da CA.
  • internaltlsEnabled: Se deve ativar o TLS interno. Por enquanto, apenas o tls unidirecional é suportado.

2. Mapear ficheiros de certificado para o contentor

Preparar ficheiros de certificados

Crie uma nova pasta chamada tls no mesmo diretório que o seu docker-compose.yaml. Copie os arquivos server.pem, server.key e ca.pem para a pasta tls. Coloque-os em uma estrutura de diretório como a seguir:

├── docker-compose.yml
├── milvus.yaml
└── tls
     ├── server.pem
     ├── server.key
     └── ca.pem

Atualizar a configuração do Docker Compose

Edite o ficheiro docker-compose.yaml para mapear os caminhos do ficheiro de certificado dentro do contentor, conforme mostrado abaixo:

  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
Implantar o Milvus usando o Docker Compose

Execute o seguinte comando para implantar o Milvus:

sudo docker compose up -d

Configuração para o operador do Milvus

Coloque os ficheiros de certificado no seu diretório de trabalho. A estrutura do diretório deve ser semelhante a esta:

├── milvus.yaml (to be created later)
├── server.pem
├── server.key
└── ca.pem

Crie um segredo com os ficheiros de certificado:

kubectl create secret generic certs --from-file=server.pem --from-file=server.key --from-file=ca.pem

Para ativar o TLS externo, adicione as seguintes configurações no ficheiro 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

Para ativar o TLS interno, adicione as seguintes configurações no arquivo milvus.yaml:

Não se esqueça de substituir o campo internaltls.sni pelo CommonName nos seus certificados.

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

criar o Milvus CR:

kubectl create -f milvus.yaml

configuração para o Milvus Helm

Coloque os ficheiros de certificados no seu diretório de trabalho. A estrutura do diretório deve ter o seguinte aspeto:

├── values.yaml (to be created later)
├── server.pem
├── server.key
└── ca.pem

Crie um segredo com os ficheiros de certificados:

kubectl create secret generic certs --from-file=server.pem --from-file=server.key --from-file=ca.pem

Para ativar o TLS externo, adicione as seguintes configurações no ficheiro 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

Para ativar o TLS interno, adicione as seguintes configurações no arquivo values.yaml:

Não se esqueça de substituir o campo internaltls.sni pelo CommonName nos seus certificados.

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

Criar a versão milvus:

helm repo add milvus https://zilliztech.github.io/milvus-helm/
helm repo update milvus
helm install my-release milvus/milvus -f values.yaml

Verificar se o TLS interno está ativado

É difícil verificar o TLS interno diretamente. Pode verificar o registo do Milvus para ver se o TLS interno está ativado.

No registo do Milvus, deverá ver a seguinte mensagem se o TLS interno estiver ativado:

[...date time...] [INFO] [utils/util.go:56] ["Internal TLS Enabled"] [value=true]

Ligar ao servidor Milvus com TLS

Para interações SDK, utilize as seguintes configurações, dependendo do modo TLS.

Ligação TLS unidirecional

Forneça o caminho para server.pem e certifique-se de que server_name corresponde a CommonName configurado no certificado.

from pymilvus import MilvusClient

client = MilvusClient(
    uri="https://localhost:19530",
    secure=True,
    server_pem_path="path_to/server.pem",
    server_name="localhost"
)

Ligação TLS bidirecional

Forneça os caminhos para client.pem, client.key, e ca.pem, e certifique-se de que server_name corresponde a CommonName configurado no certificado.

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"
)

Consulte example_tls1.py e example_tls2.py para obter mais informações.

Ligar ao servidor Milvus RESTful com TLS

Para APIs RESTful, pode verificar o tls utilizando o comando curl.

Conexão TLS unidirecional

curl --cacert path_to/ca.pem https://localhost:8080/v2/vectordb/collections/list

Ligação TLS bidirecional

curl --cert path_to/client.pem --key path_to/client.key --cacert path_to/ca.pem https://localhost:8080/v2/vectordb/collections/list