Configure a segurança do serviço com o Envoy

Use as instruções neste guia para configurar a autenticação e a autorização para serviços implementados com a Cloud Service Mesh e os proxies Envoy. Para ver informações completas sobre a segurança do serviço Cloud Service Mesh, consulte Segurança do serviço Cloud Service Mesh.

Requisitos

Antes de configurar a segurança do serviço para a Cloud Service Mesh com o Envoy, certifique-se de que a configuração cumpre os seguintes pré-requisitos:

Prepare-se para a configuração

As secções seguintes descrevem as tarefas que tem de concluir antes de configurar o serviço de segurança do Cloud Service Mesh. Estas tarefas são:

  • Atualizar a CLI do Google Cloud
  • Configurar variáveis
  • Ativar as APIs necessárias para o funcionamento da malha de serviços na nuvem com o serviço de autoridade de certificação

Atualize a ferramenta de linha de comandos gcloud

Para atualizar a CLI Google Cloud, execute o seguinte no seu computador local:

gcloud components update

Configure variáveis

Defina as seguintes variáveis para poder copiar e colar código com valores consistentes à medida que trabalha no exemplo neste documento. Use os seguintes valores.

  • PROJECT_ID: substitua o ID do seu projeto.
  • CLUSTER_NAME: substitua o nome do cluster que quer usar, por exemplo, secure-td-cluster.
  • ZONE: substitua a zona onde o cluster está localizado. o cluster está localizado.
  • GKE_CLUSTER_URL: substitua https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
  • WORKLOAD_POOL: substitua PROJECT_ID.svc.id.goog
  • K8S_NAMESPACE: substitua default.
  • DEMO_CLIENT_KSA: substitua o nome da conta de serviço do Kubernetes do cliente.
  • DEMO_SERVER_KSA: substitua o nome da conta de serviço do Kubernetes do seu servidor.
  • PROJNUM: substitua o número do projeto do seu projeto, que pode determinar na Google Cloud consola ou com este comando:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"
    
  • SA_GKE: substitua service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

  • CLUSTER_VERSION: substitua pela versão mais recente disponível. Pode encontrar esta informação nas notas de lançamento do canal rápido. A versão mínima necessária é 1.21.4-gke.1801. Esta é a versão do cluster do GKE a usar neste exemplo.

Defina os valores aqui:

# Substitute your project ID
PROJECT_ID=PROJECT_ID

# GKE cluster name and zone for this example.
CLUSTER_NAME=CLUSTER_NAME
ZONE=ZONE

# GKE cluster URL derived from the above
GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME"

# Workload pool to be used with the GKE cluster
WORKLOAD_POOL="PROJECT_ID.svc.id.goog"

# Kubernetes namespace to run client and server demo.
K8S_NAMESPACE=K8S_NAMESPACE
DEMO_CLIENT_KSA=DEMO_CLIENT_KSA
DEMO_SERVER_KSA=DEMO_SERVER_KSA

# Compute other values
# Project number for your project
PROJNUM=PROJNUM

CLUSTER_VERSION=CLUSTER_VERSION
SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

Ative as APIs

Use o comando gcloud services enable para ativar todas as APIs de que precisa para configurar a segurança da Cloud Service Mesh com o Certificate Authority Service.

gcloud services enable \
   container.googleapis.com \
   cloudresourcemanager.googleapis.com \
   compute.googleapis.com \
   trafficdirector.googleapis.com \
   networkservices.googleapis.com \
   networksecurity.googleapis.com \
   privateca.googleapis.com \
   gkehub.googleapis.com

Crie ou atualize um cluster do GKE

A segurança do serviço Cloud Service Mesh depende da integração do serviço de AC com o GKE. O cluster do GKE tem de cumprir os seguintes requisitos, além dos requisitos de configuração:

  • Use uma versão mínima do cluster de 1.21.4-gke.1801. Se precisar de funcionalidades que estão numa versão posterior, pode obter essa versão no canal de lançamento rápido.
  • O cluster do GKE tem de estar ativado e configurado com certificados de malha, conforme descrito no artigo Criar autoridades de certificação para emitir certificados.
  1. Crie um novo cluster que use a Workload Identity Federation para o GKE. Se estiver a atualizar um cluster existente, avance para o passo seguinte. O valor que indica para --tags tem de corresponder ao nome transmitido ao parâmetro --target-tags para o comando firewall-rules create na secção Configurar a malha de serviços na nuvem com componentes do Cloud Load Balancing.

    # Create a GKE cluster with GKE managed mesh certificates.
    gcloud container clusters create CLUSTER_NAME \
      --release-channel=rapid \
      --scopes=cloud-platform \
      --image-type=cos_containerd \
      --machine-type=e2-standard-2 \
      --zone=ZONE \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --enable-mesh-certificates \
      --cluster-version=CLUSTER_VERSION \
      --enable-ip-alias \
      --tags=allow-health-checks \
      --workload-metadata=GKE_METADATA
    

    A criação do cluster pode demorar vários minutos.

  2. Se estiver a usar um cluster existente, ative a Workload Identity Federation para o GKE e os certificados de malha do GKE. Certifique-se de que o cluster foi criado com a flag --enable-ip-alias, que não pode ser usada com o comando update.

    gcloud container clusters update CLUSTER_NAME \
      --enable-mesh-certificates
    
  3. Execute o seguinte comando para mudar para o novo cluster como cluster predefinido para os seus comandos kubectl:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --zone ZONE
    

Implementação num ambiente de vários clusters

Se estiver a implementar num ambiente com vários clusters, siga o procedimento geral descrito nesta secção. Estas instruções pressupõem que os pods de cliente estão a ser executados num cluster e os pods de servidor estão a ser executados no outro cluster.

  1. Crie ou atualize os clusters através das instruções na secção anterior.

  2. Capture os intervalos de endereços IP dos pods para cada cluster através do seguinte comando:

    gcloud compute firewall-rules list \
      --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \
      --format="value(sourceRanges)"
    

    Por exemplo, para clusters denominados cluster-a e cluster-b, os comandos devolvem resultados como os seguintes:

    cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node
    cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
    
  3. Crie regras de firewall da VPC que permitam que os clusters comuniquem entre si. Por exemplo, o comando seguinte cria uma regra de firewall que permite que os endereços IP dos pods cluster-a comuniquem com os nós cluster-b:

    gcloud compute firewall-rules create per-cluster-a-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-b-acd14479-node"
    

    O comando seguinte cria uma regra de firewall que permite que os endereços IP dos cluster-bpods comuniquem com os nós cluster-a:

    gcloud compute firewall-rules create per-cluster-b-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-a-9cd18751-node"
    

Registe clusters numa frota

Registe o cluster que criou ou atualizou em Criar um cluster do GKE com uma frota. O registo do cluster facilita a configuração de clusters em vários projetos.

Tenha em atenção que cada um destes passos pode demorar até dez minutos a ser concluído.

  1. Registe o seu cluster na frota:

    gcloud container fleet memberships register CLUSTER_NAME \
      --gke-cluster=ZONE/CLUSTER_NAME \
      --enable-workload-identity --install-connect-agent \
      --manifest-output-file=MANIFEST-FILE_NAME
    

    Substitua as variáveis da seguinte forma:

    • CLUSTER_NAME: o nome do cluster.
    • ZONE: a zona do seu cluster.
    • MANIFEST-FILE_NAME: o caminho onde estes comandos geram o manifesto para registo.

    Quando o processo de registo é bem-sucedido, é apresentada uma mensagem como a seguinte:

    Finished registering the cluster CLUSTER_NAME with the fleet.
  2. Aplique o ficheiro de manifesto gerado ao cluster:

    kubectl apply -f MANIFEST-FILE_NAME
    

    Quando o processo de candidatura é bem-sucedido, vê mensagens como as seguintes:

    namespace/gke-connect created
    serviceaccount/connect-agent-sa created
    podsecuritypolicy.policy/gkeconnect-psp created
    role.rbac.authorization.k8s.io/gkeconnect-psp:role created
    rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created
    role.rbac.authorization.k8s.io/agent-updater created
    rolebinding.rbac.authorization.k8s.io/agent-updater created
    role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created
    rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    role.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    secret/http-proxy created
    deployment.apps/gke-connect-agent-20210416-01-00 created
    service/gke-connect-monitoring created
    secret/creds-gcp create
    
  3. Obtenha o recurso de subscrição do cluster:

    kubectl get memberships membership -o yaml
    

    O resultado deve incluir o Workload Identity Pool atribuído pela frota, onde PROJECT_ID é o ID do seu projeto:

    workload_identity_pool: PROJECT_ID.svc.id.goog
    

    Isto significa que o cluster foi registado com êxito.

Crie autoridades de certificação para emitir certificados

Para emitir certificados para os seus pods, crie um conjunto do serviço de AC e as seguintes autoridades de certificação (ACs):

  • CA de raiz. Esta é a raiz de fidedignidade para todos os certificados de malha emitidos. Pode usar uma AC raiz existente, se tiver uma. Crie a CA de raiz no nível enterprise, que se destina à emissão de certificados de longa duração e baixo volume.
  • CA subordinado. Esta AC emite certificados para cargas de trabalho. Crie a AC subordinada na região onde o cluster está implementado. Crie a AC subordinada no nível devops, que se destina à emissão de certificados de curta duração e em grande volume.

A criação de uma CA subordinada é opcional, mas recomendamos vivamente que crie uma, em vez de usar a CA de raiz para emitir certificados da malha do GKE. Se decidir usar a AC de raiz para emitir certificados de malha, certifique-se de que o modo de emissão baseado na configuração predefinido continua a ser permitido.

A AC subordinada pode estar numa região diferente do seu cluster, mas recomendamos vivamente que a crie na mesma região que o cluster para otimizar o desempenho. No entanto, pode criar as ACs raiz e subordinadas em diferentes regiões sem qualquer impacto no desempenho ou na disponibilidade.

Estas regiões são suportadas para o serviço de AC:

Nome da região Descrição da região
asia-east1 Taiwan
asia-east2 Hong Kong
asia-northeast1 Tóquio
asia-northeast2 Osaca
asia-northeast3 Seul
asia-south1 Mumbai
asia-south2 Deli
asia-southeast1 Singapura
asia-southeast2 Jacarta
australia-southeast1 Sydney
australia-southeast2 Melbourne
europe-central2 Varsóvia
europe-north1 Finlândia
europe-southwest1 Madrid
europe-west1 Bélgica
europe-west2 Londres
europe-west3 Frankfurt
europe-west4 Países Baixos
europe-west6 Zurique
europe-west8 Milão
europe-west9 Paris
europe-west10 Berlim
europe-west12 Turim
me-central1 Doha
me-central2 Damã
me-west1 Telavive
northamerica-northeast1 Montréal
northamerica-northeast2 Toronto
southamerica-east1 São Paulo
southamerica-west1 Santiago
us-central1 Iowa
us-east1 Carolina do Sul
us-east4 Virgínia do Norte
us-east5 Columbus
us-south1 Dallas
us-west1 Oregon
us-west2 Los Angeles
us-west3 Salt Lake City
us-west4 Las Vegas

Também pode verificar a lista de localizações suportadas executando o seguinte comando:

gcloud privateca locations list
  1. Conceda o IAM roles/privateca.caManager a indivíduos que criam um conjunto de ACs e uma AC. Tenha em atenção que, para MEMBER, o formato correto é user:userid@example.com. Se essa pessoa for o utilizador atual, pode obter o ID do utilizador atual com o comando de shell $(gcloud auth list --filter=status:ACTIVE --format="value(account)").

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.caManager
    
  2. Conceda a função role/privateca.admin para o serviço de AC a indivíduos que precisam de modificar as políticas de IAM, em que MEMBER é um indivíduo que precisa deste acesso, especificamente, todos os indivíduos que executam os passos que se seguem e que concedem as funções privateca.auditor e privateca.certificateManager:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.admin
    
  3. Crie o pool do serviço de AC de raiz.

    gcloud privateca pools create ROOT_CA_POOL_NAME \
      --location ROOT_CA_POOL_LOCATION \
      --tier enterprise
    
  4. Crie uma AC de raiz.

    gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \
      --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \
      --key-algorithm="ec-p256-sha256" \
      --max-chain-length=1 \
      --location ROOT_CA_POOL_LOCATION
    

    Para esta configuração de demonstração, use os seguintes valores para as variáveis:

    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_NAME=pkcs2-ca
    • ROOT_CA_POOL_LOCATION=us-east1
    • ROOT_CA_ORGANIZATION="TestCorpLLC"
  5. Crie o grupo subordinado e a CA subordinada. Certifique-se de que o modo de emissão baseado na configuração predefinido permanece permitido.

    gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --tier devops
    
    gcloud privateca subordinates create SUBORDINATE_CA_NAME \
      --pool SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --issuer-pool ROOT_CA_POOL_NAME \
      --issuer-location ROOT_CA_POOL_LOCATION \
      --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \
      --key-algorithm "ec-p256-sha256" \
      --use-preset-profile subordinate_mtls_pathlen_0
    

    Para esta configuração de demonstração, use os seguintes valores para as variáveis:

    • SUBORDINATE_CA_POOL_NAME="td-ca-pool"
    • SUBORDINATE_CA_POOL_LOCATION=us-east1
    • SUBORDINATE_CA_NAME="td-ca"
    • SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_POOL_LOCATION=us-east1
  6. Conceda a função privateca.auditor do IAM ao conjunto de ACs raiz para permitir o acesso a partir da conta de serviço do GKE:

    gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \
     --location ROOT_CA_POOL_LOCATION \
     --role roles/privateca.auditor \
     --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  7. Conceda a função de IAM privateca.certificateManager para o conjunto de ACs subordinado para permitir o acesso a partir da conta de serviço do GKE:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --role roles/privateca.certificateManager \
      --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  8. Guarde a seguinte configuração YAML para indicar ao cluster como emitir certificados de malha:WorkloadCertificateConfig

    apiVersion: security.cloud.google.com/v1
    kind: WorkloadCertificateConfig
    metadata:
      name: default
    spec:
      # Required. The CA service that issues your certificates.
      certificateAuthorityConfig:
        certificateAuthorityServiceConfig:
          endpointURI: ISSUING_CA_POOL_URI
    
      # Required. The key algorithm to use. Choice of RSA or ECDSA.
      #
      # To maximize compatibility with various TLS stacks, your workloads
      # should use keys of the same family as your root and subordinate CAs.
      #
      # To use RSA, specify configuration such as:
      #   keyAlgorithm:
      #     rsa:
      #       modulusSize: 4096
      #
      # Currently, the only supported ECDSA curves are "P256" and "P384", and the only
      # supported RSA modulus sizes are 2048, 3072 and 4096.
      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
      # Optional. Validity duration of issued certificates, in seconds.
      #
      # Defaults to 86400 (1 day) if not specified.
      validityDurationSeconds: 86400
    
      # Optional. Try to start rotating the certificate once this
      # percentage of validityDurationSeconds is remaining.
      #
      # Defaults to 50 if not specified.
      rotationWindowPercentage: 50
    
    

    Substitua o seguinte:

    • O ID do projeto no qual o cluster é executado:
      PROJECT_ID
    • O URI totalmente qualificado da CA que emite os certificados da malha (ISSUING_CA_POOL_URI). Pode ser a sua CA subordinada (recomendado) ou a sua CA de raiz. O formato é:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
  9. Guarde a seguinte configuração YAML TrustConfig para indicar ao cluster como confiar nos certificados emitidos:

    apiVersion: security.cloud.google.com/v1
    kind: TrustConfig
    metadata:
      name: default
    spec:
      # You must include a trustStores entry for the trust domain that
      # your cluster is enrolled in.
      trustStores:
      - trustDomain: PROJECT_ID.svc.id.goog
        # Trust identities in this trustDomain if they appear in a certificate
        # that chains up to this root CA.
        trustAnchors:
        - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
    

    Substitua o seguinte:

    • O ID do projeto no qual o cluster é executado:
      PROJECT_ID
    • O URI totalmente qualificado do conjunto de ACs de raiz (ROOT_CA_POOL_URI). O formato é:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
  10. Aplique as configurações ao cluster:

    kubectl apply -f WorkloadCertificateConfig.yaml
    kubectl apply -f TrustConfig.yaml
    

Configure a gestão de identidade e de acesso

Para criar os recursos necessários para a configuração, tem de ter a função de compute.NetworkAdmin. Esta função contém todas as autorizações necessárias para criar, atualizar, eliminar, listar e usar (ou seja, referenciar esta função noutros recursos) os recursos necessários. Se for o proprietário-editor do seu projeto, tem automaticamente esta função.

Tenha em atenção que o networksecurity.googleapis.com.clientTlsPolicies.use e o networksecurity.googleapis.com.serverTlsPolicies.use não são aplicados quando faz referência a estes recursos no serviço de back-end.

Se estas autorizações forem aplicadas no futuro e estiver a usar a função compute.NetworkAdmin, não vai notar problemas quando esta verificação for aplicada.

Se estiver a usar funções personalizadas e esta verificação for aplicada no futuro, tem de se certificar de que inclui a autorização .use respetiva. Caso contrário, no futuro, pode descobrir que a sua função personalizada não tem as autorizações necessárias para fazer referência a clientTlsPolicy ou serverTlsPolicy a partir do serviço de back-end ou da política de ponto final.

As instruções seguintes permitem que a conta de serviço predefinida aceda à API Cloud Service Mesh Security e crie as contas de serviço do Kubernetes.

  1. Configure o IAM para permitir que a conta de serviço predefinida aceda à API Cloud Service Mesh Security.

    GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
       --filter='displayName:Compute Engine default service account')
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:${GSA_EMAIL} \
      --role roles/trafficdirector.client
    
  2. Configure contas de serviço do Kubernetes. As implementações do cliente e do servidor nas secções seguintes usam os nomes K das contas de serviço do cliente e do servidor do Kubernetes.

    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA
    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
    
  3. Permita que as contas de serviço do Kubernetes se façam passar pela conta de serviço predefinida do Compute Engine criando uma associação de políticas da IAM entre as duas. Esta associação permite que a conta de serviço do Kubernetes atue como a conta de serviço predefinida do Compute Engine.

    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL}
    
    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser  \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
    
  4. Anotar as contas de serviço do Kubernetes para as associar à conta de serviço do Compute Engine predefinida.

    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_SERVER_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    
    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_CLIENT_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    

Configure o Cloud Service Mesh

Siga as instruções que se seguem para instalar o injetor de sidecar, configurar um serviço de teste e concluir outras tarefas de implementação.

Instale o injetor de sidecar do Envoy no cluster

Use as instruções nas duas secções seguintes da configuração do Cloud Service Mesh para pods do GKE com injeção automática do Envoy para implementar e ativar a injeção do sidecar do Envoy no seu cluster:

Certifique-se de que conclui ambos os conjuntos de instruções antes de configurar um serviço de teste.

Configure um serviço de teste

Depois de instalar o injetor de sidecar do Envoy, use estas instruções para configurar um serviço de teste para a sua implementação.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml

kubectl apply -f service_sample.yaml

O ficheiro service_sample.yaml contém o podspec da sua aplicação de servidor de demonstração. Existem algumas anotações específicas da segurança do Cloud Service Mesh.

Metadados do proxy do Cloud Service Mesh

O podspec especifica a anotação proxyMetadata:

spec:
...
      annotations:
        cloud.google.com/proxyMetadata: '{"app": "payments"}'
...

Quando o pod é inicializado, o proxy sidecar seleciona esta anotação e transmite-a ao Cloud Service Mesh. Em seguida, o Cloud Service Mesh pode usar estas informações para enviar de volta a configuração filtrada:

  • Mais adiante neste guia, tenha em atenção que a política de pontos finais especifica um correspondente de pontos finais.
  • O matcher de pontos finais especifica que apenas os clientes que apresentam uma etiqueta com o nome app e o valor payments recebem a configuração filtrada.

Use certificados e chaves de malha assinados pelo serviço de AC

O podspec especifica a anotação enableManagedCerts:

spec:
...
      annotations:
        ...
        cloud.google.com/enableManagedCerts: "true"
...

Quando o pod é inicializado, os certificados e as chaves assinados pelo serviço de AC são montados automaticamente no sistema de ficheiros do proxy sidecar local.

Configurar a porta de interceção de tráfego de entrada

O podspec especifica a anotação includeInboundPorts:

spec:
...
      annotations:
        ...
        cloud.google.com/includeInboundPorts: "8000"
...

Esta é a porta na qual a sua aplicação de servidor escuta as ligações. Quando o pod é inicializado, o proxy sidecar seleciona esta anotação e transmite-a para o Cloud Service Mesh. Em seguida, a Cloud Service Mesh pode usar estas informações para enviar uma configuração filtrada que interceta todo o tráfego recebido para esta porta e pode aplicar políticas de segurança na mesma.

A porta de verificação do estado tem de ser diferente da porta da aplicação. Caso contrário, as mesmas políticas de segurança aplicam-se às ligações recebidas à porta de verificação de estado, o que pode levar à recusa das ligações e, consequentemente, à marcação incorreta do servidor como não saudável.

Configure serviços do GKE com NEGs

Os serviços do GKE têm de ser expostos através de grupos de pontos finais de rede (NEGs) para que os possa configurar como back-ends de um serviço de back-end do Cloud Service Mesh. O pacote service_sample.yaml fornecido com este guia de configuração usa o nome do NEG service-test-neg na seguinte anotação:

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

Não precisa de alterar o ficheiro service_sample.yaml.

Guarde o nome do NEG

Guarde o nome do GNE na variável NEG_NAME:

NEG_NAME="service-test-neg"

Implemente uma aplicação cliente no GKE

Execute o seguinte comando para iniciar um cliente de demonstração com um proxy Envoy como sidecar, que precisa para demonstrar as funcionalidades de segurança.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml

kubectl apply -f client_sample.yaml

O podspec do cliente inclui apenas a anotação enableManagedCerts. Isto é necessário para montar os volumes necessários para os certificados e as chaves da malha gerida do GKE, que são assinados pela instância do serviço de AC.

Configure recursos de verificação de estado, regras de firewall e serviços de back-end

Nesta secção, cria recursos de verificação de funcionamento, regra da firewall e serviço de back-end para a Cloud Service Mesh.

  1. Crie a verificação de funcionamento.

    gcloud compute health-checks create http td-gke-health-check \
      --use-serving-port
    
  2. Crie a regra de firewall para permitir os intervalos de endereços IP do verificador de funcionamento.

    gcloud compute firewall-rules create fw-allow-health-checks \
       --action ALLOW \
       --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --rules tcp
    
  3. Crie o serviço de back-end e associe a verificação de funcionamento ao serviço de back-end.

    gcloud compute backend-services create td-gke-service \
      --global \
      --health-checks td-gke-health-check \
      --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  4. Adicione o NEG criado anteriormente como back-end ao serviço de back-end.

    gcloud compute backend-services add-backend td-gke-service \
      --global \
      --network-endpoint-group ${NEG_NAME} \
      --network-endpoint-group-zone ZONE \
      --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

Configure recursos Mesh e HTTPRoute

Nesta secção, cria recursos Mesh e HTTPRoute.

  1. Crie a especificação do recurso Mesh e guarde-a num ficheiro denominado mesh.yaml.

    name: sidecar-mesh
    interceptionPort: 15001
    

    A porta de interceção é predefinida como 15001 se não a especificar no ficheiro mesh.yaml.

  2. Crie o recurso Mesh com a especificação mesh.yaml.

    gcloud network-services meshes import sidecar-mesh \
      --source=mesh.yaml \
      --location=global
    
  3. Crie a especificação HTTPRoute e guarde-a num ficheiro denominado http_route.yaml.

    Pode usar o PROJECT_ID ou o PROJECT_NUMBER.

    name: helloworld-http-route
    hostnames:
    - service-test
    meshes:
    - projects/PROJNUM/locations/global/meshes/sidecar-mesh
    rules:
    - action:
       destinations:
       - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
    
  4. Crie o recurso HTTPRoute com base na especificação no ficheiro http_route.yaml.

    gcloud network-services http-routes import helloworld-http-route \
      --source=http_route.yaml \
      --location=global
    

A configuração da Cloud Service Mesh está concluída e já pode configurar políticas de autenticação e autorização.

Configure a segurança de serviço a serviço

Use as instruções nas secções seguintes para configurar a segurança de serviço a serviço.

Ative o mTLS na malha

Para configurar o mTLS na sua malha, tem de proteger o tráfego de saída para o serviço de back-end e proteger o tráfego de entrada para o ponto final.

Formato para referências de políticas

Tenha em atenção o seguinte formato necessário para fazer referência ao TLS do servidor, ao TLS do cliente e às políticas de autorização:

projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]

Por exemplo:

projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy

Proteja o tráfego de saída para o serviço de back-end

Para proteger o tráfego de saída, primeiro, crie uma política de TLS de cliente que faça o seguinte:

  • Usa google_cloud_private_spiffe como o plug-in para clientCertificate, que programa o Envoy para usar certificados de malha geridos pelo GKE como a identidade do cliente.
  • Usa o google_cloud_private_spiffe como o plug-in para o serverValidationCa que programa o Envoy para usar certificados de malha geridos pelo GKE para a validação do servidor.

Em seguida, anexe a política TLS do cliente ao serviço de back-end. Isto faz o seguinte:

  • Aplica a política de autenticação da política TLS do cliente a ligações de saída a pontos finais do serviço de back-end.
  • Os SANs (nomes alternativos de entidades) indicam ao cliente que afirme a identidade exata do servidor ao qual está a estabelecer ligação.
  1. Crie a política TLS do cliente num ficheiro client-mtls-policy.yaml:

    name: "client-mtls-policy"
    clientCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importe a política de TLS do cliente:

    gcloud network-security client-tls-policies import client-mtls-policy \
        --source=client-mtls-policy.yaml --location=global
    
  3. Anexe a política de TLS do cliente ao serviço de back-end. Isto aplica a autenticação mTLS a todos os pedidos de saída do cliente para este serviço de back-end.

    gcloud compute backend-services export td-gke-service \
        --global --destination=demo-backend-service.yaml
    

    Anexe as seguintes linhas a demo-backend-service.yaml:

    securitySettings:
      clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
      subjectAltNames:
        - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
    
  4. Importe os valores:

    gcloud compute backend-services import td-gke-service \
        --global --source=demo-backend-service.yaml
    
  5. Opcionalmente, execute o seguinte comando para verificar se o pedido falha. Esta é uma falha esperada, porque o cliente espera certificados do ponto final, mas o ponto final não está programado com uma política de segurança.

    # Get the name of the Podrunning Busybox.
    BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # Command to execute that tests connectivity to the service service-test.
    TEST_CMD="wget -q -O - service-test; echo"
    
    # Execute the test command on the pod.
    kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
    

    Vê um resultado como este:

    wget: server returned error: HTTP/1.1 503 Service Unavailable
    

Proteja o tráfego recebido para o ponto final

Para proteger o tráfego recebido, primeiro, crie uma política de TLS do servidor que faça o seguinte:

  • Usa google_cloud_private_spiffe como o plug-in para serverCertificate, que programa o Envoy para usar certificados de malha geridos pelo GKE como a identidade do servidor.
  • Usa google_cloud_private_spiffe como o plug-in para clientValidationCa, que programa o Envoy para usar certificados de malha geridos pelo GKE para validação do cliente.
  1. Guarde os valores da política TLS do servidor num ficheiro denominado server-mtls-policy.yaml.

    name: "server-mtls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    mtlsPolicy:
      clientValidationCa:
      - certificateProviderInstance:
          pluginInstance: google_cloud_private_spiffe
    
  2. Crie a política TLS do servidor:

    gcloud network-security server-tls-policies import server-mtls-policy \
        --source=server-mtls-policy.yaml --location=global
    
  3. Crie um ficheiro denominado ep_mtls.yaml que contenha o correspondente do ponto final e anexe a política de TLS do servidor.

    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: MATCH_ALL
        metadataLabels:
        - labelName: app
          labelValue: payments
    name: "ep"
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy
    type: SIDECAR_PROXY
    
  4. Importe o correspondente de pontos finais.

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Valide a configuração

Execute o seguinte comando curl. Se o pedido for concluído com êxito, é apresentado x-forwarded-client-cert no resultado. O cabeçalho é impresso apenas quando a ligação é uma ligação mTLS.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

Vê um resultado como o seguinte:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: 10.48.0.6
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Tenha em atenção que o cabeçalho x-forwarded-client-cert é inserido pelo Envoy do lado do servidor e contém a sua própria identidade (servidor) e a identidade do cliente de origem. Como vemos as identidades do cliente e do servidor, isto é um sinal de uma ligação mTLS.

Configure o acesso ao nível do serviço com uma política de autorização

Estas instruções criam uma política de autorização que permite pedidos enviados pela conta DEMO_CLIENT_KSA na qual o nome do anfitrião é service-test, a porta é 8000 e o método HTTP é GET. Antes de criar políticas de autorização, leia o aviso em Restrinja o acesso através da autorização.

  1. Crie uma política de autorização criando um ficheiro denominado authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        ports:
        - 8000
        methods:
        - GET
    
  2. Importe a política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    
  3. Atualize a política de ponto final para fazer referência à nova política de autorização anexando o seguinte ao ficheiro ep_mtls.yaml:

    authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
    

    A política de pontos finais especifica agora que o mTLS e a política de autorização têm de ser aplicados em pedidos recebidos a pods cujos proxies sidecar do Envoy apresentem a etiqueta app:payments.

  4. Importe a política:

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Valide a configuração

Execute os seguintes comandos para validar a configuração.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

O resultado esperado é semelhante a este:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: redacted
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Execute os seguintes comandos para testar se a política de autorização está a recusar corretamente pedidos inválidos:

# Failure case
# Command to execute that tests connectivity to the service service-test.
# This is an invalid request and server will reject because the server
# authorization policy only allows GET requests.
TEST_CMD="wget -q -O - service-test --post-data='' ; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

O resultado esperado é semelhante a este:

<RBAC: access denied HTTP/1.1 403 Forbidden>

Configure a segurança do gateway de entrada

Esta secção pressupõe que concluiu a secção de segurança de serviço a serviço, incluindo a configuração do cluster do GKE com o injetor automático de sidecar, a criação de uma autoridade de certificação e a criação de uma política de ponto final.

Nesta secção, implementa um proxy Envoy como um gateway de entrada que termina as ligações TLS e autoriza pedidos de clientes internos de um cluster.

Terminar TLS num gateway de entrada (clique para aumentar)
Terminar TLS num gateway de entrada (clique para aumentar)

Para configurar um gateway de entrada para terminar o TLS, faça o seguinte:

  1. Implemente um serviço do Kubernetes acessível através de um endereço IP interno do cluster.
    1. A implementação consiste num proxy Envoy autónomo que é exposto como um serviço do Kubernetes e se liga à Cloud Service Mesh.
  2. Crie uma política de TLS do servidor para terminar o TLS.
  3. Crie uma política de autorização para autorizar pedidos recebidos.

Implemente um serviço de gateway de entrada no GKE

Execute o seguinte comando para implementar o serviço de gateway de entrada no GKE:

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml

kubectl apply -f gateway_sample.yaml

O ficheiro gateway_sample.yaml é a especificação do gateway de entrada. As secções seguintes descrevem algumas adições à especificação.

Desativar a injeção de sidecar do Cloud Service Mesh

A especificação gateway_sample.yaml implementa um proxy Envoy como o único contentor. Nos passos anteriores, o Envoy foi injetado como um sidecar num contentor de aplicação. Para evitar que vários Envoys processem pedidos, pode desativar a injeção de sidecar para este serviço do Kubernetes através da seguinte declaração:

sidecar.istio.io/inject: "false"

Monte o volume correto

A especificação gateway_sample.yaml monta o volume gke-workload-certificates. Este volume também é usado na implementação de sidecar, mas é adicionado automaticamente pelo injetor de sidecar quando vê a anotação cloud.google.com/enableManagedCerts: "true". O gke-workload-certificatesvolume contém os certificados e as chaves SPIFFE geridos pelo GKE que são assinados pela instância do serviço de AC que configurou.

Defina o endereço IP interno do cluster

Configure o gateway de entrada com um serviço do tipo ClusterInternal. Isto cria um nome de anfitrião DNS resolvível internamente para mesh-gateway. Quando um cliente envia um pedido para mesh-gateway:443, o Kubernetes encaminha imediatamente o pedido para a porta da implementação do gateway de entrada do Envoy 8080.

Ative o TLS num gateway de entrada

Siga estas instruções para ativar o TLS num gateway de entrada.

  1. Crie um recurso de política TLS do servidor para terminar ligações TLS com os valores num ficheiro denominado server-tls-policy.yaml:

    description: tls server policy
    name: server-tls-policy
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importe a política TLS do servidor:

    gcloud network-security server-tls-policies import server-tls-policy \
        --source=server-tls-policy.yaml --location=global
    
  3. Crie um novo destino Gateway e guarde-o no ficheiro td-gke-gateway.yaml. Isto anexa a política TLS do servidor e configura o gateway de entrada do proxy Envoy para terminar o tráfego TLS recebido.

    name: td-gke-gateway
    scope: gateway-proxy
    ports:
    - 8080
    type: OPEN_MESH
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
    
  4. Importe o gateway:

    gcloud network-services gateways import td-gke-gateway \
      --source=td-gke-gateway.yaml \
      --location=global
    
  5. Crie e guarde um novo HTTPRoute denominado td-gke-route que faça referência ao gateway e encaminhe todos os pedidos para td-gke-service.

    name: td-gke-route
    hostnames:
    - mesh-gateway
    gateways:
    - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway
    rules:
    - action:
        destinations:
        - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"
    
  6. Importe o HTTPRoute:

    gcloud network-services http-routes import td-gke-route \
      --source=td-gke-route.yaml \
      --location=global
    
    
  7. Opcionalmente, atualize a política de autorização nos back-ends para permitir pedidos quando todas as seguintes condições forem cumpridas:

    • Pedidos enviados por DEMO_CLIENT_KSA. (A implementação do gateway de entrada usa a conta de serviço DEMO_CLIENT_KSA.)
    • Pedidos com anfitrião mesh-gateway ou service-test
    • Porta: 8000

    Não precisa de executar estes comandos, a menos que tenha configurado uma política de autorização para os seus back-ends. Se não existir uma política de autorização no ponto final ou não contiver uma correspondência de anfitrião ou principal de origem na política de autorização, os pedidos são permitidos sem este passo. Adicione estes valores a authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        - mesh-gateway
        ports:
        - 8000
        methods:
        - GET
    
  8. Importe a política:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    

Valide a implementação do gateway de entrada

Usa um novo contentor denominado debug para enviar pedidos para o gateway de entrada para validar a implementação.

Na especificação seguinte, a anotação "sidecar.istio.io/inject":"false" impede que o injetor de sidecar do Cloud Service Mesh injete automaticamente um proxy sidecar. Não existe nenhum sidecar para ajudar o contentor debug no encaminhamento de pedidos. O contentor tem de se ligar ao gateway de entrada para o encaminhamento.

A especificação inclui a flag --no-check-certificate, que ignora a validação do certificado do servidor. O contentor debug não tem os certificados de validação da autoridade de certificação necessários para validar os certificados assinados pelo serviço de AC que são usados pela gateway de entrada para terminar o TLS.

Num ambiente de produção, recomendamos que transfira o certificado de validação do serviço de AC e o monte ou instale no seu cliente. Depois de instalar o certificado de validação, remova a opção --no-check-certificate do comando wget.

Execute o seguinte comando:

kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"

Vê um resultado semelhante a este:

GET / HTTP/1.1
Host: 10.68.7.132
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-envoy-expected-rq-timeout-ms: 15000
x-envoy-internal: true
x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef
x-forwarded-for: 10.64.0.53
x-forwarded-proto: https
content-length: 0
user-agent: Wget

Execute o seguinte comando de teste negativo:

# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"

Vê um resultado semelhante ao seguinte:

wget: error getting response: Connection reset by peer

Execute o seguinte comando de teste negativo:

# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"

Vê um resultado semelhante ao seguinte:

HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden

Elimine a implementação

Opcionalmente, pode executar estes comandos para eliminar a implementação que criou através deste guia.

Para eliminar o cluster, execute este comando:

gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet

Para eliminar os recursos que criou, execute estes comandos:

gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
    --location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
   --location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
    --location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
    --location=global --quiet

Limitações

A segurança do serviço Cloud Service Mesh só é suportada com o GKE. Não pode implementar a segurança de serviços com o Compute Engine.

Resolução de problemas

Esta secção contém informações sobre como corrigir problemas que encontrar durante a configuração do serviço de segurança.

Falhas de ligação

Se a ligação falhar com um erro upstream connect ou disconnect/reset before headers, examine os registos do Envoy, onde pode ver uma das seguintes mensagens de registo:

gRPC config stream closed: 5, Requested entity was not found

gRPC config stream closed: 2, no credential token is found

Se vir estes erros no registo do Envoy, é provável que o token da conta de serviço esteja montado incorretamente ou esteja a usar um audience diferente, ou ambos.

Para mais informações, consulte o artigo As mensagens de erro nos registos do Envoy indicam um problema de configuração.

Pods não criados

Para resolver este problema, consulte o artigo Resolução de problemas de implementações automáticas para pods do GKE.

O Envoy não está a autenticar com o Cloud Service Mesh

Quando o Envoy (envoy-proxy) se liga ao Cloud Service Mesh para obter a configuração xDS, usa a federação de identidade da carga de trabalho para o GKE e a conta de serviço predefinida da VM do Compute Engine (a menos que o arranque tenha sido alterado). Se a autenticação falhar, o Envoy não entra no estado pronto.

Não é possível criar um cluster com --workload-identity-certificate-authority flag

Se vir este erro, certifique-se de que está a executar a versão mais recente da CLI Google Cloud:

gcloud components update

Os agrupamentos permanecem num estado pendente

Se os pods permanecerem num estado pendente durante o processo de configuração, aumente os recursos de CPU e memória para os pods na especificação de implementação.

Não é possível criar o cluster com a flag --enable-mesh-certificates

Certifique-se de que está a executar a versão mais recente da CLI gcloud:

gcloud components update

Tenha em atenção que a flag --enable-mesh-certificates só funciona com gcloud beta.

Os pods não são iniciados

Os pods que usam certificados da malha do GKE podem não ser iniciados se o aprovisionamento de certificados falhar. Isto pode acontecer em situações como as seguintes:

  • O WorkloadCertificateConfig ou o TrustConfig está configurado incorretamente ou em falta.
  • Os CSRs não estão a ser aprovados.

Pode verificar se o aprovisionamento de certificados está a falhar verificando os eventos do pod.

  1. Verifique o estado do seu Pod:

    kubectl get pod -n POD_NAMESPACE POD_NAME
    

    Substitua o seguinte:

    • POD_NAMESPACE: o espaço de nomes do seu Pod.
    • POD_NAME: o nome do seu Pod.
  2. Verifique os eventos recentes do seu Pod:

    kubectl describe pod -n POD_NAMESPACE POD_NAME
    
  3. Se o aprovisionamento de certificados estiver a falhar, é apresentado um evento com Type=Warning, Reason=FailedMount, From=kubelet e um campo Message que começa com MountVolume.SetUp failed for volume "gke-workload-certificates". O campo Message contém informações de resolução de problemas.

    Events:
      Type     Reason       Age                From       Message
      ----     ------       ----               ----       -------
      Warning  FailedMount  13s (x7 over 46s)  kubelet    MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
    
  4. Consulte os seguintes passos de resolução de problemas se os seus Pods não iniciarem devido a objetos configurados incorretamente ou a CSRs rejeitados.

WorkloadCertificateConfig ou TrustConfig está configurado incorretamente

Certifique-se de que criou os objetos WorkloadCertificateConfig e TrustConfig corretamente. Pode diagnosticar configurações incorretas em qualquer um destes objetos através do kubectl.

  1. Obter o estado atual.

    Para WorkloadCertificateConfig:

    kubectl get WorkloadCertificateConfig default -o yaml
    

    Para TrustConfig:

    kubectl get TrustConfig default -o yaml
    
  2. Inspeccione o resultado do estado. Um objeto válido tem uma condição com type: Ready e status: "True".

    status:
      conditions:
      - lastTransitionTime: "2021-03-04T22:24:11Z"
        message: WorkloadCertificateConfig is ready
        observedGeneration: 1
        reason: ConfigReady
        status: "True"
        type: Ready
    

    Para objetos inválidos, é apresentado status: "False". Os camposreasonemessage contêm detalhes de resolução de problemas adicionais.

Os CSRs não são aprovados

Se algo correr mal durante o processo de aprovação do CSR, pode verificar os detalhes do erro nas condições type: Approved e type: Issued do CSR.

  1. Liste os CSRs relevantes através de kubectl:

    kubectl get csr \
      --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
    
  2. Escolha um CSR que seja Approved e não Issued, ou que não seja Approved.

  3. Obtenha detalhes do CSR selecionado através do kubectl:

    kubectl get csr CSR_NAME -o yaml
    

    Substitua CSR_NAME pelo nome do CSR que escolheu.

Um CSR válido tem uma condição com type: Approved e status: "True", e um certificado válido no campo status.certificate:

status:
  certificate: <base64-encoded data>
  conditions:
  - lastTransitionTime: "2021-03-04T21:58:46Z"
    lastUpdateTime: "2021-03-04T21:58:46Z"
    message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
    reason: AutoApproved
    status: "True"
    type: Approved

As informações de resolução de problemas para CSRs inválidos são apresentadas nos campos message e reason.

As aplicações não podem usar credenciais mTLS emitidas

  1. Verifique se o certificado não expirou:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  2. Verifique se o tipo de chave que usou é suportado pela sua aplicação.

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
    
  3. Verifique se a AC emissora usa a mesma família de chaves que a chave do certificado.

    1. Obtenha o estado da instância do serviço de CA (pré-visualização):

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Substitua o seguinte:

      • ISSUING_CA_TYPE: o tipo de AC emissora, que tem de ser subordinates ou roots.
      • ISSUING_CA_NAME: o nome da AC emissora.
      • ISSUING_CA_LOCATION: a região da AC emissora.
    2. Verifique se o keySpec.algorithm na saída é o mesmo algoritmo de chave que definiu no manifesto YAML WorkloadCertificateConfig. O resultado tem o seguinte aspeto:

      config:
        ...
        subjectConfig:
          commonName: td-sub-ca
          subject:
            organization: TestOrgLLC
          subjectAltName: {}
      createTime: '2021-05-04T05:37:58.329293525Z'
      issuingOptions:
        includeCaCertUrl: true
      keySpec:
        algorithm: RSA_PKCS1_2048_SHA256
       ...
      

Os certificados são rejeitados

  1. Verifique se a aplicação de pares usa o mesmo pacote de confiança para validar o certificado.
  2. Verifique se o certificado não expirou:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  3. Verifique se o código do cliente, se não estiver a usar a API de recarregamento de credenciais do gRPC Go, atualiza periodicamente as credenciais do sistema de ficheiros.

  4. Verifique se as cargas de trabalho estão no mesmo domínio de confiança que a AC. Os certificados de malha do GKE suportam a comunicação entre cargas de trabalho num único domínio de confiança.